Jump to content

在本文中,我們將探討如何濫用某些特殊的PE節(PE Sections),在無需直接訪問進程的情況下將任意shellcode植入遠程進程的內存中。

跨進程橫向移動是惡意軟件中非常常見的一種技術,以便在系統間進行傳播。近年來,微軟已經通過“Microsoft-Windows-Threat-Intelligence”ETW提供程序增加了安全遙測功能,以對抗這種威脅。

當這種新增的遙測功能與現有的方法(如ObRegisterCallbacks)結合在一起後,攻擊者在進行橫向移動過程中,相關的惡意操作很難逃過內核可見遙測的法眼。在本文中,我們將探討如何濫用某些特殊的PE節,在無需直接訪問進程的情況下將任意shellcode植入遠程進程的內存中。

背景知識現有的橫向移動方法,通常都涉及危險的API調用,如OpenProcess,以獲得進程句柄,並伴有與內存相關的操作,如VirtualAlloc、VirtualProtect或WriteProcessMemory。近年來,針對這些操作的檢測有所增加。

例如,在舊版本的Windows上,內核驅動程序可見的唯一跨進程API調用,就是ObRegisterCallbacks,它常用於創建進程和線程句柄。

微軟威脅情報ETW提供程序引入的可見性已經擴展到涵蓋以下操作:

1、讀/寫虛擬內存調用(EtwTiLogReadWriteVm);

2、可執行內存的分配(EtwTiLogAllocExecVm);

3、將內存保護屬性改為可執行文件(EtwTiLogProtectExecVm);

4、映射可執行節(EtwTiLogMapExecView)。

進入另一個進程上下文的其他方法通常與其他檢測向量一起出現。例如,橫向移動的另一種方法可能涉及基於磁盤的攻擊,如代理Dll注入。這類攻擊的問題在於,它們通常需要將惡意代碼寫入磁盤,這對於基於內核的防禦解決方案是可見的。

由於已知的跨進程移動方法需要用到這些可見的操作,因此,要想打敗防御者可用的遙測技術,就必須超越現有的方法。

發現過程最近,我研究了在不影響PE格式二進製文件可用性的條件下,可以將這種二進製文件破壞到哪種程度。例如,您是否可以將已知的惡意工具(如Mimikatz)破壞到這樣一種程度:既不會影響其可操作性,同時,還能讓反病毒軟件中內置的映像解析器無法正常對其進行解析?

與Linux中的ELF可執行文件類似,Windows PE映像也是由“節”組成的。例如,代碼通常存儲在名為.text的節中,可變數據可以在.data節中找到,而只讀數據通常存放到.rdata節中。但是,操作系統是如何知道哪些節包含代碼,或是可寫的呢?每個節都具有相應的“characteristics(特徵)”,用於記錄這段內存的相關信息。

對於PE節來說,單單記錄在冊的特徵就超過35個。其中,最常見的特徵包括IMAGE_SCN_MEM_EXECUTE、IMAGE_SCN_MEM_READ和IMAGE_SCN_MEM_WRITE,它們分別用於定義一個節是否為可執行、可讀和/或可寫的。然而,這些只是PE節的各種特徵中的一小部分而已。

當試圖破壞PE節頭時,一個特定的標誌引起了我的注意:

1.png

“IMAGE_SCN_MEM_SHARED”特徵

根據Microsoft的文檔,IMAGE_SCN_MEM_SHARED標誌表示“該節可以在內存中共享”。但是,這到底是什麼意思呢?在網絡中沒有找到太多關於該標誌的說明文檔,但事實證明,如果啟用該標誌,該節的內存將在加載了該映像的所有進程之間共享。例如,如果進程A和B加載一個PE映像,其中包含一個“共享”(並且可寫)的節,那麼進程A中該節的內存中的任何變化都將反映在進程B中。

與我們將在本文中討論的理論密切相關的一篇文獻是“DLL shared sections: a ghost of the past”。在這篇文章中,Coldwind探討了由具有IMAGE_SCN_MEM_SHARED特徵的PE節的二進製文件所帶來的潛在風險。

Coldwind解釋說,這些PE映像帶來的風險“是一個古老而眾所周知的安全問題”,並引用了微軟在2004年發表的一篇文章,題為“ Why shared sections are a security hole”。該文章只考察了“讀/寫共享節”和“只讀共享節”所構成的威脅,而沒有討論第三種可能,即“讀/寫/執行共享節”。

利用共享節儘管研究人員和微軟本身知道共享節的一般風險已經有很長一段時間了,但還沒有文獻對可讀、可寫和可執行(RWX-S)的共享節的潛在濫用進行過深入介紹。

RWX-S二進製文件具有極大的進攻潛力,這是因為:如果您可以使遠程進程加載指定的RWX-S二進製文件,那麼您就在遠程進程中獲得了一個可執行的內存頁,即使您對這個內存頁進行修改,基於內核的防禦解決方案也是看不到的。為了注入代碼,攻擊者可以將RWX-S二進製文件加載到自己的進程中,並在內存中使用他們想要的任何惡意代碼編輯該節,然後將RWX-S二進製文件加載到遠程進程中,這時,他們自己進程中的修改也會反映在受害者進程中。

加載RWX-S二進製文件本身的操作對防禦性解決方案仍然是可見的,但正如我們將在後面的部分中討論的那樣,對於在惡意上下文之外使用的合法RWX-S二進製文件,實際上有很多選擇的餘地。

使用這種技術時,有幾點需要注意:

1、攻擊者必須能夠將RWX-S二進製文件加載到遠程進程中。不過,該二進製文件不需要包含任何惡意代碼,但是,必須有一個PE節是RWX-S的。

2、如果RWX-S二進製文件是用於x86架構的,則x64進程內的LoadLibrary調用將失敗。不過,我們仍然可以通過打開文件、創建具有屬性SEC_IMAGE的節並映射節的視圖,在x64進程中手動映射x86二進製文件。

3、RWX-S二進製文件不在會話之間共享。 RWX-S二進製文件由同一會話中的非特權進程和特權進程共享。

4、對共享節的修改不會寫入磁盤。例如,由ReadFile返回的緩衝區,以及映射具有屬性SEC_COMMIT的映像時所返回的緩衝區,都不包含對共享節的任何修改。只有當二進製文件映射為SEC_IMAGE時,才會存在這些更改。這也意味著對共享節的任何修改都不會破壞磁盤上的驗證碼簽名。

5、除非所使用的RWX-S二進製文件的入口點位於共享可執行節中,否則攻擊者必須能夠在遠程進程中的任意地址執行代碼。這不需要直接的進程訪問。例如,SetWindowsHookEx可用於在沒有直接進程訪問權限的情況下執行模塊中的任意指針。

接下來,我們將為讀者介紹該理論的實際實現,以及RWX-S宿主二進製文件的在野普及情況。

通過修改入口點以獲得執行權限在某些情況下,可以繞過攻擊者必須能夠在遠程進程中執行任意指針的限制。

如果RWX-S宿主二進製文件的入口點位於RWX-S節內,則攻擊者不需要特殊的執行方法。

相反,在將RWX-S宿主二進製文件加載到遠程進程之前,攻擊者可以修改位於映像入口點的內存,使其指向指定的shellcode。當受害進程加載RWX-S宿主二進製文件並試圖執行入口點時,攻擊者的shellcode將被執行。

在野外尋找RWX-S二進製文件這項研究試圖解決的問題之一是“RWX-S的威脅有多廣泛?”。為了確定這項技術的流行程度,我使用了VirusTotal的Retrohunt功能,該功能允許用戶“使用……YARA規則掃描過去12個月中發送給VirusTotal的所有文件”。

為了在野外檢測無簽名的RWX-S二進製文件,我們創建了一個自定義YARA規則,專門用於檢查PE映像中的RWX-S節:

import'pe'

ruleRWX_S_Search

{

meta:

description='DetectsRWX-Sbinaries.'

author='BillDemirkapi'

condition:

foranyiin(0.pe.number_of_sections-1):(

(pe.sections[i].characteristicspe.SECTION_MEM_READ)and

(pe.sections[i].characteristicspe.SECTION_MEM_EXECUTE)and

(pe.sections[i].characteristicspe.SECTION_MEM_WRITE)and

(pe.sections[i].characteristicspe.SECTION_MEM_SHARED))

}這個規則所做的事情,就是枚舉二進製文件的PE節,並檢查它是否可讀、可寫、可執行和共享的。

當通過Retrohunt功能搜索這個規則時,會發現超過10,000個無簽名的二進製文件(當結果超過10,000個時,Retrohunt功能就會停止搜索)。

當再次搜索該規則時,可以稍微修改一下,以檢查PE映像對應的機器類型是否為MACHINE_AMD64機,這時,只找到了99個x64架構的RWX-S二進製文件。

這表明,在過去的12個月中,用於x64機器的RWX-S二進製文件相對不常見,同時還表明防禦性解決方案可能能夠過濾RWX-S二進製文件,而不會在受保護的機器上產生明顯的噪聲。

為了檢測已簽名的RWX-S二進製文件,只需對上面的YARA規則稍加修改,以包含對authenticode簽名的檢查。

import'pe'

ruleRWX_S_Signed_Search

{

meta:

description='DetectsRWX-Ssignedbinaries.Thisonlyverifiesthattheimagecontainsasignature,notthatitisvalid.'

author='BillDemirkapi'

condition:

foranyiin(0.pe.number_of_sections-1):(

(pe.sections[i].characteristicspe.SECTION_MEM_READ)and

(pe.sections[i].characteristicspe.SECTION_MEM_EXECUTE)and

(pe.sections[i].characteristicspe.SECTION_MEM_WRITE)and

(pe.sections[i].characteristicspe.SECTION_MEM_SHARED))

andpe.number_of_signatures0

}不幸的是,對於YARA規則,沒有一個簡單的方法來確定一個PE映像是否包含基於有效證書的authenticode簽名——所謂有效證書,指的是還未過期,或在證書有效期內用有效的時間戳簽名的。這意味著上面的YARA規則會包含一些具有無效簽名的二進製文件的誤報。由於存在誤報,上面的規則無法直接給出一個具有有效的authenticode簽名的RWX-S二進製文件清單。為了提取已簽名的二進製文件,我們編寫了一個簡單的Python腳本,下載低於檢測閾值的每個樣本並驗證每個二進製文件的簽名。

經過這一處理,發現了大約15個具有有效簽名的獨特二進製文件。正如未簽名的二進製文件檢查結果所示,在過去12個月裡,具有簽名的RWX-S二進製文件在野外並不是很多。此外,15個獨特的已簽名二進製文件中只有5個是用於x64機器。值得注意的是,雖然這個數字看起來很低,但使用已簽名的二進製文件只是為了方便,在大多數情況下肯定不是必需的。

濫用未簽名的RWX-S二進製文件修改未簽名的二進製文件鑑於諸如用戶模式代碼完整性之類的緩解措施尚未得到廣泛採用,因此,修改現有的未簽名二進製文件仍然是一種可行的方法。

若要通過未簽名的二進製文件來濫用RWX-S節,攻擊者可以:

1、查找要修改的、合法但未簽名的宿主DLL。

2、將未簽名的DLL讀入內存,並修改節的特徵,使其具有可讀、可寫、可執行和共享的特性。

3、在使用之前,將這個新修補的RWX-S宿主二進製文件寫入磁盤的某個位置。

以下是維護操作安全的幾點建議:

1、建議攻擊者不要修補磁盤上現有的二進製文件。例如,如果攻擊者只修改了現有二進製文件的節特徵,並將修改過的程序寫入磁盤上的同一路徑,則防禦解決方案可以檢測到RWX-S補丁已應用於現有的文件。因此,建議將修補後的二進製文件寫入磁盤上的不同位置。

2、建議攻擊者添加RWX-S以外的其他補丁程序,比如修改與節特徵相關的其他無意義的屬性,或者隨機修改部分代碼(重要的是這些修改看上去並不是惡意的)。這樣做,是為了迷惑對手。

使用現有的未簽名二進製文件實際上,攻擊者並不需要創建自定義的、應用過補丁的二進製文件。例如,使用上一節中的YARA規則,攻擊者可以使用任何可能用於合法應用程序的現有未簽名RWX-S二進製文件。

在內核中濫用已簽名的RWX-S二進製文件儘管在過去的12個月內只發現了15個有簽名的RWX-S二進製文件,但在利用可能需要已簽名模塊的進程時,具有有效的authenticode簽名這一事實可能非常有用。

搜索顯示的一個有趣的已簽名的RWX-S二進製文件是一個已簽名驅動程序。當試圖測試共享節是否可以從用戶模式複製到內核模式時,發現內存沒有共享,即使已經通過Session 0中的進程映射和修改了該映像。

小結儘管共享節的稀有性為防御者提供了獲得高保真遙測的獨特機會,但RWX-S二進製文件仍然是一種強大的方法,它戳破了關於跨進程內存分配和執行的常見臆想。圍繞這一技術,防御者面臨的主要挑戰是它在未簽名代碼中的普遍性。檢測RWX-S二進製文件可能相對簡單,但你如何判斷它是否被用於合法的應用程序呢?

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...