文章总结: CAST攻击利用Java中char(16位)转byte(8位)时高8位被丢弃的幽灵比特位特性,通过构造特殊Unicode字符使WAF看到无害内容而Java后端执行恶意payload,可绕过文件上传、路径穿越等防护。防御需从代码修复、WAF增强或RASP监控行为三方面入手。 综合评分: 88 文章分类: 漏洞分析,Web安全,应用安全,Java,安全开发
深度解析Cast Attack:Java幽灵比特位如何突破WAF防线
原创
ZKAFKA ZKAFKA
网络安全研究站
2026年6月23日 08:00 广东
在小说阅读器读本章
去阅读
2026年Black Hat Asia大会上披露的“Cast Attack: A New Threat Posed by Ghost Bits in Java”迅速成为安全圈热点。这一技术并非单一CVE,而是Java生态中长期存在的 char(16位)与byte(8位)转换不一致导致的系统性问题。
攻击者通过构造特殊Unicode字符,让WAF看到“无害”内容,而后端Java处理时高8位被静默丢弃(Ghost Bits),还原成恶意payload,从而实现绕过。
01
从“陪”变成“j”,看懂 Ghost Bits
要理解 Ghost Bits,不需要深奥的底层知识,只需要回到 Java 里最基本的两个数据类型。
Java 的 char 类型是 16 位(2 字节),而 byte 类型只有 8 位(1 字节)。当代码里出现 (byte)ch、ch & 0xFF 这样的写法,把一个 char 强制转成 byte 时,会发生什么?
高 8 位被静默丢弃,只保留低 8 位。这被丢弃的高 8 位,就是所谓的“幽灵比特位”。
拿一个具体的汉字来看:
- 汉字「陪」的 Unicode 码点为
U+966A,十六进制写作0x966A - 高 8 位是
0x96,低 8 位是0x6A (byte)'陪'只保留低 8 位,得到0x6A- 而
0x6A恰好是字母j的 ASCII 编码
应用层看到的是“陪”,底层实际执行的却变成了 j。
类似的例子还有:
- 「爻」(U+2F58)→ 截断后变成
X(0x58) - 「阮」(U+962E)→ 截断后变成
.(0x2E) - 「严」(U+4E25)→ 截断后变成
%(0x25)
研究人员在 GitHub 搜索 Java 代码中典型的 Ghost Bits 写法,如 (byte)ch、ch & 0xff,命中的结果超过 8,100 条。这说明这类缺陷在 Java 生态中极其普遍。
02
Cast Attack:检查语义与执行语义的交错
:
研究者将这类由类型转换引发的攻击链统称为 Cast Attack。它的核心矛盾很简单:同一个输入,在系统不同阶段以不同的“视图”出现。
- 字符串视图:WAF、业务校验看到的是一串无害的 Unicode 字符,判断为“安全,放行”。
- 字节层视图:Java 后端、底层协议执行时,高位被截断,看到的变成了危险的 ASCII 字节。
攻击者的思路非常清晰:对每一个危险 ASCII 字符,找一个 Unicode 字符,使其低 8 位恰好等于那个危险字符的 ASCII 码。
数学表达就是:
目标字符 = (任意高位 << 8) | 目标字节
这意味着,对每一个危险 ASCII 字符,攻击者至少有 255 个不同的 Unicode 字符可供选择。例如:
| 目标字节 | 对应的 Unicode 字符(示例) | 用途 |
| — | — | — |
| j (0x6A) | 陪 (U+966A) | 伪装 .jsp 文件 |
| . (0x2E) | 阮 (U+962E) | 路径穿越 |
| % (0x25) | 严 (U+4E25) | URL 编码绕过 |
| X (0x58) | 爻 (U+2F58) | 任意字符替换 |
有了这个“武器库”,攻击者可以把攻击载荷中的关键字符,一个个替换成对应的 Unicode 字符,让 WAF 完全看不到任何攻击特征。
03
实战场景下的攻击
Ghost Bits 不是一个孤立漏洞,而是一套可复用的攻击套件,能触发多种高危场景。
场景一:文件上传绕过——“1.陪sp” 变 “1.jsp”
攻击者上传一个文件名为 1.陪sp 的附件。
- WAF 检查文件名:
1.陪sp,没有.jsp,不是敏感文件,放行。 - Java 后端处理:
陪截断为j,实际保存的文件名变成1.jsp。
第二天,服务器上多了一个 Webshell。
场景二:路径穿越——七个汉字变成“..”
攻击者构造路径:「阮严灵丰丰甲来」。
- WAF 看到的是一串无害中文。
- Java 后端截断后得到:
./%u002e..,再经过 URL 解码,变成../..。
一次隐蔽的路径穿越,就这样悄无声息地完成了。
场景三:CRLF 注入——两个汉字变成换行符
「瘍瘊」截断后变成 \r\n,可以拆分 HTTP 协议命令,实现请求走私或响应拆分攻击。
场景四:关键字绕过——“㹣౬ᙡ⑳⑳” 变成 “class”
攻击者用「㹣౬ᙡ⑳⑳」这样的 Unicode 字符串,绕过对 class 关键字的检测,触发 Spring4Shell 等已知高危漏洞。
已确认受影响的组件包括:Spring、Tomcat、Jackson、fastjson、Jetty、Undertow、Vert.x 等主流 Java 框架与中间件。
04
如何防御?从“看输入”到“看行为”
Ghost Bits 最值得警惕的地方在于:它并非某个程序员写错了代码,而是 Java 语言规范允许的行为。
Java 语言规范(JLS §5.1.3)明确允许这种“窄化转换”。也就是说,这个安全隐患在二十年前语言设计之初就已经埋下。大量遗留框架、旧代码依赖这种转换逻辑,修复起来不是“打个补丁”那么简单,而是需要全量审计和重构。
传统 WAF 站在流量入口,基于 HTTP 原始报文进行规则匹配。它看到的是 Unicode 码点,而 Java 应用按 char→byte 截断后再执行。两者理解的“数据”完全不同。这种“语义鸿沟”,让基于正则表达式的规则库瞬间失明。
三条防御路线
路线一:代码层修复(治本,但工程量大)
排查并整改 Java 代码中的危险写法:
// ❌ 危险:隐式截断byte b = (byte) ch;int i = ch & 0xFF;baos.write(ch);
// ✅ 安全:明确指定编码byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
路线二:WAF 增强(治标,但可快速落地)
部分 WAF 产品已支持 Unicode Ghost Bits 检测。核心思路是在检测层模拟 Java 的截断行为,提前识别变形后的攻击载荷。
路线三:RASP 运行时防护(从“看输入”到“看行为”)
WAF 的盲区,恰恰是 RASP 的主场。RASP(运行时应用自保护)的核心逻辑不是猜测输入长什么样,而是监控程序最终做了什么。
当 Ghost Bits 编码的载荷骗过 WAF 进入应用,试图读取 /etc/passwd,或在 JDBC 层进行拼接式 SQL 查询时,RASP 在字节码层面植入的探针会直接拦截这些危险操作。简单说:WAF 看到的是“伪装”,RASP 看到的是“行为”。
参考来源:Black Hat Asia 2026《Cast Attack: A New Threat Posed by Ghost Bits in Java》议题(Asia-26-Bai-Cast-Attack-Ghost-Bits-4.23.pdf)及安全社区相关分析。
本站致力于做最深度、专业、前沿的网络安全知识分享平台,欢迎点赞、关注、推荐,为您持续更新深度好文。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:网络安全研究站 ZKAFKA ZKAFKA《深度解析Cast Attack:Java幽灵比特位如何突破WAF防线》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论