陳智峰
(南京東南司法鑒定中心,江蘇 南京 210008)
Cobalt Strike 可以簡單認(rèn)為是一款遠(yuǎn)控程序,相當(dāng)于木馬,但它卻又不僅僅是常規(guī)的木馬遠(yuǎn)控。它是一款基于Java 編寫的全平臺多方協(xié)同后滲透攻擊框架,也稱為CS。由于該框架具備團(tuán)隊(duì)協(xié)作攻擊、流量防檢測、防安全軟件查殺等優(yōu)勢,因而也被大量黑客組織用于真實(shí)的高危害性的攻擊。
shellcode 是一段用于利用軟件漏洞而執(zhí)行的代碼,為16 進(jìn)制的機(jī)器碼,因?yàn)榻?jīng)常讓攻擊者獲得shell 而得名。shellcode 常常使用機(jī)器語言編寫。shellcode 只是一段字符,無法執(zhí)行的,需要一個(gè)加載器來運(yùn)行加載。打個(gè)比喻,shellcode 就相當(dāng)于毒藥本身,為了給目標(biāo)服用,我們還需要容器比如瓶子來裝載它。毒藥的免殺是欺騙目標(biāo)讓其服下,木馬的免殺是欺騙、躲過殺毒軟件的檢測。免殺的手段分兩大類,一種是針對shellcode(毒藥本身),一種是針對加載器(容器),都是要想辦法偽裝成正常物品。大部分時(shí)候需要搭配使用,效果更佳。如圖1 為cs 生成的64 位shellcode。
Shellcode 的免殺,主要分為編碼和加密,就是把shellcode 進(jìn)行加密存儲(chǔ),然后在執(zhí)行的時(shí)候再解密出來執(zhí)行,這樣殺軟靜態(tài)識別時(shí)候就不認(rèn)識我們的shellcode。我們可以對全部shellcode 使用同一種加密,也可以對shellcode 進(jìn)行分段使用不同的加密手段加密再分段解密,當(dāng)然也可以進(jìn)行多次加密等。其中編碼有base64 編碼,字符串編碼,uuid 硬編碼。加密的話有AES,XOR,ROT,RSA,RC4 等等。
下面以UUID 硬編碼為例,全稱為通用唯一識別碼(Universally Unique Identifier,縮寫:UUID),是用于計(jì)算機(jī)體系中以識別信息數(shù)目的一個(gè)128 位標(biāo)識符,根據(jù)標(biāo)準(zhǔn)方法生成,不依賴中央機(jī)構(gòu)的注冊和分配,UUID 具有唯一性。如圖2 是一個(gè)python 腳本,用來將shellcode 轉(zhuǎn)換為UUID 硬編碼。
加載器的免殺,這里首先介紹內(nèi)存加載方式,這是逃避靜態(tài)查殺的關(guān)鍵。Windows 操作系統(tǒng)的內(nèi)存有三種屬性,分別為:可讀、可寫、可執(zhí)行。在申請內(nèi)存頁時(shí),一定要把控好屬性,可以在Shellcode 讀入時(shí),申請一個(gè)普通的可讀寫的內(nèi)存頁,然后再通過VirtualProtect 改變它的屬性,變成可執(zhí)行。
接著介紹遠(yuǎn)程加載,也是分離免殺的一種,將惡意代碼放置在程序本身之外的一種加載方式。首先介紹http 方式,顧名思義就是需要一個(gè)Http server 和http client,我們需要先運(yùn)行http server 提供服務(wù),木馬就是http client,運(yùn)行時(shí)候去Http server 請求shellcode,再加載進(jìn)內(nèi)存執(zhí)行。還有icmp,dns,sockets 方式,只是協(xié)議不一樣,原理都是一樣的。
加載器的免殺手法還有進(jìn)程注入,我們可以通過線程注入的方式將病毒代碼注入到系統(tǒng)其他正常進(jìn)程中,這樣不但提高了病毒和木馬隱蔽性,同時(shí)如果將病毒注入到系統(tǒng)的核心進(jìn)程中也降低了被殺毒軟件查殺的可能性。[2]也就是將shellcode 注入到進(jìn)程中,進(jìn)程可以是存在的進(jìn)程,也可以是自己新建進(jìn)程。比如計(jì)劃把shellcode 注入notepad.exe 中,為了不影響現(xiàn)有的進(jìn)程,我們創(chuàng)建一個(gè)掛起的進(jìn)程notepad.exe,讀取線程上下文,讀取進(jìn)程內(nèi)存,讀取Notepad.exe 原始入口點(diǎn),卸載Notepad.exe 占用的內(nèi)存,將shellcode 放入內(nèi)存緩沖區(qū),在Notepad.exe 進(jìn)程中分配一個(gè)內(nèi)存空間,將shellcode 注入到Notepad.exe 的進(jìn)程里,修改Notepad.exe 的區(qū)段,修改Notepad.exe 的入口點(diǎn),恢復(fù)主線程,成功注入。這里再介紹下一種比較新形的注入,Early Bird 注入,是一種簡單而強(qiáng)大的技術(shù),允許攻擊者在其主線程啟動(dòng)之前將惡意代碼注入到合法進(jìn)程,從而避免被大多數(shù)反惡意軟件產(chǎn)品所使用的Windows hook 引擎檢測到。Early Bird 技術(shù)代碼的注入方法依賴于Windows 內(nèi)置的APC(異步過程調(diào)用)函數(shù),該函數(shù)允許應(yīng)用程序在特定線程的上下文中異步執(zhí)行代碼。下面介紹攻擊者將惡意代碼注入合法進(jìn)程的步驟說明:1.創(chuàng)建一個(gè)合法的Windows 進(jìn)程的暫停進(jìn)程(例如,svchost.exe);2.在該進(jìn)程中分配內(nèi)存(svchost.exe)并將惡意代碼寫入分配的內(nèi)存區(qū)域;3.將異步過程調(diào)用(APC)排隊(duì)到該進(jìn)程的主線程(svchost.exe);4.由于APC只能在處于可警告狀態(tài)時(shí)執(zhí)行進(jìn)程,因此只要主線程恢復(fù),就可以調(diào)用NtTestAlert 函數(shù)強(qiáng)制內(nèi)核執(zhí)行惡意代碼。
說到進(jìn)程注入,不得不提反射dll 注入。常規(guī)的DLL 注入方式相信大家都很熟悉了,就是讓程序A 強(qiáng)行加載程序B 給定的a.dll,并執(zhí)行程序B 給定的a.dll 里面的代碼。注意,程序B 所給定的a.dll 原先并不會(huì)被程序A 主動(dòng)加載,但是當(dāng)程序B 通過某種手段讓程序A“加載”a.dll 后,程序A 將會(huì)執(zhí)行a.dll 里的代碼,此時(shí),a.dll 就進(jìn)入了程序A 的地址空間,而a.dll 模塊的程序邏輯由程序B 的開發(fā)者設(shè)計(jì),因此程序B 的開發(fā)者可以對程序A 為所欲為。因?yàn)閳?zhí)行命令需要借用某些合法進(jìn)程,所以一般的進(jìn)程注入都要繞過AV檢測。反射DLL注入可以將加密的DLL保存在磁盤(或者以其他形式如shellcode 等),之后將其解密放在內(nèi)存中。之后跟DLL注入一般,使用VirtualAlloc和WriteProcessMemory將DLL寫入目標(biāo)進(jìn)程。因?yàn)闆]有使用LoadLibrary 函數(shù),要想實(shí)現(xiàn)DLL 的加載運(yùn)行,我們需要在DLL 中添加一個(gè)導(dǎo)出函數(shù),ReflectiveLoader,這個(gè)函數(shù)實(shí)現(xiàn)的功能就是加載自身。
以上就是目前常見的免殺技術(shù),每一種單獨(dú)的方法可能都不能直接免殺,但是多種方法的靈活組合則能達(dá)到不錯(cuò)的效果。