1. 程式人生 > >PHP中的MD5()函式漏洞

PHP中的MD5()函式漏洞

文章目錄

1. MD5函式漏洞

$_GET['a'] != $_GET['b'] 
&&
MD5($_GET['a']) == MD5($_GET['b'])

要讓上面的等式成立,a和b的值不能相等,但是md5後的值相等。因為是==比較,只判斷值是否相等,不判斷型別是否相同。如果型別不同先轉換為相同型別再進行比較而PHP在處理雜湊字串時後,會把0E開頭的雜湊值解釋為0。所以如果兩個值通過md5後值都已0E開頭,就會相等。

md5(str)
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a
sha1(str)
sha1後以0E開頭
sha1(‘aaroZmOk’)
sha1(‘aaK1STfY’)
sha1(‘aaO8zKZF’)
sha1(‘aa3OFF9m’)


最後只要構造a=QNKCDZO&&b=240610708就可以繞過。

2.PHP特性

$_POST['a1']!==$_POST['a2'] 
&& 
md5($_POST['a1'])===md5($_POST['a2'])

成立的條件是a1和a2值不相等,但是md5後的值相等。因為這裡是===不僅比較值相等還會比較值得型別是否相同0E在這裡就不可用了。
php中md5和sha1函式都無法處理陣列,會返回NULL
所以構造a1[]=1&&a2[]=2就可以繞過。

3.MD5碰撞

(string)$_POST['a1'
]!==(string)$_POST['a2'] && md5($_POST['a1'])===md5($_POST['a2']) }

這個和第二個的區別就是傳入的最後轉為字串比較,所以陣列就不行了。只能構造兩個MD5值相同的不同字串
下面的是兩組經過url編碼後的值

param1=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
param2=
M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
Param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
Param2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2