The problem here is in $pass= hash("sha1",$pass, true);
You need to put it like this $pass= hash("sha1",$pass, false);
A good option is to move to PDO.
Let's see why this happen:
What your code is doing is returning a raw binary hash that means at a point in time the hash may contain an equal character =
,
for your example the hash that going to result in SQL injection in this case is "ocpe"
because hash ("ocpe",sha1) have a '='
character,
but how can I figure that out?
You only need to run a simple brute force and test if it contains a '='
inside the hash raw bit.
This is a simple code which can help you with that
<?php
$v = 'a';
while(1)
{
$hash = hash("sha1",$v, true);
if( substr_count( $hash, "'='" ) == 1 ) {
echo $v;
break;
}
$v++;
}
?>
Now you you have a string that gives a hash that has an equal inside of it '='
The query becomes:
$query = "select user, pass from users where user='$user' and pass='hash("ocpe",sha1)'";
then
$query = "select user, pass from users where user='$user' and pass='first_Part_of_hash'='Second_part_of_hash'";
In this case I assume that ocpe
string has a hash of this format first_Part_of_hash'='Second_part_of_hash
Because pass='first_Part_of_hash'
going to result in 0
and 0='Second_part_of_hash'
is typecasted by the SQL engine, but in case of string
if we type cast it to a int
it's going to give as 0 ((int)'Second_part_of_hash'
is result in 0
)
so in the end 0=0
$query = "select user, pass from users where user='$user' and 0=0";
Which going to result in "true" every time and as you can see it can be applied to all hash functions like MD5 and sha256 etc.
Good resources to check:
How can I prevent SQL injection in PHP?
Could hashing prevent SQL injection?