时间盲注需通过响应时间差识别,不能仅凭200状态码判断;必须构造延时请求(如sleep),并用三组交叉验证:基线?id=1 and 1=1响应≤300ms且波动小,?id=1 and sleep(5)显著延迟,排除网络抖动等干扰。

直接测响应时间差,别信“页面没报错就安全”
生产环境里最常被误判的,就是看到页面返回 200 且无错误信息,就认为没有盲注——这恰恰是时间盲注最典型的存活场景。它不靠报错或内容变化,只靠数据库执行 SLEEP()、pg_sleep() 或 WAITFOR DELAY 后的响应延迟暴露自己。你必须主动构造条件延时请求,并用稳定基准对比,否则永远发现不了。
用三组请求交叉验证延迟是否真实
单次 ?id=1 AND SLEEP(5) 响应慢了,可能是网络抖动、DB 负载高或 CDN 缓存未命中。真正可信的时间盲注信号,需要满足三个条件:
- 同一参数下,
?id=1 AND 1=1(基线)平均响应 ≤ 300ms,三次测量波动 -
?id=1 AND SLEEP(4)连续三次响应时间 ≥ 4200ms(即 4s + 网络毛刺余量) -
?id=1 AND SLEEP(0)或?id=1 AND (SELECT 1)响应时间回归基线水平
漏掉任意一组比对,都可能把 WAF 拦截重试、后端队列排队或 Redis 缓存穿透误判为漏洞。
按数据库类型选对延时函数,避开 WAF 关键字拦截
WAF 规则普遍盯死 SLEEP 和 WAITFOR 字样,但不同数据库有等效绕过写法:
- MySQL:优先用
BENCHMARK(1000000, MD5('test'))替代SLEEP(5),不触发函数名关键词 - PostgreSQL:用
pg_sleep(5)是标准,但若被拦,可改SELECT pg_sleep(5)加完整语句结构 - SQL Server:
WAITFOR DELAY '0:0:5'易被识别,换成IF 1=1 WAITFOR DELAY '0:0:5'增加语法复杂度 - Oracle:用
DBMS_LOCK.SLEEP(5),注意需目标账户有 EXECUTE 权限,否则会静默失败
别在没确认 DB 类型前硬塞 SLEEP——MySQL 里跑 WAITFOR 直接语法错误,响应快得像没注入,反而让你错过线索。
生产环境禁用 --technique=T 自动扫描
sqlmap 的 --technique=T 默认每字符尝试 10+ 次延时请求,一次 -u "http://x?id=1" 可能发出上百个 SLEEP(5),极易触发:
- WAF 的“5 秒内 3 次延时请求”熔断规则
- 应用层连接池耗尽(尤其 HikariCP 默认 max-active=20)
- 数据库审计日志写满 / SOC 实时告警
真要扫,必须走流量镜像路径:sqlmap -r prod_requests.txt --skip-static --batch --technique=BEU --time-sec=3,其中 --time-sec=3 把默认 5 秒降为 3 秒,减少单次影响;--technique=BEU 排除高危的 U(Union)和 E(Error)技术,只留 B(Boolean)和 E(Error)中较温和的部分——时间盲注本身已足够敏感,没必要叠加其他探测维度。
真正难的不是构造 payload,而是区分“数据库真在 sleep”和“中间件在 retry”。每次延迟都要回溯 Nginx access_log 中 upstream_response_time 字段,确认延迟发生在 upstream 阶段而非 proxy 阶段——这点几乎没人查,但一查一个准。











