1. 程式人生 > >DLL劫持漏洞原理

DLL劫持漏洞原理

DLL劫持

最近一段時間實在是忙,亂七八糟的,都沒空寫部落格,但是學習還得繼續,最近看了下DLL劫持,嚴格上說這不能算是漏洞,但是第一次接觸感覺有點意思,寫出來記錄一下吧,老年人了記性不好,小白文章歡迎指正。

0x01 劫持原理

1.什麼是DLL
DLL(Dynamic Link Library)檔案為動態連結庫檔案,又稱“應用程式拓展”,是軟體檔案型別。在Windows中,許多應用程式並不是一個完整的可執行檔案,它們被分割成一些相對獨立的動態連結庫,即DLL檔案,放置於系統中。當我們執行某一個程式時,相應的DLL檔案就會被呼叫。一個應用程式可使用多個DLL檔案,一個DLL檔案也可能被不同的應用程式使用,這樣的DLL檔案被稱為共享DLL檔案。
2.什麼是DLL劫持


每個DLL都有一個入口函式(DLLMain),系統在特定環境下會呼叫DLLMain。在發生DLL裝載、解除安裝、建立新執行緒、執行緒終止時,就會呼叫dll的入口函式。
另外,每個DLL檔案中都包含有一個匯出函式表也叫輸出表(存在於PE的.edata節中)。使用一些PE檔案檢視工具如LoadPE,就可以檢視匯出函式的符號名即函式名稱和函式在匯出函式表中的標識號。

應用程式匯入函式與DLL檔案中的匯出函式進行連結有兩種方式:隱式連結(load-time dynamic linking)也叫靜態呼叫和顯式連結(run-time dynamic linking)也叫動態呼叫。隱式連結方式一般用於開發和除錯,而顯式連結方式就是我們常見的使用LoadLibary或者LoadLibraryEx函式(注:涉及到模組載入的函式有很多)來載入DLL去呼叫相應的匯出函式。呼叫LoadLibrary或者LoadLibraryEx函式時可以使用DLL的相對路徑也可以使用絕對路徑,但是很多情況下,開發人員都是使用了相對路徑來進行DLL的載入。那麼,在這種情況下,Windows系統會按照特定的順序去搜索一些目錄,來確定DLL的完整路徑。關於動態連結庫的搜尋順序的更多詳細資料請參閱MSDN。根據MSDN文件的約定,在使用了DLL的相對路徑

呼叫LoadLibrary函式時,系統會依次從下面幾個位置去查詢所需要呼叫的DLL檔案。

1.程式所在目錄
2.系統目錄即 SYSTEM32 目錄。
3.16位系統目錄即 SYSTEM 目錄。
4.Windows目錄。
5.載入 DLL 時所在的當前目錄。
6.PATH環境變數中列出的目錄。

微軟為了防止DLL劫持漏洞的產生,在XP SP2之後,添加了一個SafeDllSearchMode的登錄檔屬性。登錄檔路徑如下:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\SafeDllSearchMode

當SafeDllSearchMode的值設定為1時,DLL查詢的目錄順序就發生了變化:

1.程式所在目錄
2.系統目錄即 SYSTEM32 目錄。
3.16位系統目錄即 SYSTEM 目錄。
4.Windows目錄。
5.載入 DLL 時所在的當前目錄。
6.PATH環境變數中列出的目錄。

大佬部落格中提到XP以後釋出的版本中預設都是未開啟DLL安全搜尋的(我沒裝XP虛機,只有win7和win10,找不到這個登錄檔,如果有人知道原因麻煩跟我說一聲),這就讓DLL劫持有了可乘之機,但為了進一步防止被劫持,微軟又將常被利用的DLL放在system32目錄下,並禁止這些登錄檔被非system32下的呼叫,路徑:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

win10下的KnowDLLs:

win7下的KnowDLLs:

這就意味著,利用上述存在於KnowDLLs登錄檔項下的dll去進行劫持,是不會被系統載入的。
但是在載入DLL過程中,系統都是先在程式目錄載入DLL,如果沒有找到就按照規定的順序去搜索,但如果DLL的路徑沒有在system32中,攻擊者就有可能偽造一個dll被程式載入(注意:該DLL需要與系統載入的DLL名稱相同,匯出函式表相同,並將DLL中的函式轉向到原有的DLL,這時程式的載入流程為:程式啟動→系統載入偽造DLL→真實DLL→原流程)

以上漏洞原理皆為參考Freebuf上的一篇文章,侵刪
原文傳送門