1.前言
在上一篇文章中我们分析了Brute Ratel C4 1.2.2版本的HTTP/S Badger Payload,本篇文章将带来狩猎Brute Ratel C4 TeamServer和在睡眠混淆的Badger Core Dll
2.Hunting Brute Ratel C4 TeamServer
2.1 x509 Serial Number
通过openssl命令openssl x509 -text -in
查看Brute Ratel C4 1.2.2自带的默认自签名ssl证书Serial Number为:5387412a98a70cddcc71079db20e98d04f1b2275
使用shodan查询:ssl.cert.serial:5387412a98a70cddcc71079db20e98d04f1b2275
返回了4个结果
随意查看一个ip发现已经被shodan打上了c2和自签名证书的标签
443端口被shodan识别为了Brute Ratel C4,443端口应该是HTTP/S Listeners的监听端口
8443端口同样也被识别为了Brute Ratel C4,8443端口是Brc4自带的http profile示例中的默认Brute Ratel C4 TeamSeaver端口
2.2 x509 Sha1 Fingerprint
使用openssl命令openssl x509 -fingerprint -sha1 -in
查看Brc4自带的默认自签名证书的sha1 fingerprint为:55684A30A47476FCE5B42CBD59ADD4B0FBC776A3
使用shodan语句进行查询:ssl.cert.fingerprint:55684A30A47476FCE5B42CBD59ADD4B0FBC776A3
查看历史趋势可以看到使用Brc4自带的默认自签名ssl证书在2022年7月是一个高峰
2.3 Shodan Product
使用shodan语句:product:"Brute Ratel C4"
可以查询到7个被shodan官方确认为Brute Ratel C4的ip
查看历史趋势
2.4 Html MurmurHash3
如果没有在Brc4指挥官界面中Change Root Page选项更改默认页面的话有以下两个默认的返回信息,我们计算默认返回页面的mmh3 hash
使用shodan语句查询:http.html_hash:-1957161625
,有9个结果返回
查看历史记录可以看到在2022年7月使用默认返回页面404 file not found
达到一个顶峰
2.5 Html MurmurHash3 + jarm
如果通过shodan语句:http.html_hash:182674321
进行查询会发现返回的结果过多,我们要肯定要对结果进行过滤,这里我就选择通过Brute Ratel C4的默认JARM指纹进行过滤
查询本地环境的Brute Ratel C4的jarm指纹
通过shodan语句:http.html_hash:182674321 ssl.jarm:"3fd21b20d00000021c43d21b21b43de0a012c76cf078b8d06f4620c2286f5e"
查看历史趋势在2022年10月是一个高峰,根据Brute Ratel C4 1.2.2版本被破解并泄露到网上的时间点判断,可以推断出2022年10月这波高峰基本都是使用了网络上流传的1.2.2版本
随意查看其中一个使用自签名ssl证书的ip,443端口的自签名证书信息伪造了Microsoft Windows Defender
8443端口同样也是使用相同的自签名ssl证书
通过shodan:ssl.cert.serial:7f8399f164aafcbe6c106be01810af87ae32d5d3
搜索此自签名ssl证书发现有10个使用了此自签名证书的ip
通过过滤这10个使用相同自签名证书的ip发现有9个的jarm指纹都为Brc4默认指纹:3fd21b20d00000021c43d21b21b43de0a012c76cf078b8d06f4620c2286f5e
还有一个jarm指纹为:3fd21b00000000000000000000043d9e7a0fcc9f7c415da35c1f9d626554af
的ip就是我们刚刚的查看的ip185[.]56[.]83[.]11
我们通过censys查看此ip发现OS居然为Windows操作系统,但是Brc4只有linux64和arm64两种TeamServer,猜测可能是通过Windows下的WSL运行?
查看443端口的JARM指纹发现是Brc4默认的指纹并不是shodan中显示的指纹
8443端口的JARM指纹也是Brc4默认的并不是shodan中显示的指纹
shodan:ssl.cert.fingerprint:bedf851a2b96b4428870f33d268eccbeadba280b
查询此自签名的证书sha1 Fingerprint历史趋势可以看到在2022年10月有一个高峰,可以大致推断此自签名证书应该是Brutel Ratel C4 1.2.2某个泄露版自带或者为某一个攻击团体所使用
2.6 http headers hash + html hash
如果单单通过http.headers_hash:144518609
会发现结果太多我们需要进行过滤
这里就通过默认的html hash进行过滤:http.headers_hash:144518609 http.html_hash:182674321
将这些结果通过jarm指纹进行过滤分析发现有29个ip都是Brc4默认的jarm指纹:3fd21b20d00000021c43d21b21b43de0a012c76cf078b8d06f4620c2286f5e
查看中3个jarm指纹为:40d1db40d0000001dc43d1db1db43de0a012c76cf078b8d06f4620c2286f5e
的ip可以发现这些ip都使用了Let's Encrypt的免费证书,并且我们可以看到ip地址为80[.]255[.]6[.]16
的对应域名为malware-lab[.]nsd[.]li
可以看到ip地址为80[.]255[.]6[.]16
的这个主机的域名为malware-lab[.]nsd[.]li
,在根据443端口的html hash可推断此ip为一个Brute Ratel C4 TeamServer
2.7 Banner + jarm
shodan:"HTTP/1.1 200 OK Date:" " Content-Length: 14 Content-Type: text/plain; charset=utf-8" ssl.jarm:"3fd21b20d00000021c43d21b21b43de0a012c76cf078b8d06f4620c2286f5e"
2.8 Banner + html MurmurHash3
shodan:"HTTP/1.1 200 OK Date:" " Content-Length: 14 Content-Type: text/plain; charset=utf-8" http.html_hash:182674321
通过查看jarm指纹统计可以看到29个ip的指纹都为Brc4的默认指纹
查看jarm指纹为2ad2ad16d2ad2ad00042d42d000000a5308aa908d3edc2392a602b7adac57a
的ip也是用了Let's Encrypt的免费证书并且域名为test1[.]offensive-operations[.]nl,通过这个域名大致可以认定这是一个用于测试的Brute Ratel C4 TeamServer的服务器了
3.Hunting Badger
3.1 Badger Yara Rule
以下yara rule用于检测未加密的Brc4 1.2.2版本x86和x64的Badger Shellcode
rule BRC4_badger_x64_shellcode : Brute_Ratel_C4_VERSION_1_2_2
{
meta:
description = "Brute Ratel C4 1.2.2 version badger x64 shellcode and stage x64 shellcode"
author = "yauv"
reference = "https://yauv.me"
data = "2023-2-20"
strings:
// shellcode start push reg
$hex1 = {41 5F 55 50 53 51 52 56 57 41 50 41 51 41 52 41 53 41 54 41 55 41 56 41 57}
// mov rax,imm; push rax
$hex2 = {48 B8 ?? ?? ?? ?? ?? ?? ?? ?? 50}
// mov r8,imm; push r8
$hex3 = {49 B9 ?? ?? ?? ?? ?? ?? ?? ?? 41 51}
// NtProtectVirtualMemory ror13 hash
$hex4 = {89 4D 39 8C}
// RtlAllocateHeap ror13 hash
$hex5 = {26 25 19 3E}
// LoadLibraryA ror13 hash
$hex6 = {8E 4E 0E EC}
condition:
all of them
}
rule BRC4_badger_x86_shellcode : Brute_Ratel_C4_VERSION_1_2_2
{
meta:
description = "Brute Ratel C4 1.2.2 version badger x86 shellcode and stage x86 shellcode"
author = "yauv"
reference = "https://yauv.me"
data = "2023-2-20"
strings:
// shellcode push reg
$hex1 = {E8 00 00 00 00 5B 60 89 E5 83 E4 F8 31 C0 50}
// mov eax,imm; push eax
$hex2 = {B8 ?? ?? ?? ?? 50}
// mov edx,imm; push edx
$hex3 = {BA ?? ?? ?? ?? 52}
// NtProtectVirtualMemory ror13 hash
$hex4 = {89 4D 39 8C}
// RtlAllocateHeap ror13 hash
$hex5 = {26 25 19 3E}
// LoadLibraryA ror13 hash
$hex6 = {8E 4E 0E EC}
condition:
all of them
}
使用yara进行扫描
以下yara rule用于检测未加密的x86和x64架构的Badger Core Dll
rule BRC4_badger_core_dll : Brute_Ratel_C4_VERSION_1_2_2
{
meta:
description = "Brute Ratel C4 1.2.2 version badger core dll "
author = "yauv"
reference = "https://yauv.me"
data = "2023-2-20"
strings:
$astring1 = "bYXJm/3#M?:XyMBF" fullword ascii
$astring2 = "%ls%ls%ls%ls%ls%ls%ls%ls%ls%ls%ls%ls%ls%d%ls%lu%ls" fullword ascii
$astring3 = "%02d%02d%d_%02d%02d%2d%02d.png" fullword ascii
$astring4 = "mem.dmp" fullword ascii
$astring5 = "<Left-Mouse>;" fullword ascii
$astring6 = "<Enter>;" fullword ascii
$astring7 = "%s.%x.%s.%s" fullword ascii
$ustring1 = "[+] malloc (RX) : 0x%p\n" fullword wide
$ustring2 = "<DIR>?%ls?%02d-%02d-%d %02d:%02d\n" fullword wide
$ustring3 = "[*] Task-%02d [Thread: %lu]\n" fullword wide
$ustring4 = "+-------------------------------------------------------------------+\n" fullword wide
$ustring5 = "[+] PID (%S) => %lu\n[+] PPID => %lu\n" fullword wide
$ustring6 = "[-] E: %lu\n" fullword wide
$ustring7 = "[-] E: 0x%lx\n" fullword wide
condition:
12 of them
}
使用yara扫描
3.2 Hunting SleepObf Badger Core
以上的yara rule可用于检测明文未加密的Badger Shellcode和Badger Core Dll,但是如果是已经进入睡眠混淆阶段的Badger Core Dll以上yara rule将无能为力,因为在睡眠混淆时会通过ROP链将Badger Core Dll虚拟内存权限改为PAGE_READWRITE
权限并且使用Rc4算法将整个Badger Core Dll内存全部加密
此为Brc4 1.2.2中APC方式睡眠混淆填充ROP链CONTEXT结构时使用ZwProtectVirtualMemory函数修改Badger Core Dll内存权限为PAGE_READWRITE
此为Brc4 1.2.2中Pooling-0和Pooling-1方式睡眠混淆填充ROP链CONTEXT结构时使用VirtualProtect函数修改Badger Core Dll内存权限为PAGE_READWRITE
那有没有办法可以进行检测呢,当然后我们可以通过遍历进程所有类型为MEM_PRIVATE
状态为MEM_COMMIT
并且内存权限为PAGE_READWRITE
类型的内存然后通过CONTEXT结构解析内存,如果发现有CONTEXT的RIP为VirtualProtect函数地址并且NewProtect参数有EXECUTE权限那么可以判断此进程可能为正在睡眠混淆中的Badger Core Dll,此检测想法和代码实现为Elastic Security的Joe Desimone提出,此项目名为Patriot
kernel32.dll中导出的VirtualProtect和VirtualProtectEx函数其实都是个Stub,其实就是jmp到kernelbase.dll导出的VirtualProtect和VirtualProtectEx函数实现,而在kernelbase.dll中这两个函数最终都会调用NtProtectVirtualMemroy函数通过syscall进入0环
函数原型如下,VirtualProtect函数的参数3为NewProtect在x64下的fastcall调用约定也就是通过R8寄存器进行传参,VirtualProtectEx和NtProtectVirtualMemroy函数都是参数4为NewProtect在x64下fastcall调用约定是通过R9寄存器进行传参
Patriot项目中的VirtualProtectFunction函数实现主要就是对比函数地址是否相同,IsExecuteSet函数主要就是对比内存权限标志是否有EXECUTE权限
接下来我们来分析下核心检测代码,获取3环下所有的VirtualProtect函数地址,通过将当前内存解析为CONTEXT结构然后判断RIP是否为这5个VirtualProtect函数地址其中的任意一个,如果检测到然后通过对比NewProtect参数是否包含EXECUTE权限,如果以上条件全部满足则判断此CONTEXT为可疑的正在睡眠混淆中的Badger
写了一个项目EmberEyes开源在了我的github,目前功能主要针对Brc4 1.2.2版本,后续更新将增加更多C2 Implants扫描和更多的通用扫描功能
-s选项的实现参考Joe Desimone的项目Patriot中的代码,使用-s选项时尽量使用管理员权限以扫描管理员权限运行的进程内存
可以对比在指挥官界面中上线的Badger可以看到PID和我们通过-s扫描到的可疑进程相同
使用-e选项提取Badger Payload中的Badger Core Dll和Badger Config(仅支持Brute Ratel C4 1.2.2版本的x64和x86架构的HTTP/S、DOH、Stage、TCP、SMB)
使用-p选项解析Badger Config并打印到控制台
使用-f选项通过Badger Config虚假上线任意个数的假Badger,目前只支持HTTP/S的Badger Config
查看指挥官界面上线虚假Badger成功
使用fidder查看Badger通信流量
使用-d选项使用EncKey解密经过base64编码的Brc4自定义加密算法数据,可以看到解密后的数据为Badger的心跳包
4.总结
本文讲述了如何狩猎Brute Ratel C4 TeamServer和检测睡眠混淆中的Badger,但是针对的版本主要是泄露的Brute Ratel C4 1.2.2版本,Brc4的开发者早已经针对缺陷特征更新了许多版本,各种C2的开发者和安全研究者们一直在进行一场猫鼠游戏,目前以NightHawk和Brute Ratel C4为首的商业C2框架正在积极研究开发可逃逸现有EDR/AV检测的新技术,在可预见的将来这两款C2框架将被更多攻击者采用。