前言
这几天在一直研究fastjson反序列化漏洞,从1.2.24版本开始一直到1.2.68版本,其漏洞分析及其利用在网上还是很多的,但不知是大佬们有意为之还是怎样,各博客上写的payload大致差不多,但其实在1.2.68的漏洞中,能用的思路不只有AutoCloseable这一个,还有其他方式也有可能导致RCE,我相信大佬们的手中依然有没有放出的payload。
目前最新1.2.75版本的漏洞(在我看来确实是漏洞,因为确实执行了反序列化攻击)的原因是我在分析1.2.68中找到的,我认为作者应该是知道的,因为原理和AutoCloseable是一样的,可能作者认为利用条件比较多,难以构成威胁,但作为学习之用还是很好的素材。
旧版本漏洞回顾
关于这个话题知乎上有答主做了高质量分析
fastjson到底做错了什么?为什么会被频繁爆出漏洞?
这个帖子很详细的总结了先前fastjson网上公开的漏洞细节,不过唯一不敢苟同的是作者在提到1.2.68版本中,主要利用方式是利用异常进行攻击,并且要重写getMessage方法。
其实在1.2.68版本中,利用最广泛的是使用AutoCloseable这个接口绕过checkAutoType,网上大多也以这种方式展开分析。因为AutoCloseable构成的payload所需要的条件可能没有那么复杂。文章中说1.2.69已经修复了异常攻击漏洞,但是经过测试似乎并没有。
AutoCloseable比较完整的利用链:
fastjson 1.2.68 反序列化漏洞 gadgets 挖掘笔记
1.2.68的漏网之鱼
截止这篇文章发出,fastjson在github上的最新版本为1.2.75。
要分析1.2.75漏洞产生原因,我们还是要回到1.2.68版本的漏洞分析中去,本文不会去重提网上提到的一些常见的1.2.68的分析,会稍微提一下被人没有提出来的。
“系统的白名单”
fastjson1.2.68当初产生的主要原因在于,fastjson为了再次避免用户用其AutoType
机制进行反序列化而产生漏洞,加入了checkAutoType
方法,AutoType
机制的标志就是“@type
”这个标签。checkAutoType
这个方法本意是不想让用户使用AutoType
,除非用户自己开启AutoType
。然而在checkAutoType
方法实现过程中还是没忍住偷偷用了几下(标志是解析了"@type
"标志),但加强了限制。在代码审计过程中,我发现了一行非常重要的代码。
这行代码位置在com.alibaba.fastjson.parser.ParserConfig
第1326行
clazz = TypeUtils.getClassFromMapping(typeName);
(这行代码在fastjson宏观意义上有何作用暂不知晓)
其中typeName
变量是用户输入的序列化之后的JSON格式数据中,含有类名的字符串,比如{"@type","com.demo.test"}
这个json数据,其typeName
就是com.demo.test
。这行代码的意思就是从TypeUtils
这个类中尝试获取json中提到的类。
在TypeUtils
的静态方法中,执行了addBaseClassMappings
函数,其函数代码如下(注意其中含有AutoCloseable
接口):
private static void addBaseClassMappings(){
mappings.put("byte", byte.class);
mappings.put("short", short.class);
mappings.put("int", int.class);
mappings.put("long", long.class);
mappings.put("float", float.class);
mappings.put("double", double.class);
mappings.put("boolean", boolean.class);
mappings.put("char", char.class);
mappings.put("[byte", byte[].class);
mappings.put("[short", short[].class);
mappings.put("[int", int[].class);
mappings.put("[long", long[].class);
mappings.