Fastjson2AutoType哈希校验绕过致RCE分析

admin 2026-08-08 05:19:11 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档分析了Fastjson2中一个AutoType哈希校验绕过漏洞,该漏洞源于默认配置下FNV-1a哈希白名单校验逻辑缺陷,攻击者可构造特定前缀的类名字符串绕过校验,导致任意代码执行。关键发现是校验时使用前缀哈希,而加载时使用完整类名,存在不一致。可操作建议包括启用SafeMode完全禁用AutoType或配置WAF规则拦截@type字段。 综合评分: 86 文章分类: 漏洞分析,代码审计,安全工具,红队,WEB安全


cover_image

Fastjson2 AutoType 哈希校验绕过致RCE分析

哈拉少安全小队

2026年7月27日 20:48 广东

在小说阅读器读本章

去阅读

以下文章来源于鉴帷安全 ,作者圣火喵喵教

鉴帷安全 .

原来积木可以这么拼

#

垂死上班惊坐起,突然看到长亭发了一个fastjson2的原创 0day,让我们来康康,这个洞是怎么个事。 根据长亭公众号的描述,该漏洞源于 Fastjson2 在默认配置下未启用SupportAutoType 时,仍可能处理通用对象元素开头@type 属性。其“AutoType 已禁用”校验分支会将输入字符串的增量 FNV-1a 哈希与默认接受哈希进行匹配,但命中后不会确认实际文本是否等于预期的白名单类名。所以,可以针对任意前缀计算FNV chosen-prefix碰撞,使 URL 形态的字符串进入应用的类加载器,导致任意代码执行。

在默认情况下,Fastjson2 默认不会随便根据 JSON 里的 @type 加载任意类。不过在 ObjectReaderProvider.checkAutoType() 中,存在一段基于 FNV-1a 哈希的白名单判断逻辑。

如果前缀校验和最终加载的类名不是同一个字符串,就可能出现校验对象与实际使用对象不一致的问题。

话不多说,让我们康康源码

git clone https://github.com/alibaba/fastjson2.git

根据漏洞描述,定位关键位置:core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderProvider.java;848:872

重点方法:

checkAutoType(String typeName, Class<?> expectClass, long features)

大致逻辑是酱紫:

if&nbsp;(!autoTypeSupport) {long&nbsp;hash = MAGIC_HASH_CODE;for&nbsp;(int&nbsp;i =&nbsp;0; i < typeNameLength; ++i) {char&nbsp;ch = typeName.charAt(i);if&nbsp;(ch ==&nbsp;'$') {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ch =&nbsp;'.';&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; hash ^= ch;&nbsp; &nbsp; &nbsp; &nbsp; hash *= MAGIC_PRIME;// white listif&nbsp;(Arrays.binarySearch(acceptHashCodes, hash) >=&nbsp;0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clazz = loadClass(typeName);if&nbsp;(clazz !=&nbsp;null&nbsp;&& expectClass !=&nbsp;null&nbsp;&& !expectClass.isAssignableFrom(clazz)) {throw&nbsp;new&nbsp;JSONException("type not match. "&nbsp;+ typeName +&nbsp;" -> "&nbsp;+ expectClass.getName());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }if&nbsp;(clazz !=&nbsp;null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; afterAutoType(typeName, clazz);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }return&nbsp;clazz;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}if&nbsp;(!autoTypeSupport) {return&nbsp;null;}

这段代码不是一次性计算完整 typeName 的哈希,而是逐个字符算运行中的哈希值,也就是说,假设传入:prefix + suffix

程序会先算:FNV(prefix 的第 1 个字符); &nbsp;FNV(prefix 的前 2 个字符); ... FNV(prefix); FNV(prefix + suffix)如果其中某一个前缀的哈希刚好命中 acceptHashCodes的话,代码就会通过校验,你就算吧,算到天荒地老。但后面真正传给 loadClass() 的却是完整的:prefix + suffix,这是问题所在,白名单校验实际上是某个前缀,尝试加载都得是完整的类名,两个东西不是一个值简单说,就是“检查时看的是 A,使用时却用了 A+B”。

默认白名单哈希

代码里提到了一个默认hash,我是找了半天没找到对应的初始位置-6293031534589903644L hex:0xa8aaa929446ffce4这个在历史提交记录里应该是有的,俺不找了。

可能的思路

理论上,只要构造一个类名字符串,使它的某个前缀满足:FNV-1a(prefix) == 某个白名单哈希

之后组件就会直接尝试加载完整字符串:loadClass(prefix + suffix)

不过,就算能命中哈希不代表一定能利用成功。目前就默认条件来看,这个漏洞还是有些需要运气,我是比较菜,没复现出来。

按照长亭给的修复意见

  1. 完全禁用 AutoType:开启 SafeMode 来完全禁用 AutoType 功能,从根本上杜绝此类风险。代码配置:ParserConfig.getGlobalInstance().setSafeMode(true);JVM 参数:-Dfastjson.parser.safeMode=true
  2. WAF规则配置:拦截请求体中key包含 @type 字段的 JSON 数据

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:哈拉少安全小队 《Fastjson2 AutoType 哈希校验绕过致RCE分析》

评论:0   参与:  0