Проблема здесь в $pass= hash("sha1",$pass, true);
Вы должны поставить это так $pass= hash("sha1",$pass, false);
Хороший вариант - перейти на PDO.
Посмотрим, почему это произошло:
То, что делает ваш код, возвращает необработанный двоичный хеш, который означает, что в определенный момент времени хеш может содержать равный символ =
,
для вашего примера хеш, который приведет к внедрению SQL в этом случае, равен "ocpe"
, потому что хэш ("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
, а 0='Second_part_of_hash'
будет типизирован механизмом SQL, но в случае string
, если мы приведем его к типу int
, он будет иметь значение 0 ((int)'Second_part_of_hash'
- это результат 0
)
так в итоге 0=0
$query = "select user, pass from users where user='$user' and 0=0";
В результате каждый раз будет получаться "true", и, как вы можете видеть, его можно применять ко всем хеш-функциям, таким как MD5, sha256 и т. Д.
Хорошие ресурсы для проверки:
Как я могу предотвратить внедрение SQL в PHP?
Может ли хеширование предотвратить внедрение SQL?