使用UNION SELECT查询information_schema.tables的table_name字段失败求助
解决UNION SELECT查询table_name失败的思路
嘿,这个问题我在做SQL注入测试时碰到过好多次,咱们一步步拆解可能的原因和对应的解决办法:
1. 字段类型不匹配(最常见原因)
UNION查询要求前后两个结果集的字段数量完全一致,并且每个对应位置的字段类型要兼容。你用数字3能成功,但table_name不行,大概率是因为table_name(字符串类型)和原查询对应位置的字段类型不匹配(比如原字段是整数类型)。
解决办法:
- 先探测原查询的字段类型:可以用
UNION SELECT version(), '测试字符串' FROM information_schema.tables,如果执行成功,说明第二个字段支持字符串类型,那替换成table_name就没问题;如果失败,就换个位置放table_name,比如UNION SELECT table_name, 3 FROM information_schema.tables。 - 如果必须放在数字类型的位置,可以尝试类型转换(虽然可能因为字符串转数字报错,但部分场景可用):比如
CAST(table_name AS UNSIGNED)或者CONVERT(table_name, INT),不过更稳妥的还是找到字符串类型的字段位置。
2. 关键词或字符被过滤
有些WAF或者应用层会对table_name这类敏感关键词做过滤,导致SQL语句被拦截或解析失败。
解决办法:
- 尝试大小写混合绕过:比如写成
Table_Name或者tAbLe_nAmE。 - 用注释分割关键词:比如
table/**/_name(MySQL支持这种注释写法)。 - 用别名绕过滤:写成
UNION SELECT 1, tn, 3 FROM (SELECT table_name AS tn FROM information_schema.tables) t,通过别名隐藏原关键词。
3. 查询结果被截断或隐藏
有时候SQL语句其实执行成功了,但因为table_name内容过长、包含特殊字符,或者应用只显示部分结果,导致你以为查询失败。
解决办法:
- 截取部分内容:用
SUBSTRING(table_name, 1, 10)只取前10个字符,逐步查看完整内容。 - 转成十六进制输出:用
HEX(table_name)把字符串转成十六进制,这样即使有不可见字符也能正常显示,之后再转成原字符串即可。
4. 限定查询范围缩小结果集
如果information_schema.tables里的表太多,可能导致结果集过大触发某些限制,或者应用无法正常显示。
解决办法:
- 指定当前数据库:
SELECT table_name FROM information_schema.tables WHERE table_schema = DATABASE(),只查当前库的表,结果更精简。 - 用LIMIT分页查看:
SELECT table_name FROM information_schema.tables LIMIT 0,1,每次只查一条数据,避免结果过多。
5. 权限或数据库环境限制
虽然你能查version和其他字段,但少数情况下,当前数据库用户可能对information_schema.tables的table_name字段有访问限制,或者数据库是特殊版本(比如某些国产数据库对information_schema的结构做了修改)。
解决办法:
- 尝试查询其他系统表:比如MySQL里的
mysql.tables_priv,或者PostgreSQL里的pg_tables(如果是PostgreSQL环境)。 - 用
SELECT * FROM information_schema.tables LIMIT 1查看所有字段,确认table_name是否存在,以及其返回值是什么。
内容的提问来源于stack exchange,提问作者user3210594
相关产品推荐
相关产品推荐

