SQL注入检测前必须确认参数是否参与SQL拼接、后端是否关闭错误回显、WAF是否拦截基础payload;再用ORDER BY和UNION SELECT验证回显位置;布尔盲注需结合时间延迟与随机头防限速;information_schema查不到表名多因权限或版本限制。

SQL注入检测前必须确认的三个前提
不验证这三点,所有后续操作都可能误报或漏报:
- 目标参数是否参与拼接 SQL 查询(比如 id=1 最终变成 SELECT * FROM users WHERE id = 1)
- 后端是否关闭错误回显(error_reporting(0) 或 display_errors=Off 会让报错消失,但盲注仍可进行)
- WAF 是否已拦截基础 payload(尝试 ' OR '1'='1 返回 403 就得先绕过规则)
用 UNION SELECT 快速验证回显位置
这是最直接的“看到数据”的方式,适用于 MySQL / PostgreSQL / SQLite 等支持 UNION 的数据库:
- 先用 ORDER BY 探测字段数,比如 ?id=1 ORDER BY 3-- 成功但 ORDER BY 4 报错,说明有 3 列
- 再用 UNION SELECT NULL,NULL,NULL 占位,逐步替换为 VERSION()、DATABASE()、@@version 等函数验证回显点
- 常见坑:MySQL 5.7+ 默认禁止 UNION SELECT 中的 NULL 类型混用,得统一用字符串如 'a','b','c'
- 注意字符集问题:如果页面是 GBK 编码,%df%27 可能绕过单引号过滤
布尔盲注时怎么避免被限速/封 IP
当页面只返回“成功”或“失败”两种状态(比如登录页提示“用户不存在”),就得靠布尔逻辑逐位猜解:
- 不要用 AND ASCII(SUBSTR(...)) > 64 这类高频请求,容易触发 WAF 的频率规则
- 改用时间延迟 + 布尔组合,例如 AND IF(ASCII(SUBSTR(database(),1,1))=114,SLEEP(2),1),让真值延时更明显
- 每次请求前加随机 User-Agent 和 Referer,降低行为特征识别率
- 工具层面:sqlmap 的 --random-agent 和 --delay=1.5 是底线配置,但手工测试时更容易忽略 sleep 时间必须大于服务端平均响应时间
为什么 information_schema 查不到表名?
不是漏洞不存在,而是权限或版本限制导致:
- MySQL 8.0 默认禁用 information_schema.tables 的非特权访问,需改查 performance_schema 或 sys.schema_table_statistics
- 某些云数据库(如阿里云 RDS)会屏蔽 information_schema 所有查询,此时得用 SELECT * FROM mysql.db(需更高权限)或爆破常见表名(user、admin、account)
- 如果连 database() 都返回空,可能是应用用了连接池且每次查询走不同库,得先用 SELECT SCHEMA_NAME FROM SCHEMATA 看有哪些库可读
实际中最容易卡住的地方,是把“能执行 payload”等同于“能读数据”——很多环境允许报错注入但禁止跨库查询,或者开了 prepared statement 却没关掉 mysql_real_escape_string 的旧逻辑。得一层层确认数据库权限边界,而不是只盯着输入点。










