fastjson到底做错了什么?为什么会被频繁爆出漏洞?(推荐)
2020-07-06 13:01:03 来源:易采站长站 作者:王振洲
autoType不开启也能被攻击?
但是好景不长,在升级到 v1.2.47 版本时,黑客再次找到了办法来攻击。而且这个攻击只有在autoType关闭的时候才生效。
是不是很奇怪,autoType不开启反而会被攻击。
因为在fastjson中有一个全局缓存,在类加载的时候,如果autotype没开启,会先尝试从缓存中获取类,如果缓存中有,则直接返回。黑客正是利用这里机制进行了攻击。
黑客先想办法把一个类加到缓存中,然后再次执行的时候就可以绕过黑白名单检测了,多么聪明的手段。
首先想要把一个黑名单中的类加到缓存中,需要使用一个不在黑名单中的类,这个类就是java.lang.Class
java.lang.Class类对应的deserializer为MiscCodec,反序列化时会取json串中的val值并加载这个val对应的类。

如果fastjson cache为true,就会缓存这个val对应的class到全局缓存中

如果再次加载val名称的类,并且autotype没开启,下一步就是会尝试从全局缓存中获取这个class,进而进行攻击。
所以,黑客只需要把攻击类伪装以下就行了,如下格式:
{
"@type": "java.lang.Class","val": "com.sun.rowset.JdbcRowSetImpl"
}
于是在 v1.2.48中,fastjson修复了这个bug,在MiscCodec中,处理Class类的地方,设置了fastjson cache为false,这样攻击类就不会被缓存了,也就不会被获取到了。
在之后的多个版本中,黑客与fastjson又继续一直都在绕过黑名单、添加黑名单中进行周旋。
直到后来,黑客在 v1.2.68之前的版本中又发现了一个新的漏洞利用方式。
利用异常进行攻击
在fastjson中, 如果,@type 指定的类为 Throwable 的子类,那对应的反序列化处理类就会使用到 ThrowableDeserializer
而在ThrowableDeserializer#deserialze的方法中,当有一个字段的key也是 @type时,就会把这个 value 当做类名,然后进行一次 checkAutoType 检测。
并且指定了expectClass为Throwable.class,但是在checkAutoType中,有这样一约定,那就是如果指定了expectClass ,那么也会通过校验。

因为fastjson在反序列化的时候会尝试执行里面的getter方法,而Exception类中都有一个getMessage方法。
黑客只需要自定义一个异常,并且重写其getMessage就达到了攻击的目的。
这个漏洞就是6月份全网疯传的那个"严重漏洞",使得很多开发者不得不升级到新版本。
这个漏洞在 v1.2.69中被修复,主要修复方式是对于需要过滤掉的expectClass进行了修改,新增了4个新的类,并且将原来的Class类型的判断修改为hash的判断。













闽公网安备 35020302000061号