CobaltStrike windows木马原理分析

2023-12-28 14:51:41

本文主要介绍CobaltStrike windows型木马的原理,同Meterpreter大体类似。不同之处有使用了命名管道,使用了http的相关api来下载payload,同样使用的peb来获取api的地址,最后的后门是一个反射型dll。

安装CobaltStrike环境

环境:

  • kali 192.168.1.19 cs服务器

  • win10 192.168.1.1 cs客户端

  • win7 x64 192.168.1.20 测试和分析的靶机

步骤:

  1. 下载cs4.4 cs_start4.5.rar_免费高速下载|百度网盘-分享无限制 (baidu.com)

  2. 解压后拷贝到kali系统中。

  3. 执行chmod +x teamserver,给teamserver文件执行权限。

  4. 启动cs服务器,执行sudo ./teamserver 192.168.1.19 123456

  1. 使用客户端连接cs服务端。

  1. 生成一个监听器 192.168.1.19:80。

  2. 生成一个windows后门程序。

  3. 在靶机上测试后门程序的有效性。

样本分析

样本的基本信息

文件大小: 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出来,作进一步的分析。

第二阶段 shellcode

这段代码与之前分析的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

第三阶段 shellcode

通过上一阶段的分析,已经拿到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;
}

第四阶段 反射型dll

sc3.bin是一个反射型的dll,先使用IDA用binary模式打开看一下,如下所示。首先执行了文件偏移为0x808b的函数。

文件偏移为0x808b对应的va为10008C7B。

使用dll模式打开这个样本,发现,sub_10008C7B正好是一个导出函数,函数名为ReflectiveLoader(x) ,很明显,这是一个反射型dll,sub_10008C7B是一个PE加载器。

这是dll实现cs马的主要功能,比较复杂,以后有机会再分析。

总结

CobaltStrike生成的以HTTP为回连方式的木马,要想快速定位c2,只需要在InternetConnectA处设置断点就行。

参考资料

文章来源:https://blog.csdn.net/a854596855/article/details/135266820
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。