BuuCTF supersqli 小白体验
这题 头发 -n
本文记录我啃一道初级ctf题目的过程。这篇文章算半实况吧因为前半部分是一个月前就写出来了的。但当时太菜了啥都不会做不出来所以一个月后今天又回来挑战来了。
靶机来源:https://buuoj.cn/
初始:
先点了提交看看,页面变化:
没记错的话这应该是php一个输出内容的功能吧,看出查询结果是一个数组。
该干什么?
随便输个符号,有报错
写了个不完整的联合查询,输出:
可以看出来,黑名单,拦截了常用关键字。
emmm,应该好像可以确定要用报错注入了?
不对,报错注入最后也得用select,或许第一步是怎么绕过黑名单。而且这个还是正则匹配,不像那种字符串删除的或者什么其他方式有的绕,好像那个/i还是case ignore。怎么整。
接下来这段时间我做了如下折腾:
零字节截断——截断了,但是真的截断了。
退格字符——没用,算控制字符进去了,其他的特殊字符也都是控制字符。、
其他各种双写也好注释也好编码也好都没有效果。
投降百度了一下牛皮点的select绕过方法,有个函数连接的好像挺给力。
总之先报出库名吧:-1'+and+extractvalue(1%2Cconcat(0x7e%2C(database())%2C0x7e))%3B+%23#
库名supersqli。
百度看了一下堆叠注入,通过分号隔离语句进行多条执行。于是做了个经典尝试:1';show tables;#
(察觉)
惊了。通过这种方式可以查出表的话,那就还可以查出表结构:
-1';desc words;#
从结构可以看出来就是正常查询的那张表。
但是接下来这个:1';desc 1919810931114514;# 什么都没有返回。
感觉是纯数字表名的问题,查资料改正后:1';desc `1919810931114514`;# 成功查询
是目标了。可接下来有什么能代替select的方法查到flag吗。
https://dev.mysql.com/doc/refman/5.7/en/handler.html
正中下怀!
payload:
-1'; handler `1919810931114514` open as aaa;handler aaa read first#
妙啊。
事后
随后翻看了writeup,看到write up讲了两种方法,都用到了堆叠注入,其中一个在使用show查出表结构之后,直接将有flag的表改名成了words表,也就是人家原本正常查询的表。。从而获得了flag,这是真骚操作。。
然后大佬还写了更骚的:
';use supersqli;set @sql=concat('s','elect `flag` from `1919810931114514`');PREPARE stmt1 FROM @sql;EXECUTE stmt1;--+
因为没理解,所以百度了里面一些关键字,得知这是利用数据库的储存过程实现的拼接语句注入方式。
其中set @sql是声明了一个名为sql的变量,值是拼接字符串 ,拼出来就是select flag from `1919810931114514`
而PREPARE 是预处理语句,语法:
PREPARE \<预处理名\> from <定义好的sql语句>;
原本是可以参数化sql语句来防止注入的,现在被大佬用于注入了。
最后一句EXECUTE <定义好的预处理>执行。