A Deep Dive into Brute Ratel C4 payloads – CYBER GEEKS
摘要
Brute Ratel C4是一款红队和对抗模拟软件,可以视为 Cobalt Strike 的替代品。在这篇博文中,我们将对一个未实现该框架所有最新功能的 Brute Ratel badger/agent进行技术分析。目前野外可获得的Brute Ratel 样本并不多。该恶意软件实现了 API 哈希技术,并包含了 C2 服务器、网络通信中使用的 user-agent、用于与 C2 服务器认证的密码以及用于加密传输到 C2 服务器数据的密钥等配置信息。该 badger 通过执行来自 C2 服务器的 63 个不同命令来控制被感染的机器。本文将详细介绍前 20 个命令,其余命令将在后续博文中详述。
技术分析
SHA256: d71dc7ba8523947e08c6eec43a726fe75aed248dfd3a7c4f6537224e9ed05f6f
这是一个 64 位可执行文件。该恶意软件将要执行的代码压入栈中,以规避杀毒软件和 EDR 软件的检测:
它实现了 API 哈希技术,使用"ROR EDI,0xD"指令计算 4 字节哈希值,并与预先计算的哈希值进行比较(图 2)。
VirtualAllocEx API 用于分配一个新的内存区域来存储 DLL 文件(0x3000 = MEM_COMMIT | MEM_RESERVE, 0x40 = PAGE_EXECUTE_READWRITE):
Brute Ratel C4 的配置以明文形式存储,但在最新版本中,配置是加密并 Base64 编码的。它包含 C2 IP 地址和端口号、网络通信中使用的 user-agent、用于与 C2 服务器认证的密码、用于加密传输到 C2 服务器数据的密钥以及 URI:

通过调用 CreateRemoteThread 创建一个执行新 DLL 入口点的线程:
该进程从 gs:[0x60]提取 PEB 指针,并从中获取指向PEB_LDR_DATA结构的另一个指针(+0x18),该结构包含已加载 DLL 的信息。InMemoryOrderModuleList 双向链表包含当前进程的已加载 DLL:
恶意二进制文件使用 VirtualAlloc 为实现主要功能的另一个 DLL 分配新内存:
LoadLibraryA 用于将多个 DLL 加载到当前进程的地址空间:
恶意软件通过调用 GetProcAddress 方法获取相关函数的地址:
该二进制文件使用 NtFlushInstructionCache 函数刷新当前进程的指令缓存(见图 11)。
最后,恶意软件将执行流程传递给新构建的 DLL:
如下所示,DLL 的一个导出函数名为"badger_http_1",这表明这是一个 Brute Ratel agent/badger。

FreeConsole 方法用于将进程从其控制台分离:
DLL 重复查找函数地址的过程,如图 16 所示。
该进程提取系统时间并将结果传递给 srand 函数:
atoi 方法用于将端口号转换为整数:
恶意进程通过调用 CreateMutexA API 创建一个未命名的互斥对象,如图 19 所示。
GetUserNameW 用于获取与当前线程关联的用户名:
GetComputerNameExW 用于获取与本地机器关联的 NetBIOS 名称:
badger 使用 GetCurrentProcess 获取当前进程的伪句柄:
OpenProcessToken API 用于打开与进程关联的访问令牌(0x8 = TOKEN_QUERY):
恶意软件使用 GetTokenInformation 方法验证令牌是否提升(0x14 = TokenElevation):
它通过调用 GetCurrentProcessId 获取当前进程 ID:
GetModuleFileNameW 用于提取进程的可执行文件路径:
上述路径使用 CryptBinaryToStringW API 进行 Base64 编码(0x40000001 = CRYPT_STRING_NOCRLF | CRYPT_STRING_BASE64):
该进程使用 RtlGetVersion 获取当前操作系统的版本信息:
WSAStartup 函数启动当前进程对 Winsock DLL 的使用:
badger 构造一个 JSON,存储从配置中提取的密码、计算机名、操作系统版本、Base64 编码的可执行文件路径、用户名和进程 ID:
JSON 使用 XOR 运算符加密(密钥 = 配置中的"abcd@123")并通过其他操作进行转换:


传递给 InternetOpenW 函数的 user-agent 似乎表明该产品被德勤中国使用(图 34)。
该进程通过调用 InternetConnectW 函数连接到 80 端口的 C2 服务器:
如下所示,它使用 HttpOpenRequestW 创建一个指向"/content.php"资源的 POST 请求。
使用 InternetSetOptionW API 更改句柄的安全标志(0x1100 = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_UNKNOWN_CA):
HttpAddRequestHeadersW 可用于向句柄添加一个或多个 HTTP 请求头,但在恶意软件执行期间第二个参数为 NULL(0x20000000 = HTTP_ADDREQ_FLAG_ADD):
该进程使用 Base64 编码加密的 JSON,并使用 HttpSendRequestW 泄露生成的数据:
它通过调用 InternetQueryDataAvailable 验证 C2 服务器是否发送任何数据:
使用 InternetReadFile 读取 C2 服务器的响应:
响应被 Base64 解码并使用之前提到的相同密钥解密。"auth"字段被设置为解密的信息,并向 C2 服务器发出另一个请求,请求命令:
FakeNet-NG用于模拟与 C2 服务器的网络通信。解码和解密响应后,前 2 个字节表示要执行的命令,如果需要,后面跟着额外的参数。一个新线程处理命令执行:
我们现在将描述 C2 服务器可以发出的命令。
0x2C74 ID – 将文件内容泄露到 C2 服务器
PathFileExistsA API 用于确认目标文件是否存在于系统中:
通过调用 CreateFileA 打开文件(0x80000000 = GENERIC_READ, 0x1 = FILE_SHARE_READ, 0x3 = OPEN_EXISTING):
通过调用 ReadFile 方法读取内容,如图 46 所示。
数据与"[+] Download complete"消息一起发送到 C2 服务器,或发送下图所示的消息。
0xA905 ID – 复制文件
恶意软件使用 CopyFileA 将现有文件复制到新文件:
0x9B84 ID – 移动文件
该进程使用 MoveFileA 函数将现有文件移动到另一个位置(图 49)。
0x13A1 ID – 创建文件并用从 C2 服务器接收的内容填充
首先,通过调用 CreateFileA 创建文件:
接收的数据使用 CryptStringToBinaryA 进行 Base64 解码并写入文件:
0xE993 ID – 删除文件
如下所示,DeleteFileA 用于删除目标文件:
0x0605 ID – 关闭句柄
badger 使用 CloseHandle API 关闭对象句柄(即文件、进程):
0x3F61 ID – 创建目录
恶意二进制文件能够使用 CreateDirectoryA 方法创建目录:
0x1139 ID – 更改进程的当前目录
SetCurrentDirectoryA 用于执行所需的操作(见图 55)。
0x3C9F ID – 获取进程的当前目录
恶意软件通过调用 GetCurrentDirectoryW API 提取进程的当前目录:
0x8F40 ID – 删除目录
该进程仅在目录为空时使用 RemoveDirectoryA 删除目标目录:
0x0A32 ID – 获取文件/目录的最后写入时间
使用 FindFirstFileW 和 FindNextFileW 函数枚举当前目录中的文件:

对于每个匹配模式的文件或目录,二进制文件调用 CreateFileW API:
该进程通过调用 GetFileTime 获取最后写入时间:
使用 FileTimeToSystemTime 将文件时间转换为系统时间格式:
最后,上述时间被转换为当前活动的时区:
0x3D1D ID – 更改桌面壁纸
恶意进程打开包含桌面壁纸的"TranscodedWallpaper"文件:
上述文件用从 C2 服务器接收的内容填充(图 65)。
SystemParametersInfoA 方法用于更改桌面壁纸(0x14 = SPI_SETDESKWALLPAPER, 0x1 = SPIF_UPDATEINIFILE):
0xD53F ID – 获取用户名
此命令用于获取与当前线程关联的用户名:
0x0609 ID – 获取可用磁盘驱动器
如图 68 所示,恶意软件通过调用 GetLogicalDrives API 提取包含可用磁盘驱动器的位掩码。
0xC144 ID – 提取所有设备驱动程序
EnumDeviceDrivers 用于获取所有设备驱动程序的加载地址:
使用上述地址,该进程通过调用 GetDeviceDriverBaseNameA 方法获取设备驱动程序的名称:
0x0A01 ID – 计算系统启动以来经过的分钟数
GetTickCount 函数用于提取毫秒数并进行简单计算(见图 71)。
0x73E6 ID – 参数欺骗
badger 能够通过修改进程环境块(PEB)来隐藏参数:
0x8AFA ID – 父进程 ID 欺骗
此命令可用于伪造父进程 ID,以规避 EDR 软件或其他解决方案:
0xC929 ID – 提取子进程名称
该二进制文件可以生成多个进程,这些进程可以使用此命令显示(图 74)。
0x9E72 ID – 显示管道名称
恶意软件显示先前创建的管道的名称:
其余 30 个相关命令将在第二篇博文中详细介绍。
妥协指标
SHA256:d71dc7ba8523947e08c6eec43a726fe75aed248dfd3a7c4f6537224e9ed05f6f
C2 服务器:45.77.172.28
User-agent:[email protected]
参考资料
MSDN:https://docs.microsoft.com/en-us/windows/win32/api/
FakeNet-NG:https://github.com/mandiant/flare-fakenet-ng
Unit42:https://unit42.paloaltonetworks.com/brute-ratel-c4-tool/
原文始发于微信公众号(securitainment):Brute Ratel C4 载荷深度分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论