弱型別語言 Hash比較存在缺陷

2021-08-07 13:03:21 字數 3127 閱讀 2686

**:來自freebuf黑客與極客(freebuf.com)-->

如題這不是僅在php出現的問題,是弱型別語言轉換的問題。

最近乙個被稱為「magic hash」的php漏洞可以使得攻擊者非法獲取使用者的賬號資訊。漏洞原因是php以一種特定的方式處理被雜湊的字串,攻擊者可以利用其從中嘗試並可能獲取密碼,繞過登入認證系統和其它執行在php雜湊比較之上的函式。

漏洞描述

php在處理雜湊字串時,會利用」!=」或」==」來對雜湊值進行比較,它把每乙個以」0e」開頭的雜湊值都解釋為0,所以如果兩個不同的密碼經過雜湊以後,其雜湊值都是以」0e」開頭的,那麼php將會認為他們相同,都是0。

攻擊者可以利用這一漏洞,通過輸入乙個經過雜湊後以」0e」開頭的字串,即會被php解釋為0,如果資料庫中存在這種雜湊值以」0e」開頭的密碼的話,他就可以以這個使用者的身份登入進去,儘管並沒有真正的密碼。

攻擊案例: 

4月8日,wordpress發布了乙個重要更新,在該次更新中,修復了一系列安全漏洞。其中最顯眼的就是cookie偽造漏洞(cve -2014- 0166)。

我們來看修補的**:

$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 ))

{

前日嘗試分析該漏洞,奈何知識匱乏,對php特性不夠了解,一連用了幾個小時都想不出。想不通為何加了一次hash_hmac就可以修復漏洞。當時的我以為是涉及到了加密演算法上的一些問題,就放棄了。

今日突然看到一篇文章,頓悟是comparision operator的問題。其實之前也有注意到 「!=」 與 「!==」 這兩個符號的不同,不過大致想了一下沒想到利用的可能,就把重點放在了hash_hmac上。也許這是wordpress的障眼法?呵呵,說笑。

我們把全部的關注點放到 「!=」 與 「!==」 上來:

我們知道php比較相等性的運算子有兩種,一種是strict,一種是non-strict。

"==="和"!=="即strict比較符,只有在型別相同時才相等。"=="和"!="即non-strict比較符,會在型別轉換後進行比較。

再看php manual中給出的例子:

<?

phpvar_dump(0

=="a"

);// 0 == 0 -> true

var_dump

("1"

=="01"

);// 1 == 1 -> true

var_dump

("10"

=="1e1"

);// 10 == 10 -> true

var_dump

(100

=="1e2"

);// 100 == 100 -> true

?>

字串在與數字比較前會自動轉換為數字,所以0=="a"了。

另外兩個字串比較,如果兩個都是數字形式,則同時轉換為數字進行比較,所以"1"=="01"。

這時你要問了,wordpress的**中是將cookie中的hash和真實hash這兩個hash的字串進行比較,和這個有什麼關係呢?

我們注意上面"10"=="1e1"這個例子,php智慧型的將科學計數形式的字串轉換為對應數字(1e1 = 1*10^1 = 1)。兩個不同的字元居然相等了,不知到這裡你是否得到了啟示?

好吧,來乙個明顯的,你一定會恍然大悟:

var_dump

("0e123456789012345678901234567890"

==="0"

)//false

var_dump

("0e123456789012345678901234567890"

=="0"

)//true

當hash以"0e******************************x"之類的形式出現時,與"0"相等。

讓我們回到wordpress的驗證**上來。先生成根據使用者名稱($username)、密碼($pass_frag)、cookie有效期($expiration)、wp-config.php中的key($key)四個資訊計算出對應的$hash (演算法很簡單,不細說), 然後用cookie中取得的$hmac值與之進行比較($hmac != $hash ?),從而驗證cookie有效性。

另外提下,cookie的格式是這樣的:wordpress_hashofurl=username|expiration|hmac

我們能控制的變數有$username和$expiration,其中$username需要固定。於是我們可以通過控制cookie中的$expiration去改變$hash的值,然後將cookie中的$hmac設定為0

只要不斷改變$expiration,直到滿足$hash=="0"的$hash出現,就成功偽造了有效的cookie。

當然,通過粗略的數學概率運算即可推知,滿足條件的hash出現概率非常之低:

p = sum(10^n,n=0,30)/16^32 = 3.26526*10^-9
接近三億個請求才有乙個可碰上的概率,嗚嗚~

有時看人品,人品好的很快就碰到了,人品不好的就如我,幾乎五億了。

怎麼樣,少年,寫乙個多執行緒指令碼跑起?

影響範圍

影響大量web站點,其中的登入認證,「忘記密碼」,二進位制校驗,cookie等方面,由於都會用到php中的雜湊函式值比較,因此都存在隱患。

解決方案

分析使用php的web站點中雜湊比較函式,將其中的」==」,」!=」分別更改為」===」和」!===」。

php 弱型別比較

php中 是弱等於,不會比較變數型別 是強等於,會先比較變數型別。0e 開頭跟數字的字串 例如 0e123 會當作科學計數法去比較,所以和0相等 0x 開頭跟數字的字串 例如 0x1e240 會被當作16進製制數去比較 布林值true和任意字串都弱相等。當比較的一方是字串時,會先把其轉換為數字,不能...

PHP弱型別比較

ctf中弱型別比較 php弱型別比較 php中其中兩種比較符號 先將字串型別轉化成相同,再比較 先判斷兩種字串的型別是否相等,再比較 字串和數字比較使用 時,字串會先轉換為數字型別再比較 var dump a 0 true,此時a字串型別轉化成數字,因為a字串開頭中沒有找到數字,所以轉換為0 var...

php弱型別比較

題目 1.開啟頁面,進行 審計,發現同時滿足 a 0 和 a 時,顯示flag1。2.php中的弱型別比較會使 abc 0為真,所以輸入a abc時,可得到flag1,如圖所示。abc可換成任意字元 3.is numeric 函式會判斷如果是數字和數字字串則返回 true,否則返回 false,且p...