1. 程式人生 > >【技術分享】Windows程式的數字簽名校驗繞過漏洞 360bobao

【技術分享】Windows程式的數字簽名校驗繞過漏洞 360bobao

http://p4.qhimg.com/t0147da1822021d2ece.png

在今年的黑帽大會上,國外的一個安全研究員展示瞭如何通過Windows的數字簽名bypass對惡意程式程式碼的檢測。下載大會的該演講的ppt大概看了一下,報告分為兩部分,第一部分展示數字簽名的的校驗“漏洞”,第二部分展示該作者自己研究實現的一個pe程式載入器,用來配合第一部分的“漏洞“bypass防毒軟體對惡意程式的檢測。本文重點在於第一部分的這個數字簽名校驗”漏洞“,通過回顧分析數字簽名的校驗來闡述這個”漏洞“的原理。

 數字簽名與數字證書

講這個”漏洞“之前先講一下數字簽名的原理,理解一般的數字簽名驗證過程。下面是數字簽名的相關概念和驗證過程:

數字簽名:對一段資料摘要使用私鑰進行加密,公鑰進行解密校驗

數字證書:對數字簽名的解密公鑰和身份資訊使用CA的私鑰進行加密,系統信任的CA公鑰進行解密

http://p7.qhimg.com/t01fc41fe42a2a5e702.png

如上圖所示,數字簽名用來保護所有者的資料,所以從這些資料出發,所有者簽發資料的數字簽名過程是要先計算這些資料的摘要(也就是對這些資料做個hash運算,目前由於SHA-1開始不安全,正在逐漸換成SHA-2演算法),然後使用所有者的私鑰進行加密(目前主流還是RSA,也有一些ECC或其他演算法),加密後的資料帶上所有者的資訊按照一定的標準格式組織好其實就是所謂的數字簽名。而接收方(使用者)要驗證這個數字簽名,一般通過數字證書,因為其中包含兩個重要的資訊,一個就是用於解密數字簽名的公鑰(通過這個公鑰才能正確解密出資料所有者事先加密好的資料摘要值,用於驗證比對資料的一致性),另一個就是指明瞭這個公鑰的所有者的資訊(當然要和數字簽名所有者的資訊一致)。而數字證書其實是由第三方的可信機構頒發給數字簽名所有者的一份資料檔案,生成演算法和數字簽名類似,只不過它是把所有者的公鑰和身份這些固定資訊資料進行了加密返回給了所有者,此時所有者的身份正常是得到了可信機構的認證了。最後一個環節,數字簽名、數字證書通常都是附加到所有者的資料後面一起傳送給了使用者,但是如何解密數字證書來進行驗證呢?我的理解是,這個要依託於系統,比如windows,他們會維護一批可信機構的列表,在驗證證書的時候,就會先從這個列表裡校驗和獲取證書籤發機構的身份和公鑰,並返回到使用者系統進行儲存和使用。正是通過這樣一整套的相對完善的機制,最終比較靠譜的保證了接收資料的有效性。而本文所指的Windows程式的數字簽名,其實就是指所有者要保護的資料是一些Windows下的可執行程式這樣一種情況。

 可被利用的“漏洞”

從上面的簽名校驗流程看,由於整個過程涉及環節比較多,相應的每個環節都存在有被攻破的可能性,比如hash碰撞、根證書偽造等,但是本文不涉及此類問題。實際上,數字簽名仍然是保護資料有效的一種可靠的途徑,只要操作得當,演算法強度足夠,被攻破的可能性還是比較低。而本文所說的“漏洞”,也不是上面整個驗證過程的漏洞,下面就來看一看這個“漏洞”是什麼意思吧。

找一個帶有數字簽名的程式來實驗,就以微軟官方的庫檔案msvcr100.dll為例。右鍵點選檔案屬性,可以看到有一個數字簽名的標籤,依次點選可以檢視到下面的簽名有效狀態,表示這個程式的數字簽名驗證成功,“程式資料沒有被篡改”(這裡加引號說明理解需要謹慎,詳看下文)。

http://p1.qhimg.com/t01aaeab377c7212a89.png

然後修改這個檔案,比如在尾部隨便新增幾個位元組的資料,再次檢視數字簽名的狀態後如下圖所示,說明系統檢測到檔案被篡改,數字簽名驗證為無效。

http://p4.qhimg.com/t011fd1a0b96ff927c3.png

這就給我們造成一種感覺,數字簽名真的可以保證資料不被篡改,只要資料受到篡改,就會被系統的驗證機制檢測到並提示簽名無效。然而,這種感覺其實並不靠譜,因為我們實際上只是對簽名檔案添加了一些資料,並沒有修改到程式的原始資料區域的部分,理論上只要系統能夠找到程式的數字簽名並通過上述的驗證流程,那麼數字簽名就仍是有效的,受保護資料沒有遭到篡改。那麼,有沒有辦法讓這個添加了資料的檔案去正確識別數字簽名並顯示簽名有效呢,答案是肯定的,而這也正是本文所指的“漏洞”。

這裡直接給出這個“漏洞”的資訊:對於一個Windows的可執行程式,簽發數字簽名的時候需要計算的資料摘要並不會是程式檔案的全部資料,而是要排除一些特定區域的資料。而這些區域當然和PE檔案結構有關,具體地,不管是簽發時還是校驗時計算的hash都會排除一個checksum欄位、一個Security資料目錄欄位以及數字簽名證書部分的資料。至於原因,當然是為了合理地組織pe程式的數字簽名,符合pe檔案格式的標準了。下面是三個欄位的相關資訊:

struct IMAGE_NT_HEADERS
        …
        struct IMAGE_OPTIONAL_HEADER32
            …
            DWORD CheckSum //pe映像校驗和,dll常用
            …
struct DATA_DIR Security 
        DWORD VirtualAddress //指向數字簽名證書資料結構_WIN_CERTIFICATE
        DWORD Size //_WIN_CERTIFICATE結構大小
struct _WIN_CERTIFICATE
        DWORD dwLength //本結構資料的大小,一般和Security.Size相等
        WORD wRevision
        WORD wCertificateType
        BYTE bCertificate[ANYSIZE_ARRAY] //數字簽名證書資料

由於計算hash時排除以上3個相關的資料,故這三個欄位本身就是Windows系統留給使用者可以操作修改的區域。而實際上,要讓上述在尾部新增資料的檔案顯示數字簽名有效,即Windows系統對數字簽名可正確識別,只需要更新Security.Size這個欄位一致,且滿足新增的資料長度為8的整數倍即可:

http://p5.qhimg.com/t019b090e4cede5ca2b.png

由此可見,數字簽名狀態正常,並不意味著帶簽名的程式就是完整未被篡改過的,通過修改程式的欄位資料可以實現在帶簽名的程式後面新增任意的資料且簽名狀態驗證正常。上面的三個欄位如果同時修改,即checksum、Security.Size和dwLength都正常,除非很嚴格的去對數字簽名的資料部分進行檢查,否則比較難以檢測出帶簽名的程式檔案是否被惡意篡改添加了非法資料。而這一點,就構成所謂的“漏洞”,能夠成為很多惡意程式的良好的藏身之處,藉此bypass很多防火牆、反病毒等軟體的檢測。比如黑客可以將惡意程式碼嵌入帶有正常簽名的程式後面來繞過一些防護系統的檢測,從而為後續的一些攻擊行動起到一個很好的掩護作用。

 另一種Windows程式的簽名“漏洞”

經過以上的分析,所謂的簽名“漏洞”,其實是數字簽名檔案組織上的概念誤區,導致將簽名的正常狀態和簽名檔案的完整性混淆在一起。這裡介紹一種更為方便的Windows程式,能夠以更簡單的方式實現以上同樣的效果。

開啟Windows系統資料夾“C:/Windows/Installer”,在這個目錄下可以找到一些具有微軟數字簽名的msi/msp格式的檔案。我們知道msi是微軟格式的安裝包,點選執行後系統會自動呼叫Msiexec.exe來啟動程式,而這種程式相比於PE程式這個檔案格式來說,對數字簽名的識別好像更為簡單,也沒有PE程式結構的特殊限制。於是,隨便往帶有簽名的msi檔案尾部新增一些資料,而無需再修改檔案的其他資料,msi的數字簽名狀態仍然校驗正常。比如我係統找到的下面一個檔案:

http://p4.qhimg.com/t0147da1822021d2ece.png

可以看到,對於msi簽名檔案,隨意新增資料簽名狀態不變,說明即使被添加了非法資料,系統也能順利找到msi程式的數字簽名進行校驗,而由於msi程式的原始保護部分沒有受到篡改,所以數字簽名狀態驗證正常。

 總結

通過本文的分析,實際上這個程式簽名的“漏洞”並算不上通常意義上的漏洞,但是卻因為本身比較容易被概念混淆,使用可能沒有充分得當,導致可能存在一些比較嚴重的可利用環節。所以本文的結論就是:程式的數字簽名只能用於驗證程式的程式碼和資料是否被篡改,而無法用於驗證程式檔案本身是否被篡改。

本文由 安全客 原創釋出,如需轉載請註明來源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/2985.html