Fastjson 1.2.68漏洞分析与解决思路

漏洞描述

Fastjson 1.2.68采用了黑白名单的方法来防御反序列化漏洞,在autoType关闭的情况下仍然可能可以绕过黑白名单防御机制,造成远程命令执行漏洞。

近期Fastjson连续发布了两个版本。其中1.2.69版本修复了两个安全漏洞:前者能够绕过反序列化autotype开关限制,造成的危害严重;而后者则是常规的黑名单列表更新,在开启autotype且当前Classpath中存在Gadget类前提下会触发反序列化漏洞。对于1.2.70版本,从commit得知针对安全问题只是在黑名单列表中新增了12个Gadget漏洞利用类。相比较而言,没有出现绕过autotype的限制,造成影响并没有上版中第一个漏洞危害大。

经分析发现,绕过autotype开关反序列化漏洞在1.2.68及以下版本中均受影响,黑客可利用该漏洞直接获取服务器系统权限并远程执行任意命令。当前官方采用黑白名单的方式防御上述漏洞,但存在漏洞版本中没有统一控制的方式彻底关闭反序列化功能,导致威胁始终存在。

本文主要分析了绕过autotype的漏洞成因、POC构造方式及解决思路。

漏洞成因

1、autoType的第一道关卡:解析的特征值IgnoreAutoType。坐标:DefaultJSONParser#parseObject

image-20200721163659771

由于默认的特征值没有IgnoreAutoType,放行。

image-20200721164748976

2、autoType的第二道关卡:安全模式掩码safeModeMask。坐标ParserConfig#checkAutoType

image-20200721165843484

同样,默认未开启安全模式且特征值掩码默认没有安全模式,放行。

image-20200721170501486

3、autoType的第三道关卡:autoTypeSupport&黑白名单。坐标ParserConfig#checkAutoType

image-20200721172546648

这一道关卡是本次突破漏洞的前提,如何绕过autoType和黑白名单,首先autoType默认是不支持的,

再看黑白名单的进入条件是“不是内部白名单并且满足支持autoType或者有期望类之一”,

(黑名单:denyHashCodes,白名单:INTERNAL_WHITELIST_HASHCODES,源代码里做了hash),

所以默认就不会进黑白名单了接着看,放行。

image-20200721180220601

4、autoType的第四道关卡:BaseClassMappings。坐标TypeUtils#addBaseClassMappings

image-20200721184736078

这一关我们是收集到一个线索,那就是通过BaseClassMappings能够拿到一个类,这就需要对这个mapping进行分析,通过默认的mapping集合我们能得到的信息是这里面的类都能被拿来反序列化,只是目前是这样的。接着看到除了一些基础类,还有些其他类,这里就得到了java.lang.AutoCloseable,放行。(gadget 挖掘不做示例)

image-20200721185525909

5、autoType的第五道关卡:expectClass。坐标ParserConfig#checkAutoType

expectClass的值是第一个@type的值,可以是上一关分析得来,比如:java.lang.AutoCloseable ,不为空可以绕过第三道关卡autoType的检测,不过目标类也就是第二个@type 的类名会进入黑白名单的校验,当它不存在于黑名单的时候,便会调用TypeUtils.loadClass方法加载目标类,最后调用isAssignableFrom()方法,用来判断反序列化目标类是否实现了期望类接口,如果是,则返回该class对象。

image-20200721194907104

最后对目标类进行反序列化操作,漏洞触发。

总结:上面关卡有做重复合并和省略。

通过checkAutoType校验的情况有下面几个:

  1. 白名单里的类
  2. 开启了 autotype
  3. 使用了 JSONType 注解
  4. 指定了期望类(expectClass)
  5. 缓存 mapping 中的类

本次漏洞成因就是基于上面各关卡的校验分析,指定一个期望类的情况:
1、挖掘一个期望类并且期望类不能在黑名单。
2、找到一个目标类需要继承或实现期望类,并且不在黑名单。

POC构造

注:本次POC构造纯属场景模拟,不做为真实漏洞攻击案例。

1、构造一个类实现接口java.lang.AutoCloseable,并在set或get做命令执行(模拟RCE需要,就简单写在get里了)

image-20200721201017102

2、模拟执行json反序列化

image-20200721201512998

3、执行结果

image-20200721201638300

官方通告:https://github.com/alibaba/fastjson/wiki/security_update_20200601

官方推荐方案:fastjson在1.2.68及之后的版本中引入了safeMode,配置safeMode后,无论白名单和黑名单,都不支持autoType,可一定程度上缓解反序列化Gadgets类变种攻击(关闭autoType注意评估对业务的影响)

在项目中的思路

1、启动时告警:开发一个starter项目,启动时扫描fastjson使用情况,并根据版本做出告警,可以强制升级

2、提交时修复:开发一个idea 插件,提交代码时扫描fastjson版本,提示并升级到推荐版本。

3、运行时检测:开发一个docker镜像,构造畸形payload获取报错回显,判断是否使用fastjson以及是否有漏洞。