Thursday, July 25, 2013

Password Hashing Fail

Here's a bit of password hashing fail.

I'm not sure if it will win the Password Hashing Competition, but it certainly is novel. I really like how, after it goes through all of that sha1/md5/rot13 "encryption", it saves the plaintext to the database. Oh, and if it weren't for a misplaced '}', it would accept any password in the database, not just the one for your account. It's also vulnerable to SQL injection (pointed out by an Anonymous commenter).

Hashing a password:
 public function encryptData($string)
 {  
   $stringORG = $string;  
   $string = str_rot13($string);  
   $string = md5($string);  
   $string = substr($string, 5, 15);  
   $string = sha1(SALT . $string);  
   $string = md5($string);  
   $string = sha1(SALT . $string);  
   $string = str_rot13($string);  
   $string = substr($string, 5, 15);  
   $string = md5(SALT . $string);  
   mysql_query("INSERT INTO `encryptions` (`encvalue`, `realvalue`) VALUES ('".$string."', '".$stringORG."');");  
   return $string;  
   }  
Testing a password:
public function tryEncryption($tried)
{  
  $query = mysql_query('SELECT * FROM encryptions');  
  while($row = mysql_fetch_assoc($query))  
  {  
    $encVal = $row['encvalue'];  
    $actVal = $row['realvalue'];  
  }  
    $actTried = $tried;  
    $tried = str_rot13($tried);  
    $tried = md5($tried);  
    $tried = substr($tried, 5, 15);  
    $tried = sha1(SALT . $tried);  
    $tried = md5($tried);  
    $tried = sha1(SALT . $tried);  
    $tried = str_rot13($tried);  
    $tried = substr($tried, 5, 15);  
    $tried = md5(SALT . $tried);  
    if($encVal==$tried)  
    {  
      if($actVal==$actTried)  
      {  
        return true;  
      }  
    }  
}  

Lessons Learned:
  • When you encrypt something, make sure the plaintext is safely destroyed.
  • Hash passwords properly.
  • Write unit tests for your code.

1 comment:

  1. $string = "'); drop table encryptions; -- ";


    … why even … why … just … why.

    ReplyDelete