文章总结: 文档解析宽字节注入原理,指出GBK字符集下addslashes()因假设错误失效,攻击者构造特定序列使转义符被数据库当作字符吞噬。该漏洞与传输方式无关,核心是编码不一致,建议开发时统一应用层与数据库层字符集以规避风险。 综合评分: 93 文章分类: WEB安全,漏洞分析,渗透测试
一次性把“宽字节注入”理解清楚
原创
武文学网安 武文学网安
武文学网安
2026年1月26日 02:43 中国香港
大家好,我是武文。
在 sqli-labs 的第 32 / 34 关中,都会遇到同一个“看起来很安全”的防御函数:addslashes()
这两关本身并不复杂,也没有引入新的注入技巧,因此本文不再展开关卡细节,只简单给出一句结论:第 32 / 34 关的本质,都是同一个问题:宽字节注入。
真正值得深入理解的,不是关卡,而是:
- 为什么 addslashes() 会失效
- 宽字节注入究竟发生在什么地方
- 为什么这种漏洞在真实环境中依然危险
一、什么是宽字节注入(精准定义)
宽字节注入(Wide Byte Injection)指的是:在 GBK / BIG5 等多字节字符集下,攻击者通过构造特定字节序列,让防御函数插入的反斜杠 \被数据库当作多字节字符的一部分解析,从而导致转义失效、单引号重新获得 SQL 语义。
关键词只有三个:
- 多字节字符集
- 转义字符被“吃掉”
- SQL 结构重新被破坏
二、addslashes() 的致命假设
addslashes() 的设计逻辑非常直接:
‘ → \'” → \”\ → \NULL → \0
它隐含了一个前提条件:
一个字符 = 一个字节(ASCII 语义)
在 ASCII 世界里,这个假设是成立的。 但在 GBK / BIG5 世界中,这个假设从根本上就是错的。
三、根本问题:字符集不一致
在 GBK 编码 中:
- 一个汉字 = 两个字节
- 字节结构为:
[高字节][低字节]
- 高字节范围:
0x81 – 0xFE
关键点在于:在 GBK 的合法编码中,存在低字节为 0x5C(反斜杠)的字符组合。而 0x5C,恰好就是 addslashes() 用来“保护单引号”的字符。
四、转义是如何“失效”的(核心原理)
以最经典的构造为例:
%df%27
① PHP 层(addslashes)
原始输入:
0xDF 0x27addslashes 处理后:0xDF 0x5C 0x27
在 PHP 看来:单引号已经被成功转义 ✔
② MySQL 层(GBK 解析)
0xDF 0x5C → 一个合法的 GBK 汉字
0x27 → 单引号
MySQL 的理解是:
\不是转义符- 它只是“汉字的一部分”
- 单引号重新获得 SQL 语义
👉 转义在数据库层被彻底瓦解
五、为什么和 GET / POST 没关系?
很多人会在第 34 关产生一个错觉:“这是 POST 注入,是不是不一样?”
结论非常明确:宽字节注入与 GET / POST 无关
原因很简单:
-
GET / POST 只是 HTTP 传参方式
-
宽字节注入发生在:
-
字符编码
-
防御函数
-
数据库解析
只要:
- 数据进入 SQL
- 使用了 addslashes()
- 数据库是多字节字符集
👉 漏洞就成立
六、为什么“汉”这个字可以直接绕过?
像这种 payload:
汉’ and 1=1 —
之所以能生效,并不是因为“汉”特殊,而是因为:
-
它在 GBK 中本身就是合法双字节字符
-
它的编码结构满足:
-
前一字节参与宽字节解析
-
后续的转义被数据库重新解释
本质上:这是“字节级漏洞”,不是“汉字漏洞”
换一个满足条件的汉字,效果是一样的。
七、宽字节注入速查表
1️⃣ 可利用的高字节范围(GBK)
0x81 – 0xFE
只要满足:
[GBK 高字节] + 0x5C
就可能构成合法字符。
2️⃣ 常见测试字节组合(URL 编码)
| 高字节 | 示例 Payload |
| — | — |
| DF | %df%27 |
| BF | %bf%27 |
| A1 | %a1%27 |
| A2 | %a2%27 |
| A3 | %a3%27 |
| B0 | %b0%27 |
| B1 | %b1%27 |
| C0 | %c0%27 |
| D0 | %d0%27 |
| E0 | %e0%27 |
⚠️ 是否成功取决于:
- 数据库字符集
- 连接字符集
- MySQL 版本
3️⃣ 可用于测试的中文字符(示例集)
以下字符在 部分 GBK 环境中可作为测试起点(亲测均可用):
汉 中 国 文 表 数 据 测 试 系 统 管 理
原则不是“背字”,而是:
任何 GBK 双字节字符都有可能成为入口
八、宽字节注入真正危险的原因
这个漏洞之所以危险,不是因为技巧高级,而是因为:
-
addslashes() 仍被大量历史项目使用
-
很多系统:
-
数据库是 GBK
-
开发者却以为自己在 ASCII 世界
-
漏洞隐藏在“看起来很安全”的代码里
九、总结一句话
宽字节注入不是 SQL 技巧,而是字符编码理解错误的必然结果。
只要记住这一点:任何脱离字符集上下文讨论“安全函数”的方案,本身就是不安全的。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:武文学网安 武文学网安 武文学网安《一次性把“宽字节注入”理解清楚》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论