本文主要介绍CobaltStrike windows型木马的原理,同Meterpreter大体类似。不同之处有使用了命名管道,使用了http的相关api来下载payload,同样使用的peb来获取api的地址,最后的后门是一个反射型dll。
环境:
kali 192.168.1.19 cs服务器
win10 192.168.1.1 cs客户端
win7 x64 192.168.1.20 测试和分析的靶机
步骤:
解压后拷贝到kali系统中。
执行chmod +x teamserver
,给teamserver文件执行权限。
启动cs服务器,执行sudo ./teamserver 192.168.1.19 123456
生成一个监听器 192.168.1.19:80。
生成一个windows后门程序。
在靶机上测试后门程序的有效性。
样本的基本信息
文件大小: 14.0 KB (14,336 字节)
Verified: Unsigned
Link date: 8:17 2020/6/9
Publisher: n/a
Company: n/a
Description: n/a
Product: n/a
Prod version: n/a
File version: n/a
MachineType: 32-bit
MD5: FC3E48A0A0AE35736B62BFF12532E858
SHA1: 2ACAD343D2DF4EB5E72C7643AFA4A129D63395EB
第一阶段的功能是解密并执行一段shellcode。
使用IDA打开样本,主要的恶意功能在sub_401840函数中。该函数构造一个命名管道的名称,然后创建一个线程向这个命名管道中写入一段加密的数据(va为00403014,大小为31Dh)。
ReadAndExecSC_4017E2函数从pipe中读取数据,解密shellcode,解密使用的key = {0x4,0x3B,0xE2,0xE1},最后跳转到shellcode的入口处执行。
使用od在00401550处下断点,将这段shellcode dump出来,作进一步的分析。
这段代码与之前分析的meterpreter木马如出一辙。也使用peb获取api的地址,其hash的方式也相同,可以直接使用上次导出的api_hash表了。这段shellcode首先导入了wininet.dll
,需要将上一篇博客中代码稍微修改一下就行。
使用IDA打开这段shellcode,如下所示,开头直接进入sub_2008F。CallApiByHash_20006函数是使用hash来调用系统api的函数,上一篇博客中已经详细讲过了,这里不再展开。
首先从栈顶获取CallApiByHash_20006的地址,调用InternetOpenA(NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0)
。
下一步会进入sub_200B5,这里同样采用函数的返回地址传参,调用InternetConnectA函数,可以清楚的看到C2地址为192.168.1.19:80。
接着会进入sub_200CE,这里同样采用返回地址传参。
调用HttpOpenRequestA和HttpSendRequestA函数,可以看到uri和User-Agent,这样已经获取了完整的C2信息。
C2:http://192.168.1.19:80/CbQf
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB7.4; .NET4.0C)
使用InternetErrorDlg函数来检查HttpSendRequestA调用是否有误。
接着使用VirtualAlloc函数分配一段可执行的内存,使用InternetReadFile从C2(http://192.168.1.19:80/CbQf
)下载payload,最后跳转到payload处执行。
第二阶段中使用的API和对应的hash的值 :
kernel32.dll!LoadLibraryA: 0x0726774c
wininet.dll!InternetOpenA: 0xa779563a
wininet.dll!InternetConnectA: 0xc69f8957
wininet.dll!HttpOpenRequestA: 0x3b2e55eb
wininet.dll!HttpSendRequestA: 0x7b18062d
kernel32.dll!GetLastError: 0x5de2c5aa
user32.dll!GetDesktopWindow: 0x315e2145
wininet.dll!InternetErrorDlg: 0x0be057b7
kernel32.dll!VirtualAlloc: 0xe553a458
wininet.dll!InternetReadFile: 0xe2899612
kernel32.dll!ExitProcess: 0x56a2b5f0
通过上一阶段的分析,已经拿到C2地址为http://192.168.1.19:80/CbQf
,在浏览器中打开这个url,可以直接下载到payload。
使用IDA用binary模式打开,发现这又是一段shellcode,继续分析。
这段shellcode跳了几下,进入了sub_21,如下图所示。
首先获取和payload的地址、大小和解密要使用key,然后使用异或的方式解密payload,最后跳转到解密后的payload中执行。
这部分在之前的博客中分析过,可参考一例cobalt Strike 反射式注入payload的分析_cobaltstrike_payload_encoded-CSDN博客。
我们使用C语言实现解密的过程(代码如下 ),也可以从OD中直接dump出来。将dump出来的shellcode命名为sc3.bin。
#include <stdio.h>
#include <windows.h>
int main(int argc,char** argv){
FILE* file = fopen("CbQf","rb");
DWORD sc_size = 0x34000;
DWORD offset = 0x00000059;
DWORD key = 0x7C7E8867;
fseek(file,offset,SEEK_SET);
char* buf = (char*)malloc(sc_size);
memset(buf,0,sc_size);
size_t readbytes = 0;
while(readbytes < sc_size){
size_t r = fread(buf + readbytes,1,sc_size-readbytes,file);
if(r < 0) break;
readbytes += r;
}
fclose(file);
if (sc_size == readbytes){
//解密
DWORD *_buf = (DWORD*)buf;
DWORD _sc_size = sc_size / sizeof(DWORD);
for(int i = 0;i< _sc_size;i++){
_buf[i] ^= key;
key ^= _buf[i];
}
//导出
FILE* outfile = fopen("sc3.bin","wb");
fwrite(buf,1,sc_size,outfile);
fclose(outfile);
}
free(buf);
return 0;
}
sc3.bin是一个反射型的dll,先使用IDA用binary模式打开看一下,如下所示。首先执行了文件偏移为0x808b的函数。
文件偏移为0x808b对应的va为10008C7B。
使用dll模式打开这个样本,发现,sub_10008C7B正好是一个导出函数,函数名为ReflectiveLoader(x) ,很明显,这是一个反射型dll,sub_10008C7B是一个PE加载器。
这是dll实现cs马的主要功能,比较复杂,以后有机会再分析。
CobaltStrike生成的以HTTP为回连方式的木马,要想快速定位c2,只需要在InternetConnectA处设置断点就行。