宽字节注入、二次注入、堆叠注入:高级 SQLi 专题

文章目录

    • 一、先共用一张脑图
    • 二、宽字节注入:当"反斜杠"被吃掉
      • [1. 它在解决攻击者的什么问题](#1. 它在解决攻击者的什么问题)
      • [2. 为什么说它是"年代感"很强的洞](#2. 为什么说它是“年代感”很强的洞)
      • [3. 授权测试时怎么意识到"可能是宽字节"](#3. 授权测试时怎么意识到“可能是宽字节”)
      • [4. 怎么修(比背 payload 重要)](#4. 怎么修(比背 payload 重要))
      • [5. 一句收束](#5. 一句收束)
    • 三、二次注入:安全地走进去,危险地走出来
      • [1. 这是高级题里最"业务"的一种](#1. 这是高级题里最“业务”的一种)
      • [2. 常见真实长相](#2. 常见真实长相)
      • [3. 为什么自动化容易漏](#3. 为什么自动化容易漏)
      • [4. 授权测试怎么挖](#4. 授权测试怎么挖)
      • [5. 怎么修](#5. 怎么修)
      • [6. 一句话](#6. 一句话)
    • [四、堆叠注入:一句请求,多句 SQL](#四、堆叠注入:一句请求,多句 SQL)
      • [1. 它到底是什么](#1. 它到底是什么)
      • [2. 为什么有的库"怎么都堆叠不了"](#2. 为什么有的库“怎么都堆叠不了”)
      • [3. 授权测试里怎么证明"支持堆叠"](#3. 授权测试里怎么证明“支持堆叠”)
      • [4. 危害为什么常被高估或低估](#4. 危害为什么常被高估或低估)
      • [5. 和存储过程、批处理的关系](#5. 和存储过程、批处理的关系)
    • 五、三专题对照:怎么记才不容易混
    • 六、实战中的组合拳(认识即可)
    • 七、防御工程:把专题落进日常
      • [1. 代码审计加三枚探针](#1. 代码审计加三枚探针)
      • [2. 测试用例别只砸"当前参数"](#2. 测试用例别只砸“当前参数”)
      • [3. 配置基线](#3. 配置基线)
      • [4. 监控](#4. 监控)
    • 八、收尾

上一篇把 SQL 注入从手工到 sqlmap 走了一遍。有人读完会觉得:参数化一上,注入不就死了吗?话是没错,可真实项目里总有"历史包袱"和"聪明人自己造的轮子"------编码处理不一致、入库一次出库再拼一次、驱动居然允许多语句执行。于是就有了这三类更刁钻、也更容易在代码评审里漏掉的东西:宽字节注入、二次注入、堆叠注入


一、先共用一张脑图

普通注入:用户输入 → 拼进 SQL → 当场爆炸。

高级一点的,缝隙往往在别处:

text 复制代码
宽字节:   "转义"和"数据库编码"不是同一套尺子,逃逸字符被吃掉
二次注入: 第一次像安全地存进去了,第二次再拼 SQL 时才爆炸
堆叠注入: 一条请求里塞多句 SQL,数据库驱动居然肯挨个执行

三者可以叠在一起出现,但学习时最好分开想清楚。


二、宽字节注入:当"反斜杠"被吃掉

1. 它在解决攻击者的什么问题

很多老 PHP 代码喜欢用 addslashes()、魔法引号、或自己在单引号前加 \,以为这样字符型注入就废了。想法很朴素:' 变成 \',字符串闭合不了。

宽字节注入盯的是另一处:若连接数据库时用了某些多字节编码 (经典讨论最多的是 GBK ),而转义又按"单字节思维"加反斜杠,攻击者可以构造一种两字节组合------前一个字节把后面的 \"吃进"一个合法汉字(或其它多字节字符)里,于是 ' 重新露出原形,重新具备闭合字符串的能力。

人话版:

你以为你给引号穿了防弹衣(前面加了 \),

编码一搅合,防弹衣和别人拼成了别的字,引号又光着了。

2. 为什么说它是"年代感"很强的洞

它高度依赖:

  • 应用层按字节做转义;
  • 数据库链路仍是 GBK / GB2312 一类;
  • 字符集在连接、库、表、客户端之间还不统一。

今天大量系统默认 UTF-8 / utf8mb4,宽字节这条路会窄很多。但别得意:内网老 OA、老电商、政府项目、十年不升级的 PHP,依旧能撞见。供应链里一个老组件也能把你拖回 GBK 时代。

3. 授权测试时怎么意识到"可能是宽字节"

线索通常很"运维":

  • 响应头或页面暗示国产老栈、GBK;
  • 数据库/连接配置里能看到 GBKGB2312
  • 普通 ' 被转义看起来没戏,但团队怀疑转义只做在应用层;
  • 白盒直接搜:addslashes、自制 escape、却未见真正参数化。

黑盒下乱撞宽字节 payload,既吵又容易误判。更稳的是:先确认编码链路,再在测试环境验证。能白盒就白盒。

4. 怎么修(比背 payload 重要)

按优先级:

  1. 彻底参数化------转义游戏直接退场;
  2. 全链路统一 UTF-8 / utf8mb4,连接串显式指定;
  3. 不要用 addslashes 当防注入方案;
  4. 对遗留库迁移编码时做好数据评估,别只改半截。

看到有人说"我们加了宽字节 WAF 规则",我会问:编码统一了吗?预编译了吗?没有的话,规则只是多一层运气。

5. 一句收束

宽字节注入教你的不是更花的攻击技巧,而是:

任何"在字符串层面手工逃逸"的方案,都要和字符编码绑在一起审查;编码一错,逃逸就可能失效。


三、二次注入:安全地走进去,危险地走出来

1. 这是高级题里最"业务"的一种

二次注入(Second-Order Injection)的剧本常常是:

  1. 攻击者提交一段看起来无害、甚至通过了当下校验与转义的输入;
  2. 应用把它存进数据库;
  3. 之后另一次查询------可能是别的接口、定时任务、管理端功能、触发器------把库里的值取出来,又拼进 SQL;
  4. 这时候才发生注入。

第一次请求的日志可能完全干净;安全测试如果只砸"当前参数",也会漏。

我特别想强调:二次注入不是因为攻击者更聪明,而是因为开发把"存进去"和"再拿出来用"当成了两个世界。存的时候当脏数据防;拿的时候当可信数据用。数据库不是信任根。

2. 常见真实长相

  • 用户改昵称 / 地址 / 备注,管理端按昵称搜索,拼了 SQL;
  • 注册用户名写进 profile,某处 WHERE user='...' 又拼了一次;
  • 工单系统、CMS 标签、导入的 Excel 字段;
  • 安全设备或审计系统把"原始攻击串"存下,再在报表里二次查询(是的,安全产品也干过这种事)。

有时候第一次输入还有长度限制、过滤关键字;但存进去的是"半成品",二次拼接时过滤策略并不一致,照样爆。

3. 为什么自动化容易漏

sqlmap 默认强在"当前请求的参数 → 当前响应"。二次注入需要:

  • 找到写入点触发点
  • 两者可能隔着角色、时间、甚至异步队列;
  • 触发点不一定回显给你这个会话。

所以它更吃业务理解。工具可以辅助,替代不了脑。

4. 授权测试怎么挖

我自己的习惯步骤:

(1)画数据生命周期

这个字段从哪里进、存在哪张表、哪些功能会读、读完干什么。像跟账一样跟字段。

(2)特意埋探针

在测试环境用可控账号,把昵称/备注改成带特殊字符的"探针串"(注意别破坏生产数据)。然后去所有会用到该字段的管理功能、搜索、导出点一点。

(3)看第二次查询是否参数化

白盒最爽:搜对该字段的二次拼接。黑盒就看触发时是否出现 SQL 异常、时间差、或业务结果异常。

(4)别只测"当前用户能看的页面"

二次触发经常在管理员视角、批处理、消息消费者里。测试账号体系要够。

5. 怎么修

说起来简单,做起来要改习惯:

  • 任何时候拼 SQL 都不信任"来自数据库的字符串"------它昨天可能来自用户;
  • 二次查询同样参数化;
  • 对业务上必须进 SQL 结构的字段(极少见)做白名单;
  • 写入侧过滤不能替代读出侧安全;
  • 代码审计 checklist 里加一条:"取出再拼 SQL 的点"。

有团队觉得"入库前已经 escape 了"。请回想宽字节:escape 本身就不牢;更何况二次使用时 escape 可能被解掉、或根本没带上。

6. 一句话

二次注入是信任边界画错了:把"库里的"当成"干净的"。


四、堆叠注入:一句请求,多句 SQL

1. 它到底是什么

堆叠(Stacked Queries)指在一次数据库执行里塞多条语句,例如概念上的:SELECT ...; UPDATE ...; --

若驱动/接口允许一次执行多语句,攻击者在注入点不仅能读,还可能改数据、调存储过程,危害面明显变宽。

注意:这和"UNION 注入"不是一路------UNION 是把查询拼进同一条 SELECT 的结果集;堆叠是多条语句依次执行

2. 为什么有的库"怎么都堆叠不了"

能不能堆叠,很大程度取决于:

  • 数据库类型与连接方式;
  • 是否显式打开多语句选项(历史上某些 PHP 连接方式对此很敏感);
  • 中间件、ORM、预编译接口是否根本不支持一次丢多句。

所以你会看到教材里写"MySQL 也可以堆叠",真打目标却纹丝不动------不一定是你菜,可能是链路不允许。老手先试探是否支持多语句,再谈利用。

3. 授权测试里怎么证明"支持堆叠"

在授权环境,目标通常是证明风险,而不是把库搅烂。优先用:

  • 相对无害的时间差异、会话变量、或只读类确认;
  • 严格避免随手 DROP、大规模 UPDATE
  • 与客户事先约定可执行边界。

若手工不好证明,sqlmap 等工具在授权下也有对应探测技术选项------仍要控速、控范围,避免生产抖动。

4. 危害为什么常被高估或低估

高估: 以为有注入就一定能堆叠。不能。

低估: 一旦能堆叠,而账号权限又大,危害从"拖库"跃迁到"改账、插后门用户、清数据"。

修复时两刀一起砍:

  • 堵住注入(参数化);
  • 连接配置关闭多语句(若业务不需要);
  • 数据库账号最小权限。

即使将来又写出拼接,也少一道"多语句"的翅膀。

5. 和存储过程、批处理的关系

业务合法地使用多语句 / 批处理时,要分清入口:管理任务用单独高权限连接,面向用户的 Web 连接绝不打开多语句。别为了图省事共用一个 DSN。


五、三专题对照:怎么记才不容易混

宽字节 二次注入 堆叠注入
核心缝隙 编码与转义不一致 信任了库中数据再拼接 驱动允许多语句
何时爆 当前请求拼 SQL 时 往往在后续请求/任务 当前执行点支持多句
现代系统频率 相对少(UTF-8 普及) 仍常见 看配置与驱动
测试重点 编码链路、伪转义 字段生命周期 是否允许多语句
主修复 参数化 + 统一编码 全程参数化、不信任库字段 参数化 + 关闭多语句 + 权限

六、实战中的组合拳(认识即可)

真实漏洞偶尔会"套娃":宽字节让转义失效 → 当前请求注入成功 → 若可堆叠则危害升级;或第一次用宽字节写入恶意昵称 → 二次在管理端爆发。

分析时按层剥:

  1. 输入怎么进;
  2. 有没有伪安全转义;
  3. 编码是什么;
  4. 最终哪一次 query 拼了它;
  5. 那次执行允许多句吗;
  6. 账号能干什么。

能画完这六步,报告会非常漂亮,开发也没法用"我们有 addslashes"糊弄你。


七、防御工程:把专题落进日常

1. 代码审计加三枚探针

在 Code Review / 半自动审计里专门搜:

  • 手工 escape / addslashes / 自制 safe_sql
  • 取出数据库字段后的字符串拼接;
  • 连接配置里的多语句开关、过时驱动用法。

2. 测试用例别只砸"当前参数"

加两类用例:

  • 编码相关(遗留 GBK 系统);
  • 业务字段写入后再在管理端/批处理触发。

3. 配置基线

  • 连接字符集显式 utf8mb4;
  • 应用账号禁止多余权限;
  • 非必要关闭多语句;
  • 生产禁止 SQL 明细回显。

4. 监控

短时间大量语法错误、异常多语句模式、管理端搜索功能报错飙升------都可能是二次注入被触发的侧写。和 WAF 日志对着看。


八、收尾

宽字节注入提醒你:逃逸不是安全边界,编码才可能让边界破产。

二次注入提醒你:数据库里的未必干净,第二次拼接一样要命。

堆叠注入提醒你:语句执行器的能力边界,也是安全边界;能关的多语句就别开着。

高级 SQLi 专题写到这里,其实都在重复上一篇的那句老话------只是缝隙更隐蔽:

让用户数据永远只能当"值",不能当"语法";

让信任只来自明确的白名单与绑定,不来自"我曾经过滤过"。

你若今晚只做一件事:打开你们最老的那个业务库连接配置,看字符集和是否多语句;再找一个"用户可改、管理员可搜"的字段,问开发第二次查询绑参了没有。

这两眼,比再背十个高级 payload 更值回票价。


相关推荐
2301_780789663 小时前
DDoS 攻击溯源:DNS 水印标记 + 区块链存证的双保险
运维·服务器·网络·云原生·ddos
童槿顏丶4 小时前
GitLab部署到Linux
linux·运维·gitlab
微学AI6 小时前
从连接到安全落地:KES MCP Server 工程化实践的全记录
安全
小柒儿3366 小时前
从单Agent到多智能体系统:多智能体协作重塑自动化边界
运维·自动化
空堂与归7 小时前
Linux 命令实战:AI 开发者必备的终端操作手册
linux
A-刘晨阳7 小时前
数据主权时代:自主可控时序大模型TimechoAI筑牢关键基础设施安全防线
大数据·安全
QYR-分析7 小时前
注塑机机械手自动化装备行业发展研判:存量升级催生增量红利,2032 年市场规模逼近 9 亿美元
运维·自动化
安全指北针8 小时前
AI Agent自主入侵真实系统:OpenAI和Anthropic两大模型接连“失控“,给安全行业敲响了什么警钟?
人工智能·安全
牢姐与蒯8 小时前
Linux基本指令及知识点(二)
linux·运维·服务器