时间型盲注通过响应时间差异判断,需用SLEEP等函数配合AND 1=1/1=2测试,排除网络干扰且三次验证延迟≥4秒;布尔型则依赖页面差异,用ASCII数值比较更稳;修复须禁用拼接、强制预编译、关闭错误回显。

SQL盲注无法直接看到错误或回显数据,必须靠时间延迟或布尔响应来“猜”数据库内容——这意味着你得先确认它存在,再设计 payload 逐字提取,漏掉任意一环都会失败。
怎么判断目标是否存在时间型盲注(time-based)
核心是观察响应时间是否随 SQL 表达式真假变化而显著延长。常见误判点是忽略网络抖动和服务器负载干扰。
- 用
SLEEP(5)或BENCHMARK(5000000,ENCODE('test','salt'))(MySQL)触发延时,但必须加AND 1=1或AND 1=2控制逻辑分支 - 测试 URL 示例:
http://site.com/news.php?id=1 AND SLEEP(5)—— 若响应明显卡顿约 5 秒,且id=1 AND SLEEP(0)响应正常,则时间型盲注大概率存在 - 注意:某些 WAF 会拦截
SLEEP,可换用WAITFOR DELAY '0:0:5'(SQL Server)或pg_sleep(5)(PostgreSQL) - 别只测一次:至少连续发 3 次相同请求,排除偶然超时;响应时间差需稳定 ≥ 4s 才可信
如何用布尔逻辑验证字符内容(boolean-based)
本质是构造能返回“页面有/无变化”的条件语句,靠 HTML 差异、HTTP 状态码或空响应体判断真假。
- 典型 payload:
id=1 AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'—— 若页面正常显示,说明第一位是a;若空白/报错/跳转,则不是 - 优先用
ASCII()+ 数值比较,比字符串比较更稳定:id=1 AND ASCII(SUBSTRING((SELECT password FROM users LIMIT 1),1,1)) > 97 - 注意闭合方式:数字型参数直接拼接;字符型必须补全引号,比如
name=test' AND ... --,否则语法错误导致始终为假 - 别依赖“报错即为真”:很多应用统一返回 500,此时布尔逻辑失效,必须切到时间型
修复盲注漏洞的关键实操点
修复不是加个过滤就能完事——盲注往往意味着底层已存在未参数化的 SQL 拼接,补丁必须从根源切断输入参与查询构建的路径。
- 强制使用预编译语句:
PreparedStatement(Java)、pg_query_params()(PHP/PDO)、cursor.execute(sql, params)(Python/psycopg2)——变量永远不进 SQL 字符串 - 禁用动态表名/列名:如需动态结构,用白名单映射,而非直接拼接
ORDER BY $_GET['sort'] - 关闭数据库错误回显:MySQL 的
display_errors=Off、PHP 的error_reporting(0),避免泄露字段名或结构信息辅助盲注 - WAF 规则仅作补充:正则匹配
SLEEP\(|BENCHMARK\(可拦截基础 payload,但绕过手段极多(大小写混淆、内联注释、编码),不能替代代码层修复
最易被忽略的是:即使用了预编译,如果业务逻辑里还存在 if (user_input == 'admin') { sql = "SELECT * FROM logs WHERE level = 'ERROR'" } 这类基于用户输入决定 SQL 结构的写法,依然可能被诱导执行非预期查询——盲注的入口,永远藏在“把输入当逻辑分支依据”的那一行代码里。










