Java“幽灵比特位”(GhostBits)引发的新型WAF绕过与注入攻击-把一段中文汉字发给服务器,它还原成了 ‘ 号然后打穿了数据库

admin 2026-05-02 05:46:09 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细分析了Java字符强制转换为字节时高位比特被静默丢弃的机制(GhostBits攻击),导致WAF无法识别Unicode字符转换后的恶意载荷。攻击者可利用该缺陷实现SQL注入绕过、路径穿越、SMTP命令注入等,影响Spring、Tomcat、Jira等主流组件。文章提供了具体CVE案例、自查工具和防御方案,包括升级补丁、代码审查和WAF策略调整。 综合评分: 92 文章分类: 漏洞分析,WEB安全,应用安全,威胁情报,解决方案


cover_image

Java “幽灵比特位”(Ghost Bits)引发的新型 WAF 绕过与注入攻击-把一段中文汉字发给服务器,它还原成了 ‘ 号然后打穿了数据库

原创

IceByte IceByte

Zner sec

2026年5月1日 17:29 内蒙古

在小说阅读器读本章

去阅读

你的 WAF 拦住了 ' OR 1=1,却没拦住**「逧 OR 亱=亱」**。

因为对于 WAF 来说,它看到的是汉字——无害; 但对于 Java 的底层字节处理来说,那串汉字在执行时悄悄变成了 ' OR 1=1。

这是因为 Java char 强转 byte 时高位被静默丢弃的底层机制,被研究员包装成了一套完整的攻击体系,在今年4月 Black Hat Asia 2026 正式公开。

名字叫:Ghost Bits(幽灵比特位)。



一、先讲清楚这个”缺陷”到底是什么

研究员 Xinyu Bai(浅蓝) 最初发现这个问题,是在用 BurpSuite 测试时往请求 URI 里输入中文字符,结果数据包发出去以后——字变了。

他输入的是 大黑阔(\u5927\u9ED1\u9614), 发出去的变成了\x27\xd1\x14。

\x27就是单引号 '。



原因是 Java 标准库方法 DataOutputStream#writeBytes(String s) 的文档里清楚写着:

“Each character in the string is written out, by discarding its high eight bits.”

这不是 bug,是有意为之的设计——只是在当年设计时没人考虑到它会成为攻击向量。

Java 的 char 是16位(UTF-16),byte 是8位。 当代码执行以下任意一种操作时,高8位会被抹掉,不报错,不抛异常,静默完成:

(byte) ch             // 强制类型转换ch & 0xFF             // 位掩码截断baos.write(ch)        // ByteArrayOutputStream 写入DataOutputStream.writeBytes(str)

那些被抹掉的高8位,就是研究员命名的 “Ghost Bits(幽灵比特位)”。

说白了就一句话:字符在 WAF 眼里是 Unicode 汉字,在 Java 底层执行里是另一个 ASCII 字符。两层视角,同一个输入,完全不同的解读。


二、一段汉字如何变成路径穿越攻击

来看一个最典型的真实漏洞:CVE-2025-41242(Spring Framework 任意文件读取)。

研究员设计了一串中文:阮严灵丰丰甲来。 看起来毫无意义,但每一个字都经过精心挑选:

| 字符 | Unicode | 低8位(byte) | 对应 ASCII | | — | — | — | — | | 阮 | U+962E | 0x2E | . | | 严 | U+4E25 | 0x25 | % | | 灵 | U+7075 | 0x75 | u | | 丰 | U+4E30 | 0x30 | 0 | | 丰 | U+4E30 | 0x30 | 0 | | 甲 | U+7532 | 0x32 | 2 | | 来 | U+6765 | 0x65 | e |

这七个汉字拼在一起,经过 Ghost Bits 截断,变成了:.%u002e

.%u002e 是什么?是点号 . 加上 .. 的 Unicode 编码形式。

也就是说,阮严灵丰丰甲来/阮严灵丰丰甲来 = ./.. = ../

路径穿越就这样发生了。



这个漏洞厉害在哪?

Spring 有安全检查:isInvalidPath,会拦截包含 ../ 的路径。 但它只认识字面量 ../,对 /.阮严灵丰丰甲来/ 完全无感,判定放行。

路径随后进入 Jetty 的 PathResource``#resolve,Jetty 会识别 %u002e 并将其解码为 .,最终在文件系统层面还原成 ../../。

一句话总结:Spring 说”这段路径安全”,但 Jetty 执行时已经穿越了。

受影响范围:spring-boot-starter-jetty ≤ 3.2.4,无需认证,直接读取服务器任意文件。


三、这套手法的攻击图谱

Ghost Bits 不是一个漏洞,是一种攻击范式。研究员演示了至少六个不同的攻击方向:


3.1 让 WAF 看不到 SQL 注入

Jackson 处理 JSON 字段时,内部有个 charToHex 方法用 ch & 255 截断字符:

"name": "1 union select 1,2,3--"

↑ 这个 WAF 会拦。

"name": "\u丰丰耳失\u丰丰甲丰..."

↑ 这个 WAF 不认识,放行——但 Jackson 解码后得到的结果和上面完全一样。



3.2 Tomcat 文件上传,jsp 伪装成汉字发过去

上传文件时,Content-Disposition 里的文件名写成 filename*="UTF-8''1.陪sp"。

WAF 看到的是 1.陪sp——不是 .jsp,规则不触发,放行。

Tomcat 的 RFC2231Utility.java 内部执行 (byte) c,字符 陪(U+966A)高位 0x96 被丢弃,低位 0x4A = 'j',文件最终以 1.jsp 保存。

Webshell 就这样传上去了。



3.3 让 Jira 给你发钓鱼邮件(而且绕过 DKIM)

这是本次研究中社会危害最大的攻击方向。

Jakarta Mail(angus.mail)的 ASCIIUtility.java 在序列化邮件地址时,对每个字符执行强制 (byte) 转换。攻击者在”收件人”字段中夹入特定 Unicode 字符,经 Ghost Bits 截断后还原为 \r\n(回车换行),从而注入任意 SMTP 命令。

具体场景:

攻击者在 Jira 注册时,邮箱地址填入精心构造的 Ghost Bits 载荷。Jira 后端发送”注册确认邮件”时,触发 SMTP 注入——邮件被劫持,实际发送的是攻击者自定义内容:

RCPT&nbsp;TO: <[email protected]>DATASubject: You are Hacked!Malicious Link...

但发件人依然是 Jira 的官方邮件地址,而且 SPF / DKIM / DMARC 全部校验通过——因为邮件本来就是从 Jira 服务器发出去的,没有伪造发件服务器。



3.4 Confluence 域名白名单?直接绕过

Confluence 可以配置”只允许 @company.com 邮箱注册”。 攻击者注册时填:hacker[Ghost\r\n]@company.com

  • Confluence 的验证逻辑

    :检查字符串末尾,确实是 @company.com → 验证通过

  • 底层 SMTP 执行

    :Ghost Bits 将特定字符还原为 \r\n,SMTP 在 [email protected] 处提前结束 RCPT TO 命令,确认邮件被发送到攻击者的 QQ 邮箱

攻击者拿到邮件里的激活链接,完成注册,获得内部系统账号权限。



3.5 供应链污染:一个库,倒下一片

这个 SMTP 注入问题的根源——angus.mail——不是某个小众库,它是整个 Java 邮件生态的底座:

  • Confluence、Jira、Bitbucket(Atlassian 全家桶)
  • Keycloak
  • YouTrack
  • TeamCity(CVE-2025-57733)
  • Liferay
  • OpenMeetings

只要应用允许用户输入邮箱并从后端发信,就可能中招。这是典型的供应链级攻击。



3.6 还有 HTTP 请求走私和 XSS

  • Apache HttpClient ≤ 4.5.9

    (HTTPCLIENT-1974):ByteArrayBuffer#append 在构建请求头时盲目 cast,如果应用把用户可控 token 拼进请求头,攻击者可注入 \r\n 实现请求走私

  • JDK 原生 HttpServer

    (CVE-2026-21933):若将用户输入反射到响应头,Ghost Bits 可注入 \r\n,将响应头变成新的响应体,导致 XSS


四、真的到处都是

研究员用自动化工具 Secrux 在 GitHub 搜索相关高危写法:

lang:Java&nbsp;AND&nbsp;("(byte)ch"&nbsp;OR&nbsp;"(byte) ch"&nbsp;OR&nbsp;"ch & 0xff"&nbsp;OR&nbsp;"baos.write(ch")

结果:8100+ 条匹配,Display limit hit(超出展示上限)。



这意味着什么?意味着 Ghost Bits 不是某一个组件的问题,而是渗透在整个 Java 生态底部的一类编码哲学缺陷,还有大量未被发现的利用路径。

研究员在演讲结尾说的那句话:

“We have only scratched the surface.”(我们才刚触及表面。)

不是谦虚,是字面意思。


五、系统自查

poc脚本自查

https://github.com/shiyeshu/GBitsTools

测试环境搭建:

https://github.com/vulhub/vulhub/blob/master/spring/CVE-2025-41242/README.zh-cn.md

快速自查清单:

| 使用框架 | 排查范围 | | — | — | | Spring Boot + Jetty(≤ 3.2.4) | CVE-2025-41242,路径穿越 | | Tomcat 处理文件上传 | Ghost Bits 文件名绕过 | | Jackson / fastjson 解析用户输入 | WAF 绕过,SQL 注入 / RCE | | 使用 jakarta.mail / angus.mail 发邮件 | CVE-2025-7962,SMTP 注入 | | Apache HttpClient ≤ 4.5.9 | 请求走私 | | Openfire(未打补丁) | CVE-2023-32315 新型绕过 | | GeoServer(未打补丁) | CVE-2024-36401 WAF 绕过 |


六、如何防御

第一步,打补丁(优先级最高)

| 组件 | 升级目标 | | — | — | | Spring Framework 6.2.x | → 6.2.10 | | Spring Framework 6.1.x | → 6.1.22 | | Spring Framework 6.0.x | → 6.0.30 | | Spring Framework 5.3.x | → 5.3.44 | | Apache Commons BCEL | → 6.12.0+ | | Apache HttpClient | → 4.5.10+ | | GeoServer | → 2.28.3+ | | Openfire | → 5.0.4+ |

第二步,代码层面排查

搜索代码库中的以下高危模式,逐一评估是否接收了外部输入:

(byte) chch &&nbsp;0xFFbaos.write(ch)DataOutputStream.writeBytes(...)

替换方式:统一使用 str.getBytes(StandardCharsets.UTF_8) 做显式编码转换。

第三步,防线前移

在任何用户输入进入协议处理层之前(HTTP头、SMTP命令、文件路径),先做 Unicode 规范化(NFC/NFKC),并校验字符集是否在允许的范围内。参数化查询依然是注入攻击的最终防线——即使 WAF 被绕过,参数化也能挡住。

第四步,WAF 策略调整

传统 WAF 基于”看到的字符串”匹配规则,对 Ghost Bits 天然盲目。绿盟、阿里云 WAF 已针对已知 Ghost Bits 攻击模式上线专项规则。如果你的 WAF 厂商还没有动作,值得主动询问。


七、最后说一句

Ghost Bits 让人不舒服的地方不在于任何单一漏洞,而在于它质疑了一个长期被视为理所当然的假设:

“WAF 看到的,就是后端处理的。”

这个假设错了。同一个输入,在不同的编码层之间流动时,可以携带着截然不同的语义——WAF 看到的是无害的汉字,Java 底层执行的是单引号、点号、换行符。

这不是一个组件的问题,不是一家厂商的失误,是分层系统中语义一致性这个根本性课题的失守。

而它被披露于 2026 年——距离 Java 诞生已经30年。

那些”幽灵”,一直都在。


![](https://mmbiz.qpic.cn/sz_mmbiz_png/P8tspoQj3VqqaogoUAcWbsmibRQlEtJXeISTcEYroDQmp7ymsPANEaqPcu2rZouiaudib3YgkBsMGGQEvITSanIzAkYB82WNlcQZ0jibA7fAtCM/640?wx_fmt=png&from=appmsg&watermark=1#imgIndex=14)

参考来源

  1. Black Hat Asia 2026 原始议题
https://i.blackhat.com/Asia-26/Presentations/Asia-26-Bai-Cast-Attack-Ghost-Bits-4.23.pdf    https://i.blackhat.com/Asia-26/Presentations/Asia-26-Bai-Cast-Attack-Ghost-Bits-4.23.pdf
2. CVE-2025-41242 Vulhub 复现环境
https://github.com/vulhub/vulhub/blob/master/spring/CVE-2025-41242/README.zh-cn.md
3. GBitsTools 自查脚本
https://github.com/shiyeshu/GBitsTools

免责声明:

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

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

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

本文转载自:Zner sec IceByte IceByte《Java “幽灵比特位”(Ghost Bits)引发的新型 WAF 绕过与注入攻击-把一段中文汉字发给服务器,它还原成了 ‘ 号然后打穿了数据库》

评论:0   参与:  0