内容提要
本文逆向学习Fastjson反序列化漏洞,分析@type字段指定反序列化类名导致的安全隐患,重点解析JdbcRowSetImpl类payload的构造与触发原理,给出Gadget chain调用链,并讨论不同版本下DNSLOG探测payload的适用性差异。
延伸解读
@type字段的作用与风险
Fastjson在序列化时加入SerializerFeature.WriteClassName特征后,会在JSON中写入@type字段,记录类名。反序列化时,Fastjson会根据@type指定的类名直接实例化对象,这为攻击者提供了指定任意类的入口。理解这一机制是分析漏洞的关键,也解释了为何Fastjson的autoType机制需要严格限制。
JdbcRowSetImpl利用链的触发条件
JdbcRowSetImpl的payload依赖dataSourceName和autoCommit两个属性。dataSourceName指定JNDI名称,autoCommit设为true时,会触发JNDI查找并可能加载远程恶意类。文章指出,删除autoCommit属性不会触发漏洞,说明该属性是触发链的关键环节。实际利用时需确保目标环境支持JNDI注入。
DNSLOG探测的版本差异
文章提到不同Fastjson版本对DNSLOG探测payload的支持不同,例如URL payload在1.2.36至1.2.72版本可用,而Inet4Address和Inet6Address payload则全版本支持。这提醒安全测试人员需根据目标版本选择合适的探测方式,避免漏报。
Q&A
Fastjson反序列化漏洞中@type字段的作用是什么?
在Fastjson中,@type字段用于指定反序列化时使用的类名。当JSON字符串中包含@type时,Fastjson会根据该字段的值实例化对应的类,并调用其setter方法设置属性。攻击者可以通过控制@type的值来触发危险类的实例化,从而可能导致远程代码执行。
Fastjson反序列化漏洞的成因是什么?
Fastjson在反序列化JSON数据时,会解析@type字段并实例化指定的类,然后调用其setter方法。如果攻击者能够控制@type的值,就可以实例化任意类,并利用某些类的危险setter方法(如JdbcRowSetImpl的setAutoCommit)触发JNDI注入,最终导致远程代码执行。
JdbcRowSetImpl的payload是如何触发漏洞的?
JdbcRowSetImpl的payload通过设置dataSourceName为恶意的JNDI地址(如rmi://127.0.0.1:1090/Exploit),并设置autoCommit为true,触发setAutoCommit方法,该方法会连接dataSourceName指定的JNDI服务,从而加载远程恶意类,实现代码执行。
Fastjson反序列化漏洞的Gadget chain是什么?
Gadget chain为:JSON.parse() -> DefaultJSONParser.parse() -> DefaultJSONParser.parseObject() -> JavaBeanDeserializer.deserialze() -> JavaBeanDeserializer.parseRest() -> FieldDeserializer.setValue() -> Reflect.invoke() -> JdbcRowSetImpl.setAutoCommit()。
不同版本的Fastjson在DNSLOG探测payload上有什么差异?
不同版本的Fastjson对不同的DNSLOG payload支持情况不同。例如,使用java.net.URL的payload在1.2.36到1.2.72版本可用,而使用java.net.Inet4Address和java.net.Inet6Address的payload则全版本支持(<=1.2.72)。
如何通过DNSLOG探测Fastjson漏洞?
通过构造包含@type字段的JSON数据,指定一个会发起网络请求的类(如java.net.URL或java.net.Inet4Address),并设置val为DNSLOG域名。如果Fastjson存在漏洞,它会解析该字段并触发DNS请求,从而在DNSLOG平台收到记录,确认漏洞存在。