news 2026/9/10 22:36:25

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Web渗透之SQL注入-宽字节注入

本文仅用于网络安全技术学习与授权测试交流。本文实验皆在靶场进行,任何未经授权使用文中技术的行为均与作者无关,请务必遵守法律法规,获得许可后方可进行渗透测试。

目录

一、概念

1、核心原理

2、简单示例

3、典型场景与代码

4、触发条件

5、与普通注入的区别

6、防御措施

7、实际利用(合法测试环境)

8、总结

二、宽字节注入的典型过程

1、漏洞代码分析

2、攻击 Payload 与结果

3、总结

三、靶场注入示例

1、环境确认与初步探测

2、测试注入点是否存在

2.1 使用延时注入初步验证

2.2 布尔条件测试

3、利用布尔盲注获取数据库信息

3.1 获取数据库名长度

3.2 逐个字符猜解数据库名

4、使用联合查询直接获取数据库名

一、概念

宽字节注入是一种利用数据库字符集编码差异绕过转义防御(如addslashesmysql_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 id='1運'',实现了注入。

3、典型场景与代码

// 数据库连接设置为 GBK mysql_query("SET NAMES 'gbk'"); $name = addslashes($_GET['name']); $sql = "SELECT * FROM users WHERE name='$nam'";

攻击者输入name=1%df' or 1=1 --,利用宽字节特性逃逸转义。

4、触发条件

  1. 数据库连接使用了宽字节字符集(如 GBK、GB2312、BIG5、Shift_JIS)。

  2. PHP 使用了转义函数(如addslashesmysql_real_escape_string,但后者在设置正确字符集时可能无效)。

  3. 客户端提交的数据未做更严格的过滤或预处理

5、与普通注入的区别

  • 普通注入:通过闭合引号、注释符绕过。

  • 宽字节注入:通过构造宽字节使反斜杠失效,从而让单引号“活过来”。

6、防御措施

  1. 使用参数化查询(Prepared Statements):最彻底的方法,无需关心字符集。

  2. 统一使用 UTF-8 字符集:UTF-8 中%df%5c不是一个有效的多字节字符,反斜杠不会被吞掉。设置SET NAMES 'utf8'或使用charset=utf8

  3. 避免使用 GBK/GB2312 等宽字节编码,或确保转义函数正确处理(如mysql_set_charset('gbk')配合mysql_real_escape_string可防御,但推荐直接上参数化查询)。

  4. 输入过滤:过滤%df%5c等危险字符,但不如前两种可靠。

7、实际利用(合法测试环境)

在宽字节环境下,探测注入:

http://example.com/?id=1%df' and 1=1 --

如果返回内容与1' and 1=1类似,则存在宽字节注入。

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 与结果

Payload

http://127.0.0.1/demo3.php?id=1%bf union select 1,2,3 limit 1,1 -- -

执行过程

  1. 用户输入1%bf%bf是一个十六进制字节(191)。

  2. addslashes会在单引号前加反斜杠,但这里并没有单引号?注意:代码中$id被拼接进 SQL 时会用单引号包裹,如'{$id}'。传入1%bf,实际字符串为1后跟一个字节0xbf

  3. 然而,攻击者最终目的是要让原本的闭合单引号失效。实际注入的完整 payload 是1%bf' union ...。因为在 URL 中单引号被编码为%27,但为了展示,图中写的是1%bf union...,可能省略了单引号?注意图中显示的 SQL 语句:select * from userinfo where id='1' 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。由于bf5c组成一个有效的 GBK 字符(如),反斜杠被消耗,剩下的27即为独立的单引号,从而闭合了原 SQL 中的引号。然后攻击者可以追加union select ...

执行的 SQL 最终变为:

select * from userinfo where id='1' union select 1,2,3 limit 1,1 -- -'

成功执行了联合查询,并返回了数组[1,2,3]


3、总结

  • 宽字节注入原理:利用 GBK 等字符集中,某些字节与反斜杠0x5c组成多字节字符,导致转义符失效。

  • 触发条件:数据库连接使用SET NAMES gbk(或类似宽字符集)且应用程序使用转义函数(如addslashes)。

  • 防御方法:使用参数化查询(推荐)或统一使用 UTF-8 字符集,并避免使用不安全的转义函数。

三、靶场注入示例

以pikachu靶场为例

1、环境确认与初步探测

  1. 正常访问访问http://192.168.179.135/pikachu-master/pikachu-master/vul/sqli/sqli_widebyte.php,输入用户名kobe查询,返回uid=3, email=kobe@pikachu.com。确认正常功能。

  2. 确认字符集与宽字节条件查看页面源码或提示,得知该模块使用 GBK 编码,并且存在宽字节注入漏洞。


2、测试注入点是否存在

2.1 使用延时注入初步验证

Payload(POST 参数name):

kobe%bf'or sleep(5)--
  • %bf是宽字节字符,与转义添加的反斜杠%5c组合成 GBK 汉字,从而吃掉反斜杠,使单引号存活。

  • 提交后页面响应明显延迟 5 秒,确认存在时间盲注,同时说明宽字节注入有效。

2.2 布尔条件测试

  • 永真条件kobe%bf'or 1=1--结果返回了所有用户(uid 从 1 到 7 等多条记录),说明条件生效。

  • 永假条件kobe%bf'or 1=2--返回“您输入的username不存在”,说明页面能区分真/假。 → 确认存在布尔盲注。


3、利用布尔盲注获取数据库信息

3.1 获取数据库名长度

Payload

kobe%bf'or length(database())=7--

页面正常返回多条用户数据(真),说明length(database()) = 7成立。 若改为=8则返回空,从而确定数据库名长度为7

3.2 逐个字符猜解数据库名

使用substr(database(),1,1)结合 ASCII 码或十六进制比较。

示例(猜第一个字符是否为p):

kobe%bf'or substr(database(),1,1)=0x70--
  • 0x70是字母p的十六进制。页面返回正常(真),说明第一个字符是p。 后续依次猜解substr(database(),2,1)等,最终得到数据库名pikachu


4、使用联合查询直接获取数据库名

由于联合查询需要确定列数,且该模块存在回显位置,用户直接使用了联合查询(截图显示成功)。

Payload

kobe%bf'union select database(),2 limit 0,1--
  • 闭合前面的查询,limit 0,1确保只返回联合查询的结果。

  • 执行后在页面上your uid处显示pikachuyour email显示2。 → 成功获取当前数据库名。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 22:35:26

昇腾GE历史注册协议设计

History Registry Protocol 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、…

作者头像 李华
网站建设 2026/9/10 22:32:31

论文初稿与实习并行,按碎片时间推进的节奏

白天在岗实习,论文初稿只能挤通勤、午休和下班后的零散时间——拖慢进度的往往不是时间太短,而是每次坐下都要先花十几分钟回忆"上次写到哪"。知学术AIPaperGPT 用免费智能大纲起步,AI 无限改稿能力与 1 小时全文承接这套"接续…

作者头像 李华
网站建设 2026/9/10 22:32:25

Multisim 14.3 安装与汉化指南(附下载链接)

Multisim 14.3 安装与汉化指南(附下载) 安装包获取 夸克网盘: 我用夸克网盘给你分享了「Multisim 14.3安装2026」,点击链接或复制整段内容,打开「夸克APP」即可获取。 链接:https://pan.quark.cn/s/786fcd…

作者头像 李华
网站建设 2026/9/10 22:30:35

大学院笔试练习:线性代数与数据结构备考全解析

说实话,看到“大学院-筆記試験練習”这个标题的时候,我脑子里第一时间浮起来的画面,就是当年备考时图书馆桌子上一摞草稿纸、一支笔、一杯咖啡的日子。“大学院”这个词,熟悉日本留学方向的同学应该都知道,指的是研究生…

作者头像 李华