方法一:java.net.Inet[4|6]Address
以下两个类没有在黑名单中(v1.2.67),可以用来发送 dns 请求
fastjson 在进行反序列化的过程中会执行 checkAutoType 方法对类进行检查(主要通过黑
白名单机制),相关代码如下:
Code Snippet 1:
com.alibaba.fastjson.parser.ParserConfig#checkAutoType
由于 Inet4Address 类不在黑名单中,可以通过 1 处的的的黑名单检查,且它存在于
IdentityHashMap 类中,所以在 3 处直接 return,跳过 4 处的检查,所以无论是否开启
AutoType,都可以跳过 checkAutoType 检查
fastjason 对于 Inet4Address 类会使用 MiscCodec 这个 ObjectDeserializer 来反序列化。跟进
发现解析器会取出 val 字段的值赋值给 strVal 变量,并通过
InetAddress.getByName(strVal)
进行域名解析
方法二:java.net.InetSocketAddress
java.net.InetSocketAddress 类也在 IdentityHashMap 中,和方法一一样可以无视
checkAutoType,但是要执行 InetAddress.getByName()
需要跟着 json 的语法解析过程来构
造 payload
最终得到的畸形 payload 如下:
方法三:java.net.URL
java.net.URL 类也在 IdentityHashMap 中,同样无视 checkAutoType 检查
这个类的利用思路和 ysoserial 的 URLDNS 一样:向 HashMap 压入一个键值对时,HashMap 需要
获取 key 对象的 hashcode。当 key 对象是一个 URL 对象时,在获取它的 hashcode 期间会调用
getHostAddress 方法获取 host,这个过程域名会被解析
fastjson 解析上述 payload 时,先反序列化出 URL(http://dnslog)
对象,然后将
{URL(http://dnslog):"x"}
解析为一个 HashMap,最终域名被解析
这个 payload 还有以下变体,原理都相同: