本文轉載自【微信公眾號:MicroPest,ID:gh_696c36c5382b】
上一篇介紹了利用熵來檢測Fileless無文件的方式,裡面提到了內存攻擊方式,這裡探討下這個很流行、很廣泛的內存攻擊話題,特選取了老外的這篇《https://www.elastic.co/cn/blog/hunting-memory》關於內存攻擊技術的文章;內存攻擊的內容很多(如棧溢出、SEH鏈等),我們這裡主要是圍繞老外這篇文章裡的提到的進行,其他的不涉及。
《嘶吼公眾號》裡曾翻譯了這篇文章,對照原文,我對其中一些進行了更正以及拓展補充,也算是對這個主題的一個總結吧。
駐留在內存中的惡意軟體利用內存進行攻擊是一種以多種形式出現、已經存在了十多年的攻擊技術;隨著時間的推移,越來越流行,也反映出了基於內存的技術成功地避開了安全產品和從業者檢測的現狀。
一、內存攻擊技術
內存攻擊技術包括:Shellcode注入、反射式DLL注入、內存模塊、進程冷注入(Process Hollowing)、模塊重寫以及 Gargoyle內存掃描逃避技術,共六種。
1、ShellCode注入技術
Shellcode注入是最基本的內存攻擊技術,也是使用時間最長的,一般步驟構成:
1)使用OpenProcess打開目標進程;
2)使用VirtuallocEx在目標進程中分配eXecute-Read-Write (XRW)內存;
3)使用WriteProcessMemory將shellcode有效內容複製到新內存;
4)遠程進程中創建一個新的線程來執行shellcode(CreateRemoteThread);
5)使用VirtualFreeEx在目標進程中解除分配XRW內存;
6)使用CloseHandle關閉目標進程句柄。
總結:當我們試圖在另一個進程中執行代碼時,會使用VirtualAllocEx -> WriteProcessMemory -> CreateRemoteThread這條鏈。
臭名昭著的遠程控制木馬Poison Ivy使用就是這種技術,這是多年來其吸引很多APT攻擊組織的一個重要原因。
如果你使用x64dbg提取Poison Ivy樣本並在VirtualAllocEx上設置斷點,你將能很快找到負責注射的代碼塊。
在上圖中,調用VirtuallocEx之前的push 40指令對應PAGE_Execute_ReadWrite的頁面訪問保護值參數;
在下面這張由ProcessHacker截取的Poison Ivy植入的內存布局的截圖中,你可以看到它分配了許多這樣的 RWX 部分。
典型的代碼段類型為「Image」,映射到磁碟上的文件。但是,它們是「Private」類型,並不會映射到磁碟上的文件。因此,它們被稱為未回調的可執行部分或浮動代碼。從這些類型的內存區域開始的線程是異常的,是惡意活動攻擊的預兆。
ProcessHacker還可以顯示惡意軟體線程的調用堆棧,堆棧中有多個函數不映射到已加載模塊關聯的內存。
2、反射式DLL注入
由Steven less開發的反射式DLL注入是另一種內存攻擊技術。Metasploit的Meterperter有效載荷是最早嘗試將該技術完全武器化的嘗試之一,現在許多惡意軟體家族都在使用它。
反射式DLL注入的工作原理是創建一個DLL,在執行時將自身映射到內存中,而依賴於Windows的加載程序。注入過程與shellcode注入相同,只是shellcode被自映射DLL替代。添加到DLL中的自映射組件負責解析導入地址、修復重定位和調用DllMain函數。攻擊者可以使用c/c++等高級語言而不是彙編語言編寫代碼。
經典的反射式DLL注入,如Meterpreter使用的,很容易被搜索者找到。它會在進程中留下大量的RWX內存段,即使在關閉meterpreter會話時也是如此。這些未回調的可執行內存部分的開始包含完整的MZ/PE頭,如下所示。但是,其他反射式DLL可以擦除頭並修復內存洩漏。
加載在內存中的dll還可以方便地導出一個稱為ReflectiveLoader()的自描述函數。
3、內存模塊
內存模塊是另一種內存駐留攻擊技術,它類似於反射式DLL注入,注射器或加載器負責將目標DLL映射到內存而不是DLL映射本身。本質上,內存模塊加載器重新實現了LoadLibrary函數,但它在內存中的緩衝區而不是磁碟上的文件中起作用。最初的設計是為了在當前進程中進行映射,但可以將模塊映射到遠程進程。大多數攻擊的實現都會使用目標DLL的部分權限,並避免使用痕跡太重的RWX方法。
NetTraveler是一個使用內存模塊駐留技術的惡意軟體家族。它啟動時,會解包核心功能並將其映射到內存中,頁面權限更接近於合法的DLL,但內存區域仍然是私有的,而不是映射過來的。
活動線程在這些私有區域有起始地址,調用堆棧還顯示了這些惡意部分。
Winnti是另一個使用內存模塊技術的惡意軟體家族,如下所示,它們會在第一頁的部分權限上有一個小部分內存模塊。
然而,Winnti 示例顯然更加先進一些,因為DLL中的MZ/PE頭被擦除,使得檢測更加困難。
4、進程冷注入
Process Hollowing是現代惡意軟體常用的一種進程創建技術,雖然在使用任務管理器之類的工具查看時,這些進程看起來是合法的,但是該進程的代碼實際上已被惡意內容所替代。
它涉及到創建一個掛起的進程,從進程中取消原始可執行文件的映射(冷注入),為進程分配和寫入一個新的有效載荷,使用SetThreadContext將原始線程的執行重定向到新的有效載荷,最後調用ResumeThread來完成;而更隱蔽的變體使用Create/Map部分API來避免WriteProcessMemory。寫入代碼後,必須知道進程新的入口點在哪裡,新的Process Hollowing攻擊會採用跳轉來修改、而不是使用SetThreadContext來修改入口點。
DarkComet是使用Process Hollowing技術的惡意軟體家族之一。它可以同時使用幾種工具來檢測Process Hollowing,它的惡意活動會用CREATE_SUSPENDED標誌攻擊過程的產生,如下示:
5、模塊重寫
到目前為止,討論的所有技術都能導致執行非映像支持的代碼,因此可以直接對這些代碼進行檢測;而模塊重寫技術避開了這些,使其更難以被檢測。該種技術包括將未使用的模塊映射到目標進程,然後用自己的有效載荷重寫模塊;Flame病毒是第一個被大規模利用此種技術的惡意軟體家族。
6、Gargoyle內存掃描逃避技術
Gargoyle內存掃描逃避技術是一個將一個程序的所有可執行代碼都隱藏在不可執行的內存塊中的Poc技術,它可以通過只讀頁面保護休眠來躲過許多安全產品的檢測;然後使用異步過程調用、周期性地喚醒,並執行ROP 鏈,在跳轉到它之前將有效載荷標記為可執行;在有效載荷執行完畢後,Gargoyle再次隱藏其頁面權限並繼續休眠。
檢測這種攻擊技術的一種方法是檢查線程和用戶APC,以獲取ROP鏈(導向編程技術Return-Oriented Programming,簡單的說就是把原來已經存在的代碼塊拼接起來,拼接的方式是通過一個預先準備好的特殊的返回棧,裡面包含了各條指令結束後下一條指令的地址)的證據。
多說下這個:
對上面這幅圖:首先說明,該技術只適用32位Windows。該技術理解起來不難,主要利用了函數棧的特性(只適用32位Windows的原因),該技術的核心就是在要執行代碼之前,修改代碼段的權限,執行完畢後,再次修改代碼段的權限。這樣就偽造了一種代碼所在段為不可執行的假象。
這個技術實在有意思,我們後續將探討下。
二、內存檢測技術
安全人員現在對基於內存的攻擊技術已經保持有高度警惕了,但現狀是目前大多數安全產品還無法大規模地對這種技術進行檢測。
為此,有安全公司實現了可以廣泛進行檢測的方法,即在其PowerShell工具Get-InjectedThread上實現了一種相對較低幹擾的內存威脅檢測方法。該方法可以掃描系統上的活動線程可疑的起始地址。用戶可以利用它掃描其網絡中的主機,並快速識別許多內存常駐惡意軟體技術。該腳本通過使用NtQueryInformationThread函數查詢每個活動線程來檢索其起始地址。然後,使用VirtualQueryEx函數查詢起始地址,以確定相關的節點屬性。如果線程啟動的存儲器區域是未回調的並且是可執行的,即不是映像類型並且具有執行位設置,那麼該線程就被認為是注入的。
下圖就顯示了在系統上運行時的樣本檢測結果。
可以看出,這是ProcessId為2812的進程注入到RealNetwork.exe這個程序中,基地址位於BaseAddress處,內存頁的屬性為PAGE_EXECUTE_READWRITE。
該腳本將捕獲各種惡意軟體家族利用shellcode注入,反射式DLL,內存模塊和一些Process Hollowing技術。但是,它不能替代全面防止內存攻擊的安全產品,如EndGame。
Get-InjectedThread這個挺有意思,我們後面給大家介紹下這個工具。