| name | sqli |
| description | SQL 注入测试技能 —— 面向真实业务系统,覆盖参数边界、布尔/时间盲注、WAF 绕过与误报规避,产出可复现 PoC 与证据链 |
| phase | test |
| severity_focus | high |
SQL 注入测试技能(SQLi)
定位:面向真实授权业务系统的注入验证,不是 CTF writeup 的 payload 罗列。重点在「参数边界判定、注入点定位、响应差异建模、误报排除」,而非追求一个 flag。
触发条件
满足以下任一信号即应进入本技能(侦察阶段产出 endpoints.json 已标注候选注入点优先级):
- 端点存在用户可控的查询参数(
id / q / search / sort / 分页 page / offset / 筛选器 filter),且响应体随参数值语义变化(列表条数、字段、排序顺序)。
- HTTP 头部带结构化参数:
Cookie 中的会话/偏好字段、X-Forwarded-For、Referer、User-Agent(后端记日志时常拼入 SQL)。
- JSON / XML / GraphQL 请求体存在嵌套字段,后端 ORM 层将其展开为查询条件(ORM 不等于安全,
order_by / group_by 字段名注入、raw() / extra() 逃逸是高发点)。
- 二阶注入信号:注册/评论/个人资料页写入的值,在另一查询场景(如后台统计、导出)被拼入 SQL 但前端不可见——需结合
assets.json 的数据流追踪判断是否值得测。
- 错误回吞但响应可观测差异:同一参数,传入合法值与非法值(超大整数、非预期字符)时,响应大小/耗时/字段集合出现稳定可复现差异。
三层测试模型
对齐 DESIGN §3.1:L1 探测(快速排除明显不存在)→ L2 验证(确立可复现差异)→ L3 绕过(对抗真实 WAF / 风控)。每层只做上一层成立后才推进的事,避免对每个参数都跑完整 payload 表烧 token。
L1 探测
目标:用最小请求量判定「该参数是否可能受 SQL 语法影响」,不追求确认漏洞。
- 布尔语义探针:对同一参数分别传
真值基准 与 AND 1=1 / AND 1=2(数字型)或 ' AND '1'='1 / ' AND '1'='2(字符型),比较响应指纹(状态码、Content-Length、关键 DOM 节点数、耗时)。
- 时间探针:对疑似盲注参数传
; WAITFOR DELAY '0:0:3' --(MSSQL)/ AND SLEEP(3)(MySQL)/ pg_sleep(3)(PG)/ DBMS_PIPE.RECEIVE_MESSAGE('a',3)(Oracle),以响应延迟相对基准的稳定偏移(非单次抖动)为信号。
- 语法错误探针:传
' / " / ) / \ 单字符,观察是否触发数据库原生错误回显、HTTP 500、或响应结构塌缩(ORM 异常常表现为 500 + 框架默认错误页)。
- 边界类型混淆:数字参数传字母串、字符串参数传超大数字、JSON 字段传数组/对象——ORM 反序列化失败有时会泄露底层 SQL 片段。
L1 的产出是「候选参数 + 初判数据库指纹 + 注入类型假设」,写入 findings.json 的 hypothesis 字段,不直接定级。
L2 验证
目标:把 L1 假设变成可复现、可向他人演示的差异证据,禁止仅凭响应码或单次延迟下结论。
- 布尔盲注建立稳定基线:重复 N 次(≥3)取「真条件响应」与「假条件响应」的指纹差,确认差异在去掉网络抖动后稳定存在;记录两组完整请求/响应(脱敏后)。
- 时间盲注建立统计:连续发 K 次(≥5)延迟探针 + K 次基准请求,用延迟分布(中位数而非单点)判定是否触发
sleep;单次 3s 不能定论(GC、慢查询同样造成延迟)。
- 联合查询/报错注入:若 L1 暴露回显或报错,用
ORDER BY n 二分定位列数,再取可见回显列;报错型优先用函数回显(如 MySQL updatexml / PG CAST 异常 / MSSQL convert),避免堆叠多请求。
- 数据库指纹收口:联合查询确定列数 + 版本函数(
@@version / version() / banner from v$version)一起取,把「假设的库」收敛为「确认的库」,定级与后续 payload 都依赖它。
L3 绕过
目标:在目标存在 WAF / 风控 / 输入过滤时,验证注入是否仍可达——这才是实战与靶场的分水岭。
- 关键字过滤识别:逐个传
SELECT / UNION / AND / 空格 / 注释符,记录哪些被拦截(403 / WAF 页 / 静默丢弃),建立「过滤面」清单,而非盲目堆 payload 字典。
- 编码与变形:对被拦关键字尝试大小写混写、内联注释
/**/、URL 双重编码、%0b 等空白替代、等价函数(SUBSTRING↔MID、ASCII↔ORD);变形以「绕过该特定 WAF」为目标,逐个验证而非组合爆破。
- 语义等价改写:
AND 被禁用 && / BETWEEN;空格被禁用括号语法 UNION(SELECT...);引号被转义时尝试宽字节(GBK 场景 %bf%27)或 CHAR() 构造。
- 风控对抗:控制单 IP 请求频率、轮换行为正常的请求伪装成业务流(先访问首页再发探针)、避免在风控采样窗口内集中触发——目标是「证明在真实对抗环境下注入仍可达」,不是触发风控封禁。
L3 成立是定级上调的依据(绕过防护 = 利用链真实可达),但产出仍须 PoC + 证据,不得凭「能绕过」直接定级。
证据要求
什么才算确认 SQLi(缺一不可,禁止仅凭响应码/单次现象下结论):
- 可复现:同一 PoC 在去掉抖动后重复执行(≥3 次)稳定复现差异或回显,记录每次的请求与响应指纹。
- 对照基线:提供「注入 payload」与「等价无注入基准」的成对请求/响应(如
id=1 vs id=1 AND 1=2),证明差异由 SQL 语义而非业务逻辑引起。
- 数据库确证:至少一条证据指向具体数据库与版本(版本函数回显、报错中的方言特征、
information_schema / sysobjects 可访问性),避免「疑似注入」的模糊定级。
- 影响说明:注明该注入可读取/篡改的具体数据边界(当前库、跨库、是否 DBA 权限、是否可写文件/执行命令),基于已确认的权限而非假设。
- 证据脱敏:响应中出现的真实用户数据、业务记录只记录结构与条数,不落明文;发现的凭证样式字符串(连接串里的口令等)只存哈希。
禁止事项
- 仅授权目标:本技能只在
scope.yaml in_scope 且有书面授权的目标上运行;ScopeGuardHook 拦截即停,不尝试旁路自身防护。
- 不破坏数据:不执行
DROP / UPDATE / DELETE / INSERT / 写文件 / 执行系统命令等破坏性或持久化操作——证明可读性已足以定级,写操作不提供额外安全价值且违反只读原则。
- 凭证不落明文:响应或数据库内容中出现的口令、Token、连接串,证据里只记录哈希与类型,原文不入
findings.json / 日志 / 报告。
- 不超范围扩张:发现的注入点只能用于确认该参数的漏洞边界,不得据此横向探测 scope 外资产或枚举库表以外的系统信息。
- 不依赖错误回显作为唯一证据:错误回吞是常态,能确认就别只靠报错型;报错证据须与盲注证据至少二选一可独立成立。