二分法盲注在日志中表现为单IP短时间内对同一接口发起≥20次高频、等距、收敛型GET请求,payload含substr/ascii/length等函数及递进数字(如64→80→84→83),响应仅在固定字符串与空白间切换,且无合法Referer、User-Agent异常、参数超长、语义高度相似。

怎么从日志里发现二分法盲注的请求特征
二分法盲注不是随机猜,而是有明确节奏的高频、等距、条件收敛行为。它不像手工布尔盲注那样试探零散,会在短时间内对同一接口发起大量 and ascii(substr(...)) > X 或 and length(...) > Y 类型请求,且 X / Y 呈现明显二分递进(比如 64→96→80→88→84→82→83)。
关键识别点:
- 单 IP 在 10 秒内对同一
id参数路径发起 ≥ 20 次 GET 请求,响应时间波动小但返回内容仅在 “You are in” 和空白间切换 - URL 中
payload高频出现substr、ascii、length、ord、mid等 MySQL 字符处理函数 - 请求中
>、、=比较操作符与数字组合密集,如ascii(substr(database(),1,1))>64→>80→>72 - 无真实业务含义的固定字符串出现在 payload 中,例如反复出现
security、information_schema、table_name
为什么 WAF 规则匹配 ascii(substr 这类模式容易误杀或漏杀
单纯用正则匹配 ascii(substr 或 length( 是低效的——攻击者只需大小写混用(AsCiI(sUbStR)、插入空格、用 ord 替代 ascii、或改用 hex+substr 绕过。更麻烦的是,合法业务也可能调用这些函数(比如后台导出功能需动态拼表名)。
真正该盯住的是「行为上下文」:
- 不来自已知前端 JS 构造的请求(即无 referer 或 referer 不含 /static/ /js/)
- 请求头中
User-Agent是 Python-requests / curl / sqlmap(可建 UA 黑名单,但需定期更新) - 参数值长度异常:正常 ID 是数字,而盲注 payload 往往超 50 字符且含大量括号和引号
- 同一会话中连续请求的 payload 语义高度相似,仅中间数字变化(可用 minhash 或编辑距离做轻量聚类)
如何用 Nginx + Lua 实现实时请求节流与临时封禁
在入口层拦截比等应用层解析 SQL 更快。Nginx 的 limit_req 只能控频次,不够智能;配合 OpenResty 的 Lua 脚本才能做字段级判断。
示例逻辑(放在 access_by_lua_block):
local uri = ngx.var.request_uri
if string.match(uri, "id=.-[a-zA-Z_]+%([^%)]*%)") then
local count = tonumber(ngx.shared.dict:get("blind_" .. ngx.var.remote_addr) or "0")
if count > 15 then
ngx.exit(429)
end
ngx.shared.dict:incr("blind_" .. ngx.var.remote_addr, 1)
ngx.timer.at(60, function() ngx.shared.dict:delete("blind_" .. ngx.var.remote_addr) end)
end
注意点:
- 别只匹配
substr,要覆盖mid、substring、ord、hex、unhex等常见变体 -
ngx.shared.dict必须提前在nginx.conf的http块中定义,否则运行时报错nil value - 封禁时间设为 60 秒足够——二分法爆一个字符最多 7 次请求,15 次已覆盖 2–3 个字段,再往上基本就是自动化工具了
数据库层能否直接感知二分法盲注
不能靠 SQL 解析引擎实时识别,但可以借力审计日志+行为画像。MySQL 8.0+ 的 audit_log 或 Percona Server 的 slow log 开启 full mode 后,能记录每条查询的执行时间、返回行数、客户端 IP。
真正有效的检测方式是聚合分析:
- 同一 IP 在 30 秒内触发 ≥ 10 条返回行数为 0 或 1 的
SELECT,且 WHERE 条件含嵌套函数调用(如ascii(substr(...))) - 查询文本中常量部分变化极小(用 Levenshtein 距离算,相邻查询相似度 > 0.85)
- 这些查询集中在
information_schema或系统表,而非业务表
这类信号需要外部系统(如 ELK 或 Grafana Loki)做滑动窗口统计,数据库自身不提供实时阻断能力。最易被忽略的一点:很多团队只监控慢查询,但盲注的每次请求都很快(long_query_time 检测。










