1 PHP弱型別
PHP是弱型別語言,所以變數會因為使用場景的不同自動進行型別轉換。 PHP中用 == 以及 ! = 進行相等判斷時,會自動進行型別轉換,用 === 以及 ! == 進行判斷時不會自動轉換類型。
<span>1</span> <?<span>php </span><span>2</span><span>$a</span> = 3<span>; </span><span>3</span><span>$b</span> = '3vic'<span>; </span><span>4</span><span>var_dump</span>(<span>$a</span> == <span>$b</span>);<span>//</span><span>true</span><span>5</span><span>var_dump</span>(<span>$a</span> != <span>$b</span>);<span>//</span><span>false</span><span>6</span><span>var_dump</span>(<span>$a</span> === <span>$b</span>);<span>//</span><span>true</span><span>7</span><span>var_dump</span>(<span>$a</span> !== <span>$b</span>);<span>//</span><span>false</span><span>8</span> ?>
說明:在PHP中字串轉換成整數時,如果是數字開頭就會轉換成前面的數字('3vic' -> 3),如果不是數字開頭,那麼就會轉換成0( 'vic' -> 0)
2 WordPress程式碼
客戶端後台只驗證其中的一條Cookie,如下圖
<span>1</span> <?<span>php </span><span>2</span><span>//</span><span> WordPress 3.8.1</span><span>3</span><span>if</span> (<span>$hmac</span> != <span>$hash</span><span>) {} </span><span>4</span><span>//</span><span> WordPress 3.8.2</span><span>5</span><span>if</span> ( hash_hmac('md5', <span>$hmac</span>, <span>$key</span>) !== hash_hmac('md5', <span>$hash</span>, <span>$key</span><span>) ) {} </span><span>6</span> ?>
siteurl
) 其中
siteurl為WordPress的網址,此處網址為
http://www.test.ichunqiu,md5加密後為
c47f4a97d0321c1980bb76fc00d1e78f,其部分也可省。
型別使用者名稱過期時間登入成功伺服器端賦予客戶端的hash值<span>對應變數</span>
<span>$username</span>
cookies
<span></span> | 1433403595<span></span> | cf50f3b50eed94dd0fdc3d3ea2c7bbbcf50f3b50eed94dd0fdc3d3ea2c7bbb 程式碼 | wp-includes/pluggable.php 第543-549行<span></span>wordpress_c47f4a97d0321c1980bb76fc00d1e78f=admin|<span>1433403595</span>|cf50f3b50eed94dd0fdc3d3ea2c7bbb; path=/wp-admin; domain=www.test.ichunqiu; HttpOnly |
使用者名,$expiration 有效期,又因為其中使用者名稱是固定的,因此只有 | $expiration<span></span> ,所以我們可以從改變 | $expiration <span></span>的方法來改變 | $hash<span></span>。 |
$hmac == $hash 或真值,
$hash為以字元開頭的字串; 將客戶端的Cookie中$hmac 值改為0,然後在if ( $hmac != $hash ) {
var_dump($hmac);die();<span>發現印出來</span>
$hmac 的結果是
string '0'
<span>1</span> <?<span>php </span><span>2</span><span>$key</span> = wp_hash(<span>$username</span> . <span>$pass_frag</span> . '|' . <span>$expiration</span>, <span>$scheme</span><span>); </span><span>3</span><span>$hash</span> = hash_hmac('md5', <span>$username</span> . '|' . <span>$expiration</span>, <span>$key</span><span>); </span><span>4</span><span>if</span> ( <span>$hmac</span> != <span>$hash</span><span> ) { </span><span>5</span> do_action('auth_cookie_bad_hash', <span>$cookie_elements</span><span>); </span><span>6</span><span>return</span><span>false</span><span>; </span><span>7</span> }
0e156464513131 其中的
0e156464513131 會被識別為0乘以10的156464513131方
會被識別為0乘以10的156464513131方,全是數字時就會與$hmac<span></span>的值為'0' 時相等,所以我們可以將客戶端的Cookie設定為類似
wordpress_c47f4a97d0321c1980bb76fc00d1e78f4a97d0321c1980bb76fc00d1e78fadmin 33403595的位置)的方法來碰撞伺服器端,一旦$hash 的值為0e開頭後面全是數字即可驗證通過。假設碰撞成功,就修改瀏覽器的Cookie,直接存取後台位址,就可以成功登陸後台。
3 測試腳本
<span></span>
透過改變客戶端Cookie裡過期時間的值,不斷嘗試登入後台,找出可以進入後台的時間點,從而實現Cookie偽造登入後台。 <span>1</span> <?<span>php
</span><span>2</span><span>var_dump</span>('0' == '0e156464513131');<span>//</span><span>true</span>
說明
:
三億分之一
,碰撞到可以利用的幾分率。5 修復方案
<span></span>
〜== = 分別改為 ===
和
! == 或 將比較的兩個變數使用MD5再加密一次。
<span></span>
學習筆記:http://ichunqiu.com/course/167
以上就介紹了PHP弱型:WordPress Cookie偽造,包含了方面的內容,希望對PHP教學有興趣的朋友有幫助。