首页 > 其他分享 >CobaltStrike的狩猎与反狩猎

CobaltStrike的狩猎与反狩猎

时间:2024-06-20 15:58:31浏览次数:28  
标签:yara 检测 狩猎 kit beacon 内存 CobaltStrike

0x01 前言 

又到了xxx的时间了,在对红队基础设施的准备时写下的这篇文章

0x02 开始狩猎 

CobaltStrike版本:4.9.1

不做任何配置启动teamserver

image-20240517235439110

使用默认配置的生成x64位beacon,上线pid为3040

image-20240517235936475

0x021 BeaconEye 

BeaconEye 的核心原理是通过扫描CobaltStrike中的内存特征,并进行Beacon Config扫描解析出对应的Beacon信息

BeaconEye是基于.NETFramework 4.8框架开发的,至少需要.net4.0以上,为了解决真实环境下低版本服务器没有.net4.0以上的环境,可以使用EvilEye替代BeaconEye,EvilEye是Golang版本的BeaconEye

我目前使用的测试环境为Windows Server 2008,所以直接使用EvilEye进行检测,可以看到能直接从内存中提取出Beacon的信息

image-20240518000757786

0x022 Hunt-Sleeping-Beacons 

Hunt-Sleeping-Beacons项目的主要功能是帮助广大研究人员在运行时或其他正在运行进程的上下文场景中识别休眠的Beacon

可以看到Hunt-Sleeping-Beacons可以检测出异常的进程,但是我在实际测试中发现无法对x86进程进行检测

image-20240518001945217

0x023 Yara 

Yara是一个旨在(但不限于)帮助恶意软件研究人员识别和分类恶意软件样本工具

Elastic安全公司开源检测CobaltStrike的yara规则

Google GCTI开源检测CobaltStrike的yara规则

使用Elastic的yara规则检测beacon,可以看到命中了6条规则

image-20240518002338057

使用-s参数打印出匹配的字符串

image-20240518002921163

0x024 Hollows_Hunter 

hollows_hunter用于扫描所有正在运行的进程,识别各种潜在的恶意植入物,如替换/植入的PE、shellcode、挂钩(hook)以及内存中的修补程序等

顺带提一嘴,Hollows_Hunter的作者Aleksandra Doniec在我看来是一位顶尖的安全研究员,开源了pe_to_shellcodeprocess_overwriting等优秀的作品,真正左右手互博

通过hollows_hunter可以很轻松的检测到一些异常的进程

image-20240518004719411

0x03 反狩猎 

针对以上问题,CobaltStrike官方在博客中提供了一些解决方法

0x031 Yara bypass 

0x0311 字符串处理 

可以看到Windows_Trojan_CobaltStrike_ee756db7匹配了很多字符串,我决定先看看这些字符串都是从哪里来的。

image-20240518110112247

CobaltStrike在4.x之后,会把资源文件加密存放到cobaltstrike-client端的sleeve目录中,需要使用CrackSleeve对资源文件进行解密

CobaltStrike4.9.1的key如下,需要自行替换一下

private static byte[] OriginKey = {-1, 12, -6, 65, 7, -47, 91, 48, 17, 61, 29, 43, -99, -23, 21, 109};
private static byte[] CustomizeKey = {-1, 12, -6, 65, 7, -47, 91, 48, 17, 61, 29, 43, -99, -23, 21, 109};

对cobaltstrike-client及解密的Resource进行搜索,最后在default.profile发现了结果,而且与Windows_Trojan_CobaltStrike_ee756db7匹配的规则一致

image-20240518111451906

把他复制出来,并删除stage里面内容作为Malleable-C2来使用,重新启动server,生成beacon上线

image-20240518111742768

再次使用yara检测发现字符串匹配特征已经少了很多,但是还有一些存在

image-20240518112118978

既然profile中的特征已经去除了,那么剩余的规则要么在原始beacon.dll中存在,要么就是生成的exe时出现的特征,先看看原始beacon.dll吧,使用yara单独对文件进行检测,可以明显的看到,确实是在原始beacon.dll中存在的特征

image-20240518112318454

针对这种情况,CobaltStrike提供了可以从profile中使用strrep来替换指定的字符串,把其中的一个特征替换为空

transform-x64 {
    strrep "beacon.x64.dll" "";
}

image-20240518112908819

再次生成beacon,运行发现ee756db7规则直接就消失了

image-20240518113108536

???我看了一下Windows_Trojan_CobaltStrike_ee756db7的判定规则,发现该规则需要至少6个命中才会判定

image-20240518113154292

虽然这种方法简单且有效,但是从实际考虑来说,我们不应该全部都这么做,因为无法确定其他安全公司使用的规则,如果修改了判断规则为3个你只修改其中一个,那肯定是不行的,并且有些格式化字符串也不应该直接修改,否则可能会给程序带来不可意料的结果,如Windows_Trojan_CobaltStrike_3dc22d14中还检测了一些格式化字符串

当然也不是没有解决方法。那就是sleepmask kit套件,后面会详细介绍

0x0312 MZ头/PE头处理 

可以看到Windows_Trojan_CobaltStrike_1787eef5的特征为4D 5A,很明显该处检测的是MZ

image-20240518120434746

可以从内存中看到,确实存在该特征

image-20240518120631706

针对这种情况,CobaltStrike提供了可以在profile中配置 Stage.magic_mz_*/Stage.magic_pe_*对其进行修改

官方建议:需要注意的是,对于magic_mz_* 选项,提供的值必须是有效的(无)操作码,因为它们是作为shellcode存根的一部分执行的第一条指令。通常情况下,这将是pop regA,push regA的某种变体,因为后一条指令撤消了第一条指令,但请参阅此处以获得有关配置此选项的更多指导

修改mz头

set magic_mz_x86 "KC@H"; # ASM = dec ebx, inc ebx,inc eax, dec eax
set magic_mz_x64 "A[AS"; # ASM = pop r11, push r11

修改pe头

set magic_pe "AR"; # 随机的两个值

修改完成后在内存中的效果

image-20240518122456963

使用yara进行检测的前后对比

image-20240518122716965

然而,这种修改方式是有限的,因为我们在每种情况下只能修改几个字节,所以显然更健壮的YARA签名仍然会触发

同时官方还提供了一个Stage.stomppe用于轻微混淆内存中的 beacon dll,但是我在测试发现设置stomppe为true时,PE头中的仅仅在特征处增加了一个IMAGE_FILE_RELOCS_STRIPPED

image-20240518141851580

未设置stomppe时

image-20240518142201207

从微软的文档来看,我并不能明白这么做有什么好处,感觉很鸡肋,比较了解的师傅们回答我一下

image-20240518142358377

0x0313 清理反射加载器 

当Beacon被反射加载到内存中时,它会导致两个内存分配:原始Beacon DLL(实际上将执行shellcode存根和反射加载器函数)和虚拟Beacon DLL(正确加载到内存中并准备就绪)

在内存中的情况如下,RWX存储器区域对应于虚拟信标DLL,而RX区域则对应于原始信标DLL

image-20240518124308612

同时原始信标DLL中也存在可疑字符串。这些都可以通过内存中的YARA扫描找到

前面的是原始beacon,后面的是配置strrep “beacon.x64.dll” “";去除字符串后的内存,还应该把ReflectiveLoader这个非常明显的特征给去除掉

image-20240518125603435

扯远了,回到正题,针对这种情况,CobaltStrike提供了可以在profile中配置Stage.cleanup选项为true,对原始Beacon DLL进行清除,

仅保留虚拟Beacon DLL,一旦启动Beacon,就不再需要原始Beacon DLL了

set cleanup "true";

清理前后的内存对比

image-20240518133656176

yara检测结果如下,很明显清除原始beacon dll后有些检测已经从2个变成一个了

image-20240518142902423

0x0314 配置混淆 

通过配置Stage.obfuscate为true,可以实现反射加载器复制Beacon,而不带它的DLL头,这就意味着在内存中无法再找到反射加载程序存根,而且这个选项还会混淆:

  • .text section
  • Section names
  • Import table
  • Dos/Rich Header (this is technically not masked but overwritten with random data)

大概的示例图如下:

obfuscated_beacon

这项设置可移除Beacon堆中的绝大部分字符串

set obfuscate "true";

后面是配置obfuscate为true的内存,可以看到直接去除掉了dll头部

image-20240518145141448

yara检测设置obfuscate为true的前后对比

image-20240518145640501

0x0315 Sleep_Mask 

官方解释如下:

image-20240518151457439

在启用Sleep_Mask之前,先了解一下userwx配置

set userwx "false";

反射加载时是否要把内存设置为可读可写可执行,默认为RWX,设置为false时内存设置为RX

image-20240518152236236

然后配置启用sleep_mask

set sleep_mask "true";

正如官方所说,确实对字符串进行了加密,但是会多出一条新的规则,很明显sleep_mask默认的规则已经被检测了

image-20240518152747324

在内存中也确实找到了这个规则

image-20240518153136773

不是说sleep_mask会屏蔽自己吗?其实这项规则恰恰匹配的就是sleep_mask屏蔽的方法,如下图所示

sleep_mask

使用arsenal-kit的sleepmask进行配置

在common_mask.c中自定义我们的算法

/* My a beacon section
 *   First call will mask
 *   Second call will unmask
 */
void my_mask_section(SLEEPMASKP * parms, DWORD a, DWORD b) {
   char key[] = "cf81d743beef8422";
   size_t key_lenght = sizeof(key) - 1;
   while (a < b) {
      *(parms->beacon_ptr + a) ^= key[a % key_lenght];
      a++;
   }
}

image-20240518155631310

最后重新构建并重新加载.cna脚本,以使更改生效

image-20240518161439292

yara检测使用自定义算法的beacon,最后只剩一条特征了

image-20240518161907320

在内存中默认算法和自定义加密算法的对比

image-20240518162316466

0x0316 加载器特征去除 

0x03161 shellcode loader 

最后的这个特征,其实是生成exe时附带的。如果使用shellcode loader进行上线这一个部分就不需要更改了

不过使用shellcode loader要注意需要对存放shellcode的内存进行加密或者清理,非常简单的代码,主要是为了演示

#include<iostream>
#include<windows.h>
#include<fstream>

using namespace std;

int main()
{
    // shellcode raw 
	char filePath[] = "./payload_x64.bin";
	ifstream file(filePath, ios::binary | ios::ate);
	if (!file) {
		return -1;
	}
	int fileSize = file.tellg();
	file.seekg(0, ios::beg);

	char* buffer = new char[fileSize];
	if (!file.read(buffer, fileSize))
	{
		return -2;
	}
	void* exec = VirtualAlloc(0, fileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	memcpy(exec, buffer, fileSize);

    // 对buffer进行加密
	string key = "cf81d743beef8422";
	for (int i = 0; i < fileSize; i++)
	{
		buffer[i] = buffer[i] ^ key[i % key.length()];
	}

	((void(*)())exec)();

	return 0;
}

效果如下

image-20240520115058951

image-20240520115153924

0x03161 源码修改 

当然如果你追求完美,可以接着往下看,不过首先说明,通过套件的方式进行修改的只能在生成exe文件的时候有效,shellcode还是需要使用完成在内存进行加密

首先先定位一下特征,我直接使用ida对该字节码进行搜索

image-20240520115851311

伪代码看一下,看起来是//./pipe/MSSE-随机整数-server的通道生成

image-20240520120257965

在CobaltStrike的博客中有提到这个问题,指明了可以通过Artifact Kit中的src-common/bypass-pipe.c进行修改

image-20240520121122963

当然,如果你不想使用多余的套件,可以自行反编译修改并打包原始beacon.dll进行

我这边就演示在bypass-pipe.c中进行修改,注释部分的是Artifact Kit中默认的,该方法也已经被yara标记了,我做的只是简单的字符串隐藏

image-20240520121604054

因为使用了arsenal-kit中的artifact-kit和sleepmask-kit,所以直接修改arsenal-kit配置文件生成一个套件即可

修改的位置如下:

  • /arsenal-kit/kits/artifact/build.sh:49-51行,给它注释掉就不会报错了
  • /arsenal-kit/arsenal_kit.config:16行,设置include_sleepmask_kit=“true”,因为还启用了sleepmask-kit

接下来是Artifact kit options和Sleepmask kit options,根据实际情况修改即可

#### Artifact kit options
artifactkit_technique="pipe"
artifactkit_allocator="HeapAlloc"
artifactkit_stage_size=310272
artifactkit_include_resource="false"
artifactkit_stack_spoof="false"
artifactkit_syscalls_method="indirect"

#### Sleepmask kit options
sleepmask_version="49"
sleepmask_sleep_method="WaitForSingleObject"
sleepmask_mask_text_section="true"
sleepmask_syscalls_method="indirect"

运行/arsenal-kit/build_arsenal_kit.sh生成即可,生成后的路径为/arsenal-kit/dist/

image-20240520122739929

加载该套件,重新生成beacon,运行上线,使用yara对进程进行检测,可以看到和shellcode loader上线一样是检测不到的

image-20240520123104006

以上是x64的修改,x86也同样适用,不过x86需要额外修改一下2个位置

  • /arsenal-kit/kits/artifact/src-common/bypass-pipe.c中的DWORD server_thread(LPVOID whatever) 方法

    打乱一下它的结构就行

    image-20240520124230837

  • /arsenal-kit/kits/artifact/src-common/patch.c

    也是打乱一下结构

    image-20240520124403120

0x04 效果测试 

其实到了这一步已经能解决狩猎中的所有检测了

image-20240520125918091

yara静态检测

image-20240520125142238

yara内存检测

image-20240520125344815

BeaconEye/EvilEye

image-20240520125533843

Hunt-Sleeping-Beacons

image-20240520125640009

Hollows_Hunter

image-20240520125817678

配合shellcode loader对抗大部分杀软了

卡巴内存扫描

image-20240520140918116

火绒

image-20240520142356910

0x05 结语 

到此为止,配合一下自定义的Malleable-C2足以应付大部分红队场景,如果还想进一步,建议配合unhook、堆栈欺骗等技术

嘿嘿,如果你以为这就结束了,那就错了,如果说我针对Artifact Kit套件进行yara打标呢?以下是我找另一位师傅拿的它自己制作好的免杀马,上面是Elastic的检测,下面是自己针对Artifact Kit套件写的规则

image-20240531231133921

https://blog.aruiredteam.com/posts/cobaltstrike%E7%9A%84%E7%8B%A9%E7%8C%8E%E4%B8%8E%E5%8F%8D%E7%8B%A9%E7%8C%8E/

标签:yara,检测,狩猎,kit,beacon,内存,CobaltStrike
From: https://www.cnblogs.com/Fluorescence-tjy/p/18258815

相关文章

  • CobaltStrike 远控木马在42.194.250.177的80端口报警;奇安信网神态势感知报警(多次)
    在态势感知上报毒——目的IP:42.194.250.177的80端口。报毒名称为CobaltStrike远控木马活动事件,这个情况发生在已经封禁掉源IP和目的IP的前提下,所以让人百思不得其解。然后我登上了我的kali访问了这个目的IP的80端口,嘿!您猜怎么着?!这不是明摆着,欢迎您的到来嘛!这我不就来了嘛,Dir......
  • 红队技巧12:cobaltstrike和msf相互联动
    前言我们在利用msf获取权限后有时候需要利用cobaltstrike的方便功能在利用cobaltstrike获取到权限后有时候需要利用msf的payload这时候就需要cobaltstrike和msf相互联动msf会话->cobaltstrike会话msf生成木马msfvenom-pwindows/meterpreter/reverse_tcplhost=192.168.30.......
  • 【内网渗透】隐藏cobaltstrike服务器—自定义证书+C2侧写
    简介自定义证书查看Cobaltstrike默认证书发现特征含有cobaltstrike关键字常用keytool命令查看证书文件:keytool-list-v-keystorexx.store修改证书密码:keytool-storepasswd-keystoretest.store修改alias别名:keytool-changealias-keystoretest.store-aliasso......
  • 红队开发学习----魔改cobaltstrike学习(持续更新)
    目录环境和工具准备反编译CobaltStrike_4.4_000.jarIdea项目HelloWorld测试代码去除凭证读取teamserver端配置修改端口证书profile配置JA3|JA3S/JARM指纹修改源码层面修改stager导致配置泄漏修改xor密钥(未进行,没研究明白,怕改崩了)修改stager下载路径的长度修复一个漏洞参考文......
  • 宅家过周末和远古人类的狩猎
    上周2天宅家里,都没出去。然后呢,周一上班的时候,心情特别不好。当然也和项目驻地变了有关。但是周末心情变糟糕这件事,也和宅家里不出去有关。为什么宅家里不出去,心理会出现一些负面想法,我想大概违背了人性吧,每一个人可能骨子里潜藏着远古人类狩猎的习惯,比如天亮时走出住房,然后去狩猎......
  • CobaltStrike的使用工具的使用
    CobaltStrike的使用目录CobaltStrikeCobaltStrike的安装CobaltStrike的使用创建监听器:创建Attacks:视图View:对被控主机的操作抓取hash和dump明文密码提权(Elevate)利用被控主机建立Socks4代理进程列表(注入进程,键盘监控)生成黄金票据注入当前会话(GoldenTicket)凭证转换(MakeToken......
  • 教程:开始使用 Microsoft Sentinel 中的 Jupyter Notebook 和 MSTICPy——威胁狩猎用,含
    教程:开始使用MicrosoftSentinel中的JupyterNotebook和MSTICPy项目2022/05/026个参与者  备注AzureSentinel现在称为MicrosoftSentinel,我们将在几周内更新相关页面。详细了解最近的Microsoft安全性增强。本教程介绍如何运行“MicrosoftSentinelMLNotebook入门......
  • CobaltStrike
    CobaltStrike 是一款美国 RedTeam 开发的渗透测试神器,常被业界人称为 CS。最近这个工具大火,成为了渗透测试中不可缺少的利器。其拥有多种协议主机上线方式,集成了提权,凭据导出,端口转发,socket 代理,office 攻击,文件捆绑,钓鱼等功能。同时,CobaltStrike 还可以调用 Mimikatz......
  • CobaltStrike4.8--云服务器搭建
    系统版本选用选择最熟悉的版本,我这边用的CentOS7.8,选用乌班图的话,会有一些命令的不一致配置运行环境CobaltStrike4.0支持jdk1.8的环境,4.5开始就不支持1.8了,本文搭载的是cs4.8,故配置的环境是jdk11查看自身Linux版本uname-r选用的系统是64位的,后面我们需要选择64位jdk11......
  • 威胁狩猎:基于ELK的日志监控
     通过本实验的学习,你能够了解主机安全软件监控原理,学会如何利用主机安全软件狙剑监控可疑进程,学会如何利用狙剑软件对本机进行注册表和文件的管理。0x0、概述!ELKStack即以前的ElasticStack,ElkStack是Elastic公司专门为集中化日志管理设计的免费开源软件组合。它允许搜索、分析......