php - 即使我们正在清理输入 mysql_real_escape_string 的 SQL 注入漏洞代码
问题描述
我们被攻击了;黑客从下面显示的代码中的 <login> 页面进入系统,但我们无法找出这段代码中的实际问题。
您能否指出此代码中的问题以及可能的修复方法?
<?php
//login.php page code
//...
$user = $_POST['user'];
$pass = $_POST['password'];
//...
mysql_connect("127.0.0.1", "root", "");
mysql_select_db("xxxx");
$user = mysql_real_escape_string($user);
$pass = mysql_real_escape_string($pass);
$pass = hash("sha1", $pass, true);
//...
$query = "select user, pass from users where user='$user' and pass='$pass'";
//...
?>
解决方案
这里的问题在于$pass= hash("sha1",$pass, true);
你需要这样写$pass= hash("sha1",$pass, false);
一个不错的选择是迁移到 PDO。
让我们看看为什么会这样:
您的代码正在做的是返回一个原始二进制哈希,这意味着在某个时间点哈希可能包含一个相等的字符=
,例如,在这种情况下导致 SQL 注入的哈希是"ocpe"
因为 hash ("ocpe",sha1 )有一个'='
字符,但我怎么能弄清楚呢?
您只需要运行一个简单的蛮力并测试它是否包含'='
内部散列原始位。
这是一个简单的代码,可以帮助您
<?php
$v = 'a';
while(1)
{
$hash = hash("sha1",$v, true);
if( substr_count( $hash, "'='" ) == 1 ) {
echo $v;
break;
}
$v++;
}
?>
现在你有一个字符串,它给出了一个内部相等的哈希'='
查询变为:
$query = "select user, pass from users where user='$user' and pass='hash("ocpe",sha1)'";
然后
$query = "select user, pass from users where user='$user' and pass='first_Part_of_hash'='Second_part_of_hash'";
在这种情况下,我假设ocpe
字符串具有这种格式的哈希first_Part_of_hash'='Second_part_of_hash
因为pass='first_Part_of_hash'
将导致0
and0='Second_part_of_hash'
由 SQL 引擎进行类型转换,但是string
如果我们将其类型转换为 aint
它将给出 0 ((int)'Second_part_of_hash'
结果是0
)
所以最后0=0
$query = "select user, pass from users where user='$user' and 0=0";
每次都会导致“真”,如您所见,它可以应用于所有哈希函数,如 MD5 和 sha256 等。
检查的好资源:
推荐阅读
- c# - How to get yearWeek in python like we get using DateTimeFormatInfo.InvariantInfo.Calendar.GetWeekOfYear() in C#?
- javascript - How to change background color of selected date in FullCalendar
- r - 如何将从其他excel表中提取的数据合并到r中的一个最终excel表中?
- python - twoSum 找出所有可能的独特情侣
- php - 数字从 n 减一到 0 PHP
- javascript - 自定义复选框不切换
- haskell - 在haskell中执行序列奇怪的“案例”
- c# - 从文本文件到二维数组
- javascript - 如何根据具有多个具有唯一名称的 ng-model 的名称获取价值?
- php - 如何显示按产品标签排序的 Woocommerce 产品?