skip to Main Content

Long story short, I’ve got some passwords that were improperly salted and hashed in a version of PHP that allowed the crypt() function to fall back to the CRYPT_STD_DES algorithm if the salt was invalid.

However in PHP 5.3.2+:

5.3.2 Fixed Blowfish behaviour on invalid rounds to return “failure” string (“*0” or “*1”), instead of falling back to DES.

What makes this a problem is that the salt contained the “$” character as it was intended to be a blowfish salt (but was unknowingly malformed).

Thus I am unable to manually do something like the following:
crypt($pass, "$a");
since that is not a valid CRYPT_STD_DES salt either now. The salt must be in the range “./0-9A-Za-z”. It simply returns “*0” as the PHP devs intended.

How can I validate these malformed passwords in a more recent version of PHP (at least 7.1, ideally)?

3

Answers


  1. Chosen as BEST ANSWER

    As a workaround, I ended up actually using the old version of PHP for a single directory where I could make a file_get_contents() call and retrieve a hash with the old (bugged) algorithm, but still use the more modern version of PHP elsewhere.

    This is not a proper solution, however, as it technically does not answer the question: "How can I validate these malformed passwords in a more recent version of PHP?"

    As such, unless there appears to be no other possible solution, I will not be marking this as the accepted answer (but I believe this answer should be added for completeness sake).


  2. you are probably looking for

    password_hash ( string $password , int $algo [, array $options ] ) : string
    

    https://www.php.net/manual/en/function.password-hash.php

    Login or Signup to reply.
  3. Found an actual solution. By bruteforcing the salts, it turns out that PHP was interpreting the invalid "$2" STD_DES salt as "q2".

    Therefore, the answer to this question is that one can validate these hashes in a newer version of PHP by altering the salt used to compare the hashes so that it begins with "q2" instead of "$2". From there, it’s possible to just call substr_replace($str, '$', 0, 1); to replace the newly added "q" character back to a "$" character when performing the equality check.

    As an anecdote, apparently the information I had was incorrect and the hashes were generated in PHP 5.3.29 which contradicts what the docs say about falling back to STD_DES being patched in version 5.3.2.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search