前言
迟到的Fastjson反序列化漏洞分析,按照国际惯例这次依旧没有放poc。道理还是那个道理,但利用方式多种多样。除了之前放出来用于文件读写的利用方式以外其实还可以用于SSRF。
一、漏洞概述
在之前其他大佬文章中,我们可以看到的利用方式为通过清空指定文件向指定文件写入指定内容(用到第三方库)。当gadget是继承的第一个类的子类的时候,满足攻击fastjson的条件。此时寻找到的需要gadget满足能利用期望类绕过checkAutoType。
本文分析了一种利用反序列化指向fastjson自带类进行攻击利用,可实现文件读取、SSRF攻击等。
二、调试分析
1. 漏洞调试
从更新的补丁中可以看到expectClass类新增了三个方法分别为:
java.lang.Runnable、java.lang.Readable、java.lang.AutoCloseable
首先,parseObject方法对传入的数据进行处理。通过词法解析得到类型名称,如果不是数字则开始checkAutoType检查。
当传入的数据不是数字的时候,默认设置期望类为空,进入checkAutoType进行检查传入的类。
判断期望类,此时期望类为null。往下走的代码中,autoCloseable 满足不在白名单内,不在黑名单内,autoTypeSupport没有开启,expectClassFlag为false。
其中:
A.计算哈希值进行内部白名单校验
B.计算哈希值进行黑名单校验
C.非内部白名单且开启autoTypeSupport或者是期望类的,进行hash校验白名单acceptHashCodes、黑名单denyHashCodes。如果在acceptHashCodes内则进行加载( defaultClassLoader),在黑名单内则抛出 autoType is not support。
满足条件C后来到clazz的赋值,解析来的代码中对clazz进行了各种判断。
从明文缓存中取出autoCloseable赋值给 clazz。
当clazz不为空时,expectClassFlag为空不满足条件,返回clazz,至此,第一次的checkAutoType检查完毕。
将检查完毕的autoCloseable进行反序列化,该类使用的是JavaBeanDeserializer反序列化器,从MapDeserializer中继承。
JSON.DEFAULT_TYPE_KEY 为@type ,并给它赋值传入的key @type ,将第二个类也就是这次 的gadget传入。
期望类在这里发生了变化,expectClass的值变为java.lang.AutoCloseable,typeName为gadget,
来到JSONType注解,取typename gadget转换变为路径,resource通过将 “.” 替换为”/“得到路径 。其实已经开始读取gadget了,它本意应该是加载AutoCloseable。
可以看到这里有读取文件的功能。
isAssignableFrom()这个方法用于判断里面的类是否为继承类,当利用了java.lang.AutoCloseable这个方法去攻击fastjson,那么后续反序列化的链路一定是要继承于该类的子类。
TypeUtils.addMapping(typeName, clazz)这一步成功把gadget加入缓存中并返回被赋值gadget的clazz.
checkAutoType正式检查完毕,此时用deserializer = parser.getConfig().getDeserializer(userType); userType既gadget进行反序列化。
进入coreConnect()
在这里进行连接。至此漏洞利用完结。
2. 总结:
在本次反序列化漏洞中,笔者认为关键点在于找到合适并且可利用的常用jar包中的gadget。gadget在被反序列化后即可执行类里的恶意的功能(不仅限于RCE还包括任意文件读取/创建,SSRF等)。也可以使本漏洞得到最大化的利用。
三、参考考链接
https://b1ue.cn/archives/348.html
https://daybr4ak.github.io/2020/07/20/fastjson%201.6.68%20autotype%20bypass/
作者:ale_wong
来源:freebuf.com 2020-10-14 21:20:26 by: 云影实验室
请登录后发表评论
注册