朝鲜APT组织APT37利用网络钓鱼邮件部署RokRat远程访问木马

APT37 组织
APT37 又名 ScarCruft、Reaper 和 Red Eyes,是一个由朝鲜政府支持的黑客组织,自 2012 年以来一直活跃。最初,其行动主要针对韩国的公共和私营部门,但在 2017 年,其目标扩大到日本、越南、中东以及医疗保健和制造业等行业。到 2023 年,APT37 已转向针对 Windows 和 Android 平台用户的网络钓鱼活动。
该组织以利用各种攻击媒介而闻名,包括通过群聊平台传播恶意 LNK 文件来感染受害者。
技术要点
- 感染媒介:攻击始于包含隐藏恶意 LNK 文件的 ZIP 附件的网络钓鱼电子邮件,这些文件伪装成与朝鲜事务或贸易协议相关的文件。执行后,LNK 文件使用批处理脚本和 PowerShell 启动多阶段攻击,最终以 RokRat 作为最终有效载荷。
- 主机分析:RokRat 收集详细的系统信息,包括操作系统版本、计算机名称、登录用户和可执行文件路径。它还会检索硬件详细信息、跟踪系统正常运行时间、枚举正在运行的进程并捕获屏幕截图。然后这些数据会被泄露到命令和控制 (C2) 服务器。
- C2 通信:RokRat 滥用 pCloud、Yandex 和 Dropbox 等云服务作为其命令和控制 (C2) 通道,使用其 API 发送、下载和删除文件。它还在其代码中嵌入 OAuth 令牌,以促进与这些服务的无缝通信。
- 命令执行:RokRAT 可以在受感染的系统上执行命令,允许攻击者执行各种活动,例如数据泄露、系统侦察和进程终止。它可以通过 cmd.exe 执行远程命令、收集和上传文件、扫描系统驱动器、删除特定文件以及从命令和控制 (C2) 检索其他有效负载。
感染流程
感染始于看似关键的网络钓鱼电子邮件,因为攻击者使用网站上的真实信息使其看起来更可信。这些电子邮件包含伪装成文档的恶意 LNK 文件的 ZIP 文件。执行后,它会启动下一阶段的攻击。
[
图(1):感染流程图
第 1 阶段 - LNK 文件
文件中嵌入的代码.lnk
执行调用 PowerShell 的命令。

图(2):LECmd 输出
首先,它会检查自己是否从System32或Program Files运行。如果是,它会转到该%temp%
目录。然后,它会使用一个简单的技巧,通过搜索.lnk
大小为0x0DD4B11F
字节的文件来读取自身。
一旦找到,它会从.lnk
文件中提取多个有效载荷并将其保存在%temp%
目录中。

提取的文件为:
- 在偏移量0x111E处,提取0xAD36字节并将其保存为
.hwpx
,立即执行。 - 在偏移量 0xBE54 处,提取 0xD9190 字节并将其保存为
caption.dat
。 - 在偏移量 0xE4FE4 处,提取 0x0636 字节并将其保存为
elephant.dat
。 - 在偏移量0xE561A处,提取0x0147字节并将其保存为
sharkeba.bat
,然后执行。
为了使提取过程自动化,我编写了一个快速脚本。
import os
import sys
def extract_embedded_files(lnk_path, output_dir):
try:
if not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(lnk_path, 'rb') as lnk_file:
lnk_file.seek(0x0000111E)
hwpx_data = lnk_file.read(0x0000AD36)
hwpx_path = os.path.join(output_dir, "extracted.hwpx")
with open(hwpx_path, 'wb') as f:
f.write(hwpx_data)
print(f"HWPX file extracted")
lnk_file.seek(0x0000BE54)
exe_data = lnk_file.read(0x000D9190)
exe_path = os.path.join(output_dir, "caption.dat")
with open(exe_path, 'wb') as f:
f.write(exe_data)
print(f"Caption.dat extracted")
lnk_file.seek(0x000E4FE4)
string_data = lnk_file.read(0x00000636)
string_path = os.path.join(output_dir, "elephant.dat")
with open(string_path, 'wb') as f:
f.write(string_data)
print(f"Elephant.dat extracted")
lnk_file.seek(0x000E561A)
bat_data = lnk_file.read(0x00000147)
bat_path = os.path.join(output_dir, "sharke.bat")
with open(bat_path, 'wb') as f:
f.write(bat_data)
print(f"Batch file extracted")
except :
print(f"Error occured ")
def main():
lnk_path = ''
output_dir = ''
extract_embedded_files(lnk_path, output_dir)
if __name__ == "__main__":
main()
最后,它会删除原始.lnk
文件以掩盖其踪迹。

第 2 阶段 - 被释放的
HWPX 文档
[
图(3):VT 上的 HWPX 文档
这是一份诱饵文件,旨在让受害者误以为他们打开的是正常文件,而真正的攻击则在后台运行。它看起来像是一份公共服务记录表,在韩国通常用于官方推荐和表彰。
[
图(4):HWPX文档内容
shark.bat
首先分析shark.bat
,然后提取并执行 。此批处理脚本在最小化的隐藏窗口中启动 PowerShell。然后,它elephant.dat
从%temp%
目录中读取,将其加载到内存中,并使用 执行它Invoke-Command
。

图(5):使用的脚本
elephant.dat
尽管它的名字如此,但这是另一个用于在内存中加载和执行有效负载的 PowerShell 脚本。它从目录中读取加密文件caption.dat(第四个提取的文件)%temp%
,并使用**单字节 XOR 密钥“d”**对其进行解密以获取可执行内容。

kernel32.dll
在内存中执行有效载荷。它会分配内存并创建线程来运行解密的有效载荷。
[
第 3 阶段 - [shellcode]
解密的 shellcode 从硬编码的加密数据中解密 PE 文件。
[
图(6):解密后的shellcode。
shellcode 从偏移量0x58B处的内存中读取数据,其中第一个字节是 XOR 密钥,接下来的四个字节是加密数据的长度,其余的是加密的 PE 文件。它通过将每个字节与密钥进行 XOR 来解密 PE,将其加载到内存中,解析导入并执行。
[
图(7):加密数据结构
我们可以使用这个IDApython脚本转储解密的PE文件。
def save_to_file(file_path, data):
with open(file_path, 'wb') as file:
file.write(data)
addr = 0x58B
xor_key = idc.get_bytes(addr, 1)
data_size = idc.get_wide_dword(addr + 1) # read 4-byte data size
enc_data = idc.get_bytes(addr + 5, data_size) # get encrypted data
dec_data = bytes(b ^ xor_key for b in enc_data)
save_to_file('dump_file.bin', dec_data)
最终有效载荷——RokRat
最后一个有效载荷是RokRat,这是 APT37 威胁组织主要使用的远程访问木马 (RAT)。该样本于 2024 年 10 月编译,此前曾在 2024 年 12 月的另一次攻击中出现过。
[
图(8):VT 上的 Rokrat。
反分析
加密字符串
Rokrat 使用两种自定义字符串解密技术来隐藏其字符串。
一种技术是将字符串存储为堆栈字符串,使用简单的基于减法的转换进行加密,使用第一个字符作为密钥,然后从每个后续字符中减去一个固定值(2048)。
另一种方法是使用第一个字节作为密钥来加密字符串。每次处理两个字节,然后从每个字节中减去密钥即可得到原始文本。
[
图(9):使用的加密算法。
以下是完整的解密字符串列表:
IsWow64Process
C:\Program Files\VMware\VMware Tools\vmtoolsd.exe
HARDWARE\DESCRIPTION\System
反虚拟机
Rokrat 通过 vmtoolsd.exe 检测 VMware Tools 的存在。它首先检查可执行文件是否存在于其默认安装路径中,然后检索其版本详细信息。如果找到该文件并成功提取其元数据,则假定它在 VMware 虚拟机内运行。
[
图(10):使用了 Anti vm。
检测沙箱
该函数在C:\Windows中创建然后删除一个随机文件,这是恶意软件和沙盒检测中常用的技术,用于测试文件系统的写入权限或引入执行延迟。
[
此外,Rokrat 使用 IsDebuggerPresent 检查调试器。
收集主机信息
RokRat 收集有关受感染系统的详细信息。它首先检索系统版本并确定进程是否在 下运行WOW64
。
此外,它还收集与系统相关的详细信息,例如计算机名称、登录的用户名和可执行文件的完整路径。
它从注册表中检索额外的系统详细信息,并以毫秒为单位确定系统的正常运行时间(不包括睡眠时间)。
[
图(12):收集的信息。
它还从注册表中提取系统详细信息,包括SystemBiosVersion。
[
图(13):从注册表获取硬件信息。
进程枚举固定
RokRat 收集有关正在运行的进程的详细信息,包括其进程 ID (PID)、可执行文件名称和文件路径。这些信息被格式化为"%spid:%d,name:%s,path:%s%s"
,并被存储和准备泄露。

图(14):进程枚举函数。
截取屏幕截图。
RokRat 捕获屏幕截图、处理图像(将其转换为 JPEG)并准备进行数据泄露。
[
C2 通信
RokRat 滥用 pCloud、Yandex 和 Dropbox 等合法云服务作为命令和控制 (C2) 通道。通过使用这些平台的 API,RokRat 可以无缝窃取被盗数据、下载其他有效负载并执行命令,同时混入正常网络流量中。此外,它还具有测试模式,可让其在本地机器上运行。
手术 | 云提供商 | API |
---|---|---|
上传文件 | Dropbox | https://content.dropboxapi.com/2/files/upload |
Yandex 磁盘 | https://cloud-api.yandex.net/v1/disk/resources/upload?path=%s&overwrite=%s |
|
云端 | https://api.pcloud.com/uploadfile?path=%s&filename=%s&nopartial=1 |
|
下载文件 | Dropbox | https://content.dropboxapi.com/2/files/download |
Yandex 磁盘 | https://cloud-api.yandex.net/v1/disk/resources/download?path=%s |
|
云端 | https://api.pcloud.com/getfilelink?path=%s&forcedownload=1&skipfilename=1 |
|
列出文件夹 | Dropbox | https://api.dropboxapi.com/2/files/list_folder |
Yandex 磁盘 | https://cloud-api.yandex.net/v1/disk/resources?path=%s&limit=500 |
|
云端 | https://api.pcloud.com/listfolder?path=%s |
|
删除文件 | Dropbox | https://api.dropboxapi.com/2/files/delete |
Yandex 磁盘 | https://cloud-api.yandex.net/v1/disk/resources?path=%s&permanently=%s |
|
云端 | https://api.pcloud.com/deletefile?path=%s |
它的代码中还包含 OAuth 令牌,以便与这些云服务进行通信。
主要使用 pCloud 进行命令和控制 (C2) 操作。它通过包含硬编码 OAuth 令牌的 HTTP 请求与 pCloud 进行身份验证: JINs7ZDb7OvfloXrYZt8wH7kZ7LjAjGKBckj4kTgWSBiDSVWF1fKX
它还通过欺骗其 User-Agent 字符串来隐藏其 HTTP 流量,使其看起来像是合法的 Googlebot 请求: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

图(15):Http请求示例。
RokRat 在窃取数据之前会结合使用 XOR 混淆和 RSA 加密。它首先使用随机生成的密钥进行 XOR 加密来混淆数据,使其难以识别。然后,它使用 RSA 加密混淆的数据,确保只有拥有私钥的攻击者才能解密。
命令
RokRat 从其命令与控制 (C2) 服务器检索加密命令,使用 AES-CBC 模式进行加密。然后它在本地解密命令并在系统上执行它们。
命令‘0’
此命令将发送数据标志设置为 0(假),意味着应停止数据收集。
命令 - ‘i’
该命令将发送数据标志设置为 1(true),表示收集到的信息已准备好发送到命令和控制(C2)服务器。
命令 - ‘j’ 或 ‘b’
这会创建一个终止过程,强制恶意软件停止运行并退出。
Command - ‘d’
此命令执行删除操作,从 Windows 启动文件夹和 AppData 目录中删除不同的脚本和快捷方式文件。它针对.VBS
(VBScript)、、.CMD
(.BAT
批处理脚本)、.LNK
(快捷方式) 以及执行期间创建的任何其他文件。
del "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\*.VBS"
"%appdata%\*.CMD"
"%appdata%\*.BAT"
"%appdata%\*01"
"%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\*.lnk"
"%allusersprofile%\Microsoft\Windows\Start Menu\Programs\Startup\*.lnk" /F /Q
删除完成后,命令将启动终止过程以关闭 RAT。
命令 - ‘f’
此命令与上一个命令类似,但它不针对 .lnk(快捷方式)文件。
del \"%appdata%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*.VBS\"\
"%appdata%\\*.CMD\" \
"%appdata%\\*.BAT\" \
"%appdata%\\*01\" /F /Q"
一旦删除完成,该命令还会启动终止过程以关闭 RAT。
命令 - ‘g’
此命令只是重置内存并将其擦除,使其为另一项操作做好准备。
命令 - ‘h’
此命令会扫描所有逻辑驱动器,包括固定驱动器、可移动驱动器和网络驱动器,以递归方式列出其内容并将结果保存在临时文件中。然后,该文件会被上传到命令和控制 (C2) 服务器,之后会被删除以消除任何痕迹。
[
图(16):该函数扫描所有逻辑驱动器。
命令——'e'
该命令通过cmd.exe执行从C2服务器接收的指令,允许远程执行系统命令。
[
图(17):命令e。
命令 - ‘c’
此命令从 C2 服务器接收路径,并检查它是文件还是目录。如果路径是目录,则该函数读取其文件、处理它们、加密其内容,然后将其上传到 C2 云服务器。
[
如果路径是文件,则根据文件扩展名应用过滤。当过滤器设置为“普通”时,它专门针对与文档相关的文件类型,例如.XLS
、.DOC
、.PPT
、.TXT
、.M4A
、.AMR
、.PDF
和.HWP
。但是,如果过滤器设置为“全部”,它会收集和上传任何类型的文件。

命令 [1-9]
这些命令下载有效负载并执行它:
下载(命令 1、2、5、6):
这些命令会从攻击者指定的 URL 动态获取辅助负载。此过程包括打开与 URL 的 HTTP 连接并下载数据,而无需任何额外的解密。
[
图(18):从互联网下载文件。
下载(命令 3、4、7、8、9):
这些命令从 C2 云服务下载有效载荷。下载后,将解密有效载荷,并通过检查验证其完整性。
执行(命令 1、2、3、4):
在这种情况下,代码会检查下载是否成功。如果成功,代码会创建一个新线程来执行有效载荷。如果执行成功,它会将“ OK ”写入临时文本文件(%temp%\r.txt)
。如果执行失败,它会将“ BD ”写入同一文件。

此外,还执行批处理脚本来收集系统信息,包括:
- 正在运行的进程列表
- 启动项
- 系统配置
- 路线详情
这些信息被保存到同一个临时文本文件**(r.txt)**中,加密后泄露到C2服务器。泄露后,文件被删除。
[
执行(命令 5、6、7、8、9):
在这种情况下,它还会检查下载是否成功。如果成功,它会构造一个文件路径。然后,它会创建一个名为的临时文件KB400928_doc.exe
,将提取的数据写入其中,并使用执行该文件ShellExecuteA
。
YARA 规则
rule detct_RokRat
{
meta:
description = "Detects Rokrat payload using some of the hardcoded strings "
author = "Mohamed Ezzat (@ZW01f)"
hash1 = "09a4adef9a7374616851e5e2a7d9539e1b9808e153538af94ad1d6d73a3a1232"
hash2 = "94159655fa0bfb1eff092835d8922d3e18ca5c73884fd0d8b78f42c8511047b6"
strings:
// apis used
$s0 = "https://api.pcloud.com/deletefile?path=%s" wide
$s1 = "https://api.dropboxapi.com/2/files/list_folder" wide
$s3 = "https://cloud-api.yandex.net/v1/disk/resources/upload?path=%s&overwrite=%s" wide
$s4 = "https://cloud-api.yandex.net/v1/disk/resources?path=%s&limit=500" wide
$s5 = "https://cloud-api.yandex.net/v1/disk/resources?path=%s&permanently=%s" wide
// file it use for download payloads .
$s6 = "KB400928_doc.exe"
$s7 = "%04d%02d%02d %02d%02d%02d" wide
condition:
uint16(0) == 0x5A4D and all of ($s*)
}
IoC
阶段 | 哈希 |
---|---|
Zip 文件 | cfc814a16547dd4e92607bd42d2722cc567492e88d2830d7d28a0cc20bf3950c |
Lnk 文件 | 7df7ad7b88887a06b559cd453e7b65230d0cccff1a403328a521d8753000c6c9 |
hwpx 文档 | 9d96e4816a59475768d461a71cecf20fd99215ce289ecae8c865cf45feeb8802 |
鲨鱼蝙蝠 | 5306582c8a24508b594fed478d5abaa5544389c86ba507d8ebf98c5c7edde451 |
大象档案 | 2b6928101efa6ededc7da18e7894866710c10794b8cbaf43b48c721e9731c41a |
标题.dat | 6d790df4a2c81e104db10f5e47eb663ca520a456b1305e74f18b2f20758ea4e1 |
shellcode-第 3 阶段 | 1c4cd06ebece62c796ea517bf26cc869fa71213d17e30feb0f91c8a4cfa7ef1b |
RokRat – 最终载荷 | 09a4adef9a7374616851e5e2a7d9539e1b9808e153538af94ad1d6d73a3a1232 |