极详深度笔记:SQL注入快速判定与应对策略
1. 简述与核心观念
核心观念:为何要做"人形扫描器"?
- WAF现状 :现代WAF(防火墙)规则库非常完善,常规扫描器(如AWVS、AppScan)的自动Payload(如
AND 1=1)极易被拦截或封禁IP 。 - 漏网之鱼:老网站并非唯一目标,新网站因开发人员疏忽(如未覆盖所有参数、无法使用预编译的场景)依然存在大量注入 。
- 法律红线(高危预警) :
- 红线标准 :在SRC或授权测试中,证明漏洞存在的边界是获取
database()(库名)或user()(当前用户)。 - 严禁操作 :严禁执行
dump(脱库)、严禁读取公民个人信息、严禁在DELETE/UPDATE/INSERT业务点使用扫描器(可能导致批量删库或垃圾数据污染)。
- 红线标准 :在SRC或授权测试中,证明漏洞存在的边界是获取
注入类型的深度分类
- 按数据类型 :
- 整型 (Integer) :
select * from users where id = 1。参数直接参与运算,无需闭合引号 。 - 字符型 (String) :
select * from users where id = '1'。参数被引号包裹,占比最高,必须先闭合引号才能执行后续语句 。
- 整型 (Integer) :
- 按位置 :
- 常规:GET/POST 参数。
- JSON注入:常见于API接口,需注意JSON格式破坏问题 。
- 排序注入 (Order By) :重难点 。出现在
ORDER BY后面。因为ORDER BY后的参数如果是字符串(如'1')会导致排序功能失效,所以开发人员往往无法使用预编译(Prepare Statement),只能直接拼接,导致必然存在注入风险 。
2. 常规注入手动判定(无视WAF技巧)
整型判定 (Integer Injection)
核心原理:数据库会将数学运算结果作为参数值执行。WAF通常只拦截SQL关键字,不拦截数字运算。
- 减法运算(首选推荐) :
- 操作 :输入
id=2-1。 - 现象 :如果页面返回的内容与
id=1的内容完全一致 ,且与id=2不同,则证明数据库执行了减法运算,存在注入 。
- 操作 :输入
- 加法运算(避坑指南) :
- 操作 :输入
id=1+1。 - 坑点 :在 URL (GET请求) 中,
+号会被浏览器解码为空格。因此传入后端的变成了id=1 1,导致测试失败 。 - 修正 :必须对加号进行 URL 编码,输入
id=1%2b1。若页面返回id=2的内容,则存在注入 。
- 操作 :输入
- 逻辑运算 :
id=1 and 1=1/id=1 and 1=2。- 缺点 :
AND是 WAF 的重点拦截对象,容易触发拦截,不如算术运算隐蔽 。
字符型:四法快速判定(核心技巧)
原理 :利用 SQL 语法的引号配对规则。此方法不使用 AND、OR 等敏感词,误报率极低且能绕过绝大多数 WAF 。
假设后端 SQL 为:SELECT * FROM table WHERE id = '输入值'
- 输入
'(1个单引号) →\rightarrow→ 报错- 后端变成 :
id = '1'' - 解析:3个单引号,不成对,导致 SQL 语法错误 。
- 后端变成 :
- 输入
''(2个单引号) →\rightarrow→ 正常- 后端变成 :
id = '1''' - 解析:第一个引号是闭合,第二个和第三个引号组成了空字符串(或转义),第四个是后端的闭合。语法合法,逻辑通过 。
- 后端变成 :
- 输入
'''(3个单引号) →\rightarrow→ 报错- 后端变成 :
id = '1'''' - 解析:5个单引号,不成对,语法错误 。
- 后端变成 :
- 输入
''''(4个单引号) →\rightarrow→ 正常- 后端变成 :
id = '1''''' - 解析:两对空字符串,语法合法 。
- 后端变成 :
判定结论 :只要符合 "报错 - 正常 - 报错 - 正常" 的规律,90% 以上概率存在字符型注入。
闭合与注释的细节
--+(MySQL注释符) :- SQL 标准注释是
--(后面必须有一个空格)。 - 在 URL 中,空格若未编码容易丢失,所以习惯用
+代替空格(URL解码后为空格),即--+。
- SQL 标准注释是
#(Hash注释符) :- 坑点 :在 URL 中,
#代表锚点(Fragment),不会发送给服务器。 - 修正 :必须编码为
%23才能被后端接收为注释符 。
- 坑点 :在 URL 中,
- 利用闭合绕过注释 :
- 如果注释符被过滤,可以使用
'='或' and '1'='1来手动闭合后端的单引号 。
- 如果注释符被过滤,可以使用
3. Order By 排序注入手动判定
为什么 Order By 无法预编译?
- 预编译机制:预编译将参数视为"值"而非"代码"。
- 冲突点 :如果在
ORDER BY ?中传入'id',数据库会将其解析为按照字符串 "id" 排序 (即所有行都一样),而不是按照列名id排序。 - 结果:为了功能正常,开发人员必须使用拼接,从而导致注入 。
四法快速判定 (利用多列排序特性)
原理 :ORDER BY 支持多列排序(order by col1, col2)。我们可以注入一个新的排序字段。
Payload 构造流程 (假设注入点在 order by 后):
1 desc, 1→\rightarrow→ 正常回显- 含义:先按第1列倒序,如果有相同值,再按第1列正序。逻辑合法 。
1 desc, 0→\rightarrow→ 报错- 含义:尝试按第0列排序。SQL中列号从1开始,第0列不存在,必报错 。
1 desc, 2→\rightarrow→ 正常回显- 含义:假设表中至少有2列,逻辑合法 。
1 desc, 9999→\rightarrow→ 报错- 含义:尝试按第9999列排序,超出列数范围,必报错 。
避雷与高级玩法
- 不参与排序陷阱 :
- 如果在
ORDER BY后注入if(1=1,1,2)或sleep(5),这些函数会执行。 - 但是 :函数的返回值通常被视为常量,不会改变数据的排序顺序。
- 误区:不要试图观察"排序是否变化"来判断布尔盲注,而应该直接观察是否报错或是否延时 。
- 如果在
- 利用 :可以直接配合报错注入语句(如
updatexml)在排序处直接获取数据 。
4. JSON / Int类型 SQL注入实战
原始类型与格式破坏
- 场景 :API 接收 JSON 数据,如
{"id": 1}。 - 常见错误 :测试时直接输入
{"id": 1'}。 - 后果 :JSON 规范要求键值对格式严格。
1'不是合法的 JSON 数字或字符串,导致 Web 服务器层(如 Tomcat/Nginx/PHP解析器)直接抛出 JSON Format Error,请求根本没传到数据库,导致漏测 。
正确姿势:主动添加双引号
- 策略 :主动将 Int 类型转换为 String 类型测试。
- Payload :将
{"id": 1}修改为{"id": "1'"}。- 先闭合 JSON 的双引号,使其成为合法的 JSON 字符串。
- 如果后端代码没有强制校验类型(如
(int)$id),它会将字符串拼接到 SQL 中,此时单引号生效,触发注入 。
- 转义细节 :如果在 Payload 中需要用到双引号,必须使用
\"进行转义,否则会破坏 JSON 结构 。
XiaSql 插件辅助 (WAF不拦截原理)
- 工作原理:被动扫描插件,监听 Burp 流量。
- 判定逻辑 :
- 发包 A:插入
'→\rightarrow→ 记录响应包长度(通常变短或报错)。 - 发包 B:插入
''→\rightarrow→ 记录响应包长度(通常恢复正常)。 - 对比:若 A 与 B 的响应长度存在显著差异,则判定疑似注入 。
- 发包 A:插入
- 优势 :只发送单引号,不发送
SELECT、UNION等敏感词,WAF 几乎不拦截 。
5. SQLmap 的高级使用模式
基础与进阶指令
- GET型 :
sqlmap -u "url?id=1"。 - POST型 / 需鉴权型 :
- 步骤 :在 Burp 中抓取完整数据包 →\rightarrow→ 右键 "Copy to file" 保存为
1.txt。 - 指令 :
sqlmap -r 1.txt。 - 优势:完美解决 Cookie、Header Token 等鉴权问题,且能测试 JSON 或 Multipart 表单中的参数 。
- 步骤 :在 Burp 中抓取完整数据包 →\rightarrow→ 右键 "Copy to file" 保存为
- 精准打击 :
- 指令 :
sqlmap -r 1.txt -p id。 - 意义 :只测试
id参数。避免全量扫描浪费时间,适用于已知注入点的快速利用 。
- 指令 :
Shell 获取与提权 (高阶)
--sql-shell:- 提供交互式 SQL 环境。注意:除非是堆叠注入(Stacked Injection),否则只能执行
SELECT查询,不能执行INSERT/UPDATE。
- 提供交互式 SQL 环境。注意:除非是堆叠注入(Stacked Injection),否则只能执行
--os-shell(获取系统Shell) :- MySQL 苛刻条件 :
- DB用户为 Root 权限(拥有
FILE权限)。 - 知道网站绝对路径(物理路径)。
secure_file_priv为空(允许向任意路径写文件,默认是关闭的)。
- DB用户为 Root 权限(拥有
- 原理:上传两个文件,一个小马用于文件上传,一个用于执行 CMD 命令 。
- MySQL 苛刻条件 :
--os-pwn/ UDF 提权 :- 结合 Metasploit 进行 UDF 提权。注意:集成环境(如 phpStudy)的 MySQL 往往被阉割,可能导致提权失败 。
严禁操作(红线)
- 脱库 :
--dump或--dump-all。除非红队明确授权,否则在 SRC 挖掘中属于违法行为 。 - 破坏性测试 :在 增加、删除、修改 (Update/Insert/Delete)的功能点,绝对禁止使用 SQLMap 自动扫描,否则可能导致生产环境数据全毁 。
6. Xray - 无WAF环境下的最强扫描
配置与联动 (指哪打哪)
Xray 的 SQL 注入检测能力被认为是公开工具中最强的,建议使用"被动扫描"模式。
- 安装与证书 :
- 运行
xray genca生成 CA 证书。 - 必须同时导入到 操作系统受信任根证书 和 浏览器/Burp 中 。
- 运行
- 开启监听 :
xray webscan --listen 127.0.0.1:7777 --html-output report.html。
- Burp 联动配置 (核心步骤) :
- 在 Burp 中:
User Options->Upstream Proxy Servers。 - 添加规则:Destination:
*,Proxy:127.0.0.1:7777。 - 效果 :浏览器操作 →\rightarrow→ Burp (可手动修改包) →\rightarrow→ Xray (自动扫描) →\rightarrow→ 服务器。
- 在 Burp 中:
- 指定插件 :
- 为了防止扫描动作过大导致封禁或业务崩溃,建议只开启 SQL 插件:
--plugins sqldet。
- 为了防止扫描动作过大导致封禁或业务崩溃,建议只开启 SQL 插件:
- 重要避坑 :
- 测试结束后,务必关闭 Burp 的 Upstream Proxy,否则下次打开 Burp 会因为连不上 Xray 而导致所有请求失败(断网)。