PHP Hash is flawed, affecting a large number of key services such as website login authentication and password forgetting.
A recent PHP vulnerability called "Magic Hash" allows attackers to illegally obtain user account information. The cause of the vulnerability is that PHP processes the hash string in a specific way. Attackers can use it to try and obtain the password, attackers can bypass the login authentication system and other functions running on the PHP hash comparison.
Vulnerability description
PHP uses "! = "Or" = "to compare the hash value. It interprets each hash value starting with" 0E "as 0. Therefore, if two different passwords are hashed, the hash values start with "0E", so PHP will think they are the same, all of which are 0.
Attackers can exploit this vulnerability to input a string that is hashed and starts with "0E", which is interpreted as 0 by PHP, if the database contains a password whose hash value starts with "0E", the user can log in as the user, even though there is no real password.
Attack case:
On July 6, April 8, wordpress released an important update in which a series of security vulnerabilities were fixed. Among them, the most prominent is the cookie Forgery Vulnerability (CVE-2014-0166 ).
Let's look at the patch code:
$key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme); $hash = hash_hmac('md5', $username . '|' . $expiration, $key); - if ( $hmac != $hash ) { + if ( hash_hmac( 'md5', $hmac, $key ) !== hash_hmac( 'md5', $hash, $key ) ) {
I tried to analyze the vulnerability the day before. I had little knowledge about the vulnerability and didn't know the php features. I couldn't think of it for several hours. I cannot figure out why I can fix the vulnerability by adding hash_hmac once. At that time, I thought it was a problem related to the encryption algorithm, so I gave up.
Today, I suddenly saw an article. epiphany is a problem with comparision operator. In fact, I also noticed that "! = "And"! = "These two symbols are different, but I thought about the possibility that I didn't expect to use them. I put the focus on hash_hmac. Maybe this is wordpress's blind eye? Haha.
We put all our focus on "! = "And"! =:
We know that php has two equal operators: strict and non-strict. Php manual is defined as follows:
"=" And "! = "Strict comparison operator, which is equal only when the types are the same. "=" And "! = "Non-strict comparison operator, which will be compared after type conversion.
Let's look at the example in php manual:
phpvar_dump(0 == "a"); // 0 == 0 -> truevar_dump("1" == "01"); // 1 == 1 -> truevar_dump("10" == "1e1"); // 10 == 10 -> truevar_dump(100 == "1e2"); // 100 == 100 -> true?>
The string is automatically converted to a number before being compared with the number, so 0 = ".
The other two strings are compared. If both strings are in the numeric format, they are converted to numbers for comparison. Therefore, "1" = "01 ".
Now you have to ask, what is the relationship between the hash strings in the cookie and the real hash strings in the wordpress code?
In the preceding example, "10" = "1e1", php intelligently converts a string in the form of scientific counting to a corresponding number (1e1 = 1*10 ^ 1 = 1 ). The two different characters are actually equal. Do you have any inspiration here?
Well, it's obvious that you will suddenly realize:
Var_dump ("0e123456789012345678901234567890" === "0") // false
Var_dump ("0e123456789012345678901234567890" = "0") // true
When hash appears in the form of "0 exxxxxxxxxxxxxxxxxxxxxxxxx", it is equal to "0.
Let's go back to the wordpress verification code. Based on username ($ username), password ($ pass_frag), cookie validity period ($ expiration), key ($ key) in the wp-config.php) calculate the corresponding $ hash (the algorithm is simple, not detailed), and then compare the $ hmac value obtained in the cookie ($ hmac! = $ Hash ?), To verify the cookie validity.
In addition, the cookie format is as follows: wordpress_hashofurl = username | expiration | hmac
The variables we can control include $ username and $ expiration. $ username must be fixed. Therefore, we can change the $ hash value by controlling the $ expiration in the cookie, and then set $ hmac in the cookie to 0.
As long as the $ expiration is constantly changed until $ hash = "0" is satisfied, a valid cookie is successfully forged.
Of course, it can be inferred through rough mathematical probability calculation. The probability of hash matching the condition is very low:
P = Sum (10 ^ n, n = 0, 30)/16 ^ 32 = 3.26526*10 ^-9
When there are nearly three requests, there is a probability that they can be met ~
Sometimes, when I look at my character, my character will soon be met. If my character is bad, it will be like me:
How is it, young man? Write a multi-thread script and run it?
Impact Scope
It affects a large number of web sites, including logon authentication, "forgot password", binary verification, and cookie. All of them use the hash function value in PHP for comparison, so there are risks.
Solution
Analyze and use the hash comparison function in the PHP web site, replace "= ","! = "Change to" = "and "! = ".