0

I already know about PHP strings == comparison vulnerabilities

  1. http://marcosvalle.github.io/ctf/php/2016/05/12/php-comparison-vlun.html
  2. https://www.owasp.org/images/6/6b/PHPMagicTricks-TypeJuggling.pdf
  3. https://hydrasky.com/network-security/php-string-comparison-vulnerabilities/

But I can not find the way to bypass == comparison for sha256 string. Below is the example code:

$username = $mysqli->real_escape_string($_POST['username']);
$password = $mysqli->real_escape_string(hash("sha256", $_POST['password']));

$UserDB = $mysqli->query("SELECT * FROM Database")->fetch_assoc()['value'];
$PwDB = $mysqli->query("SELECT * FROM Database")->fetch_assoc()['value'];

if($UserDB == $username){
    if($PwDB == $password){
        $_SESSION['admin'] = "Admin_".$username."_Password_".$password;
        header("Location: admin.php");
        exit;
    } else {
        $content .= alert("danger", "Password is wrong.");
    }
} else {
    $content .= alert("danger", "Username is wrong.");
}

Do you have any ideas to bypass sha256 password?

3
  • 4
    Suggestion for you: You should return a more generic message "Credentials are wrong" type message for both password and username checks. You'll obfuscate which of the two is the one that's wrong, and can help deter brute force attacks.
    – psosuna
    Commented Oct 11, 2017 at 21:22
  • 1
    The code you've shown us is complete nonsense. If you show us genuine code which functions as a logon validator there is a chance we might be able to answer your question.
    – symcbean
    Commented Oct 11, 2017 at 22:26
  • @symcbean. It's simple like this: if($_POST['username'] AND $_POST['password']){ // Check username/password with above code. } else if($_POST['username']){ $content .= alert("Please fill all fields."); }
    – Nam Vu
    Commented Oct 12, 2017 at 2:20

1 Answer 1

3

This is exploitable in some cases. The root issue here is the way PHP type juggles when comparing values with the double equal operator. If the values compared begin with "0e" or "00e", etc, they will be juggled to a float and compared as two zeros. The following snippet illustrates this:

php -r 'if ("0e123" == "00000e228") { print "You win\n"; }'

As the user supplied password is hashed without a salt you can control the $password value of the comparison, however the $PwDB value is presumably from the database itself and an unknown value. In order for the comparison to equal true you would need two things:

  1. submit a known value that results in a suitable hash value when hashed with sha256. Luckily the internet has already solved this we can take 34250003024812 ( from https://github.com/spaze/hashes/blob/master/sha256.md)

  2. A valid username for a user who's hashed password in the database starts with the magic 0e type string.

So in short, use a wordlist or enumerated usernames and attempt to login with the password 34250003024812 for each of them. If you're lucky it will match one or more users.

1
  • Nice Trick! Only PHP... Commented Nov 9, 2020 at 10:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .