include('home.php');
?>
接着再看home.php
源代码,发现有两处传入参数j进行数据库操作,两处参数均无过滤。
$item = isset($_POST['item']) ? $_POST['item'] : '';
$search = isset($_POST['search']) ? $_POST['search'] : '';
$isSearch = false;
if(($item!="") && $search!=""){
echo "
"
;
echo "Error! Can not use both search and itemcode option. Search using either of these optoins. ";
echo "";
}else if($item){
$sql = "select * from caffaine where itemid = ".$item;
$result = $conn->query($sql);
$isSearch = true;
}else if($search){
$sql = "SELECT * FROM caffaine WHERE itemname LIKE '%" . $search . "%' OR itemdesc LIKE '%" . $search . "%' OR categ LIKE '%" . $search . "%'";
$result = $conn->query($sql);
$isSearch = true;
}
item
参数,where
语句注入先看item
,此参数通过表单选项框进行提交,但是也可自行拦截修改,并无大影响。
执行语句
这个地方对应着下面这个场景。
这里直接拿sqlmap
来进行测试是否存在漏洞,不跑数据。
python sqlmap.py -u "http://127.0.0.1/xvwa/vulnerabilities/sqli/home.php" --data="item=1" --batch
运行结果如下
已经发现是存在注入,不仅有题目中所说的报错注入
,就连联合查询注入
的方式也是可以。
这里由于代码已经配置完成,所以再使用pdo
工作量也比较大,如果使用过滤
或者转义
在很多情况下也有可能会有没有想到的关键词没有处理掉,那么这里就可以使用intval()
函数来处理item
参数。
$item = isset($_POST['item']) ? intval($_POST['item']) : '';
search
参数,like
语句注入接着来看第二个地方。
这里的search
也是没有做处理的,拼接后就形成了字符型注入。sqlmap
走一波。
python sqlmap.py -u "http://127.0.0.1/xvwa/vulnerabilities/sqli/home.php" --data="search=1" --dbms="mysql" --threads=20 --flush-session --batch -v 3
我去,走不出来,我发现我是真的不太会用sqlmap
。还是手工测试下吧。
确实是存在注入的,这里使用的是报错注入,盲注一般来说也是可以的。而且由于这里where
类型的子句,大概联合查询语句也可以,试试。
那接下就是修复了。这里是字符串,所以intval()
肯定不适合了,那么我这里就只能考虑考虑转义'
符号,或者做特殊关键字的检查了(为什么不用过滤呢,过滤是真的不好用,有时候过滤没写好,还有可能被双写或者大小写绕过),这里先采用转义吧,采用转义的话那就得注入是否存在宽字节注入
啦,不过我默认都是utf_8
的编码,这里使用addslashes()
之类的转义函数即可。
$search = isset($_POST['search']) ? addslashes($_POST['search']) : '';
代码和上一关一样,没区别,可能就是把报错信息给关掉了。。。
error_reporting(0);
之前的是
error_reporting(E_ALL);
讲道理,还是可以用联合查询注入的,这个我就不继续看了。
SQL
注入防御的方法:
在刚刚那个like
语句那里,看到有个哥们是这样的写法。
select * from test where school_name like concat('%',${name},'%')
先使用concat
进行拼接,然后再进行模糊查询,我自己试了下,还别说,想了会还真绕不过去。
如果还有其它的方法,欢迎评论交流~