首款反射式PE殼《琥珀》

由於操作系統內部日益增加的安全標準和惡意軟體檢測技術的快速改進,現如今的惡意軟體作者開始利用由內存執行。PE的內存執行或者無文件執行可以被定義為在內存中執行一個編譯的PE文件,手動運行OS載入程序在正常PE文件載入時應有的操作。惡意軟體的內存執行有助於混淆和反模擬技術。另外,正在使用這種方法的惡意軟體在系統上留下的痕迹更少,因為內存執行沒必要在硬碟上佔有一個文件。內存執行方法和多階段注入模型組合,可以使用及其小的程序載入器將惡意軟體注入系統。載入程序的唯一目的是通過鏈接到遠程系統來載入和執行實際的惡意軟體代碼。使用小型載入器的代碼很難被安全產品檢測,因為載入器的代碼片段在合法應用程序中也普遍使用。使用這種方法的惡意軟體仍然可以通過掃描內存並檢查進程的行為來檢測,但是在安全性方面,這些操作難以實施,因為資源使用量較高而且代價昂貴。(Ramilli,2010[1])

Advertisements

目前普遍增長的趨勢是使用機器學習機制自動檢測惡意軟體,給系統提供巨大的數據集,如所有的機器學習程序一樣,這種機制可以更快更準確的吸收更多的惡意軟體樣本。這些機制可以提供大量的人類惡意軟體分析師無法處理的級別的樣本。Malware Detection Using Machine Learning[2]由BitDefender Romania Labs的 Gavriluţ Dragoş發表的這篇論文廣泛的闡述了機器學習在惡意軟體檢測中的使用的內部原理。根據Konrad Rieck的論文Automatic Analysis of Malware Behavior using Machine Learning[3],只要有足夠的數據和時間,假陽性的結果將趨近於0,並且惡意軟體的檢測將在新的惡意軟體樣本上產生顯著效果。

Advertisements

這項工作的主要目的是為PE文件開發一種新的加殼方法,可以改變將惡意軟體傳送到系統的方式。取代試圖找到新的反檢測技術來提供機器學習的數據集,通過無文件代碼注入將payload載入到系統中從而繞過絕大多數的安全機制。通過這種新的加殼方法,可以將PE文件轉化為可用於常見軟體漏洞(如緩衝區溢出)的多階段注入的payload。

已知方法

以下的技術是我們殼的靈感來源:

反射式DLL注入[4]是一個非常好的由Stephen Fewer 開發的庫注入技術,該方法是開發這個名為琥珀的殼的主要啟發點。這種技術允許在內存執行中用反射編程的方法編寫特定的DLL。由於採用了反射編程方法,這種技術允許多階段payload的部署。除了這種技術的諸多優點之外幾乎沒有限制。第一個限制是所需的文件格式,該技術期望將惡意軟體作為DLL文件進行開發或重新編譯,不幸的是在大多數情況下,將已編譯的EXE文件轉換為DLL是不可能的,或者需要對二進位文件進行大量工作。第二個限制是需要重定位數據。反射型DLL注入技術需要重定位數據來調整內存中DLL的基址。同時,這種方法已經存在了一段時間了,這意味著最新的安全產品可以很容易的檢測到反射型DLL注入的使用。我們的新工具,琥珀將為這些限制提供解決方案。

Process Hollowing[5]是另一種廣為人知的內存執行方法,使用公開的WindowsAPI創建新的進程然後將PE文件映射進該進程。這種旨在降低惡意軟體檢測率的加密器和殼中很受歡迎。但是這個方法也有幾個缺點。由於最新的Windows操作系統中的地址空間布局隨機化(ASLR)安全措施,創建新進程時內存區域是隨機的,因為process

hollowing同樣也需要實現在最新的Windows操作系統上的鏡像基址重定位。如上所述,基址重定位需要PE文件內的重定位數據。另一個缺點是由於特定文件的映射和進程創建API函數的使用有特定的順序,這種方法很容易被安全產品識別。

Hyperion[6] 是一款PE加密器,由Christian Amman 於 2012開發併發布。它解釋了運行時加密器的理論知識以及實現原理。在開發Hyperion是使用的PE解析方法和設計視角對我們的POC殼很有幫助。

技術細節

通過模仿OS的PE載入器,可以在OS內存中執行編譯的二進位文件是該殼的基本原理。在Windows上,PE載入器執行許多重要的事情,諸如將問價映射到內存並解析導入函數的地址是執行PE文件最重要的步驟。目前用於在內存中執行EXE文件的方法是使用特定的WindowsAPI函數來模擬WindowsPE載入器。通常的方法是使用NtMapViewOfSection,MapViewOfFile和CreateFileMapping函數。這些函數的使用通常會造成可疑行為,增加惡意軟體檢測的可能性。開發這款殼的關鍵方面之一就是盡量減少API函數。為了避免使用可疑文件映射API函數,我們的殼使用預先封裝的PE映像,此外,惡意軟體的執行發生在目標進程內部,不使用WindowsAPICreateProcess函數。目標進程內執行的惡意軟體以相同的進程許可權運行,因為它們共享了包含進程特權信息和配置的TEB塊。琥珀有兩種你類型的stub,其中一個用於支持ASLR,另一個用於被剝離或不具有任何重定位數據的EXE文件。ASLR

stub僅使用4個Windows API,其他的stub僅使用3個大多數合法應用程序廣泛使用的API。

ASLR stub:

VirtualAlloc

CreateThread

LoadLibraryA

GetProcAddress

非ASLR stub:

VirtualProtect

LoadLibraryA

GetProcAddress

為了在運行時調用這些API,琥珀使用了Stephen Fewer的反射式DLL注入[4]方法所使用的公開的EAT解析技術。該技術簡單在內存中通過PEB來定位InMemoryOrderModulesList結構。定位該結構后,可以讀取所有載入的DLL導出表,讀取由InMemoryOrderModuleList指向的每個_LDR_DATA_TABLE_ENTRY結構。在訪問到DLL的導出表之後,將先前計算出的每個導出函數名的ROR(右移)13散列值進行比較,直到匹配。琥珀的加殼方法還提供了集中替代的WindowsAPI使用方法,其中之一是使用固定的API地址,如果使用者熟知承載琥珀的遠程進程的相關信息的話。使用固定API地址將直接繞過最新的操作系統級漏洞利用,檢查導出表地址刪除API地址查找代碼將減少總體的payload大小。另一種替代技術可用於定位所需功能的地址,例如Josh Pitts 在 「Teaching Old Shellcode New Tricks」[7]中展示的技巧。當前版本的琥珀加殼器僅支持固定API地址和EAT解析技術,但IAT解析將在下一個版本中添加。

生成payload

為了生成實際的琥珀payload,首先加殼器創建一個惡意軟體的內存映像,生成的內存映射文件包含PE的所有部分,PE header和未使用的區段空間使用0填充。

獲取惡意軟體的映射之後,加殼器將檢查所提供的EXE的ASLR的兼容性,如果EXE是ASLR兼容加殼器將添加相關的stub,如果PE使用固定基址就不添加。此刻,琥珀的payload就完成了:

ASLR Stub的執行

執行ASLR stub需要5個步驟:

——申請內存

——修復導入函數

——重定位

——FileMapping替換

——執行

在內存申請階段,stub通過調用VirtualAlloc函數來分配惡意軟體映像大小相同的RWE內存空間,

這個內存空間將是重定位過程后惡意軟體新的基址。第二階段,琥珀的stub將解析導入函數的地址,並將地址寫入惡意軟體的導入表。

地址戒心階段與WindowsPE載入程序使用的方法非常類似,琥珀的stub將解析映射的惡意軟體映像的導入表,並通過LoadLibraryA函數載入惡意軟體的IMAGE_IMPORT_DESCRIPTOR中使用的每個DLL。

在載入完所需的DLL后,stub會保存每個DLL的句柄,並在GetProcAddressAPI的幫助下,從載入的DLL中查找導入函數的地址。IMAGE_IMPORT_DESCRIPTOR還包含一個指向名為import name表的結構指針,該結構的導入函數名與導入地址表(IAT)順序相同,在調用GetProcAddress時,stub以前載入的DLL句柄和導入函數的名稱為參數。每個返回的函數地址都將寫入(IAT),每個IAT之間由4位元組填充。此過程持續到導入表解析結束,載入完所需的DLL和解析完導入表之後,第二階段完成。

在第三階段,stub將根據VirtualAlloc返回的地址開始重定位過程,這幾乎和Windows本身的PE載入器完全相同,stub首先計算當前載入基址和原始載入基址之間的偏移delta,然後將delta加上重定位白的每一個條目。在第四階段,stub將文件映射到先前分配的空間中,採用單位元組移動的方式來移動內存。

最後階段,stub將通過調用CreateThread從惡意軟體的入口處創建一個新的線程。創建新線程的原因是為惡意軟體創建一個新的可擴展棧,另外在新線程中執行惡意軟體並不會映像目標進程的執行狀態。創建惡意軟體后,線程將恢復執行,返回到第一個調用者或stub,然後跳轉到一個死循環,阻塞防線線程,惡意軟體線程成功運行。

非ASLR Stub的執行

非ASLR Stub的執行需要4個步驟:

——內存申請

——解析IAT

——文件映射替換

——執行

如果惡意軟體被剝離或者沒有重定位信息,則無法將其放到首選基地址。在這種情況下,stub嘗試通過調用VirtualPtotect函數來更改目標進程的內存訪問許可權,大小為惡意軟體的大小。如果出現這種情況,首選極其之和目標進程代碼段可能由重疊,並且目標進程在執行payload后將無法執行。

stub可能無法更改指定區域的訪問許可權,這又多個原因,如執行的內存返回不在當前進程頁邊界內(原因最可能是ASLR),或執行的地址與stack

guard重合。這是stub的主要限制,如果提供的惡意軟體沒有ASLR支持(內部沒有重定位數據),並且stub不能更改目標進程訪問許可權,則無法繼續。在某些情況下,stub成功更改內存區域許可權,但立即崩潰,這是由於覆蓋部分中運行著多個線程引起的。如果目標進程在fix

stub執行時有多個線程,則可能會由於更改內存許可權或覆蓋到正在運行的部分崩潰。然而,如果不使用具有fix

stub的多級payload,則這些限制無關緊要,當前的POC封裝器可以相應的調整生成EXE文件的基址和stub

payload的位置。如果內存分配結束,第一階段就完成了。第二階段與上邊ASLR

stub方法相同。完成後同樣使用memcpy移動內存到先前修改的內存區域。

在最後階段,stub跳轉到惡意軟體的入口點並執行,不創建新線程。不幸的是使用非ASLR stub的程序不能繼續之前的運行狀態。

多階段程序

在不久的將來,操作系統將會採取的安全措施將會減少惡意軟體的攻擊面。微軟已經在2017年5月2日發布了Windows10 S[8],這個操作系統基本上是Windows10的配置了更高安全性的版本。這個操作系統採取的主要預防措施之一是不允許安裝除WindowsStore以外的程序。這種操作系統採用的白名單方法將對通過可執行文件感染系統的惡意軟體產生巨大影響。在這種情況下,多級內存執行payload將成為最有效的攻擊方法之一。由於stub位置的獨立性,它允許多階段攻擊模型,當前的POC加殼器能夠從複雜的PE文件中生成一個payload,可以從內存載入和執行,如常規的shellcode注入攻擊。在這種過度限制的系統用中,琥珀的多階段兼容性允許利用基於內存的常見軟體漏洞,例如棧和堆的緩衝區溢出。

然而由於fix stub的限制,建議在執行多級感染攻擊時使用ASLR支持的EXE文件。由POC加殼器生成的階段payload與從Metasploit Framework [9]生成的小型載入器shellcode和有效載荷兼容,這也就意味著琥珀可以用於Metasploit Framework中多級meterpreter shell code。

源碼如下,歡迎fork以及contribute!

https://github.com/EgeBalci/Amber

被檢出率

當前版本(2017.10.19)檢測率令人相當滿意,但由於這是一個公共項目,目前的檢測分數不可避免的會上升。

當沒有額外的參數傳遞(只有文件名)加殼器生成的多級載荷使用多位元組隨機密鑰執行基本的XOR加密,然後將其編譯成EXE文件,並加入少量額外的防檢測功能。生成的EXE文件在解密payload並執行所需的環境檢查之後,像常規的shell

code一樣執行payload。這個特殊的例子時用12位元組XOR key(./amber mimikatz.exe -ks 12)打包的mimikatz.exe(sha256-

9369b34df04a2795de083401dda4201a2da2784d1384a6ada2d773b3a81f8dad)文件。在VirusTotal上,加殼前的mimikatz.exe文件的檢測率為51/66。在這個特殊的示例中,加殼程序使用默認方式來查找使用哈希API的Windows

API地址,避免使用hash API會降低檢測率。目前加殼器支持IAT偏移的固定地址的使用,下一個版本將包括IAT解析器shellcode以獲得更多的替代API地址查找方法。

VirusTotal檢測

https://www.virustotal.com/#/file/3330d02404c56c1793f19f5d18fd5865cadfc4bd015af2e38ed0671f5e737d8a/detection

VirusCheckmate Result

http://viruscheckmate.com/id/1ikb99sNVrOM

NoDistribute

https://nodistribute.com/result/image/7uMa96SNOY13rtmTpW5ckBqzAv.png

未來工作

這項工作為PE文件引入了新一代的加殼方法,但不支持.NET可執行文件,未來的工作可能包括對64位PE文件和.NET文件的支持。另外,這種方法的隱秘性方面可以有更多的改進。在使用RWE許可權完成內存分配之後,根據映像對應的區段許可權修改該區段對應內存的許可權可能會降低檢測率。在地址解析完成後擦除PE頭可以更難檢測。該項目在未來將繼續保持開源。

本文由看雪翻譯小組 zplusplus 編譯,來源pentest's blog@Ege Balci

Advertisements

你可能會喜歡