SSLoad 是一种隐秘的恶意软件,主要通过钓鱼邮件打开突破口,收集各种信息再回传给攻击者。近期,研究人员发现 SSLoad 通过诱饵 Word 文档投递恶意 DLL 文件,最终部署 Cobalt Strike。另一种攻击方式是利用钓鱼邮件诱导受害者到 Azure 页面,通过 JavaScript 脚本下载 MSI 安装程序再加载 SSLoad 其他载荷。
SSLoad 是新型恶意软件,研究人员发现了许多变种。在恶意软件即服务(MaaS)领域,该恶意软件通过多样化的交付方式彰显自身的技术水平。
MSI 安装程序
由此安装程序开启多个 Loader 组成的攻击链,最终部署攻击者期望的 Payload。
攻击链
通过分析工具,可以发现安装程序要执行哪些操作:
❯ msiinfo export 90f1511223698f33a086337a6875db3b5d6fbcce06f3195cdd6a8efa90091750.sample CustomAction
[...]
SET_APPDIR 307 APPDIR [AppDataFolder][Manufacturer]\[ProductName]
LaunchFile 1026 viewer.exe C:\Windows\System32\regsvr32.exe /S [LocalAppDataFolder]sharepoint\MenuEx.dll
PhantomLoader
最初的 Loader 是 C/C++ 编写的 32 位 DLL 文件,该 Loader 通过二进制修补文件并采用自修改技术来逃避检测,加载程序被添加到合法的 DLL 中。
根据文件的元数据来看,PhantomLoader 试图将自己伪装成名为 MenuEx.dll(360 杀软引擎依赖的 DLL 文件)的合法 DLL 文件。该文件的 PDB 路径为 C:\vmagent_new\bin\joblist\500965\out\Release\MenuEx.pdb
,该加载程序还与反病毒软件共享部分代码并保留了数字签名的痕迹。
代码重用
文件元数据
Payload 被加密存在资源段中,熵值较大:
文件结构
Phantom Loader 首先解密再从资源段中提取 Payload,.text
段具有可读可写可执行权限。该 Loader 是自修改的,攻击者需要这种权限也是理所应当的。
样本文件将指定地址的加密代码的每个字节与预定义加密密钥的相应字节进行异或操作,如果代码超过密钥长度,密钥会被重复使用。异或加密的密钥如下所示:
71 21 2a 43 74 52 4f 42 65 6a 6c 6-4 57 46 37 45 33 40 31 4c 69 79 55 53 00
根据加密的逻辑反解的 IDA Python 脚本如下所示:
import ida_bytes
import ida_auto
def decode_code(start_addr, length, key_hex):
# Convert the hex key string into a byte array
key_bytes = bytearray.fromhex(key_hex)
# Read the current encrypted data from the IDB
encrypted_data = ida_bytes.get_bytes(start_addr, length)
# Create a bytearray for the encrypted data to perform mutable operations
encrypted_data = bytearray(encrypted_data)
key_length = len(key_bytes)
# Perform the XOR decryption
for i in range(length):
encrypted_data[i] ^= key_bytes[i % key_length]
# Write the decrypted data back to the IDB
# Convert bytearray back to bytes since patch_bytes expects a 'bytes' type
ida_bytes.patch_bytes(start_addr, bytes(encrypted_data))
# Optionally, inform IDA to reanalyze modified areas to reflect changes in disassembly
ida_auto.auto_make_code(start_addr)
ida_auto.auto_wait()
# Constants
encryption_key_hex = "71212a4374524f42656a6c6-4574637453340314c6979555300" # The decryption key in hex
code_region_length = 0x76C # Length of the code region
start_address = 0x1000AF77 # Starting address of the encrypted code
# Decode the encrypted code region
decode_code(start_address, code_region_length, encryption_key_hex)
print("Decryption complete. The code region has been updated."
解密后 EIP 会指向第一条指令,再使用相同的密钥进行异或解密,从资源段中提取 Payload。提取得到 Payload 后再加载执行,这又是另一个 Loader。
资源段
相似诱饵文档的攻击中,使用了另一版本的 Loader。这个 Loader 处理逻辑类似,但异或的密钥不同。
25 5e 47 51 4d 4a 42 44 77 42 6-4 58 4c 41 46 57 75 28 21 46 61 67 32 24 34 46 47 00
恶意 DLL 文件
Phantom Loader 的第二阶段是一个用 C/C++ 编写的小型、简单的 32 位 DLL 文件,攻击者利用其加载 Payload 并执行 DllRegisterServer 函数。
入口点函数
SSLoad
SSLoad 是使用 Rust 编写的 32 位 DLL 文件,字符串都使用了独特的方式进行加密。样本文件首先解密 URL 与 User-Agent,URL 指向 Telegram 频道。频道中的另一个加密字符串,则是最终 Payload 的 C&C 服务器。
分析样本的 URL 与 User-Agent 如下所示:
https://t[.]me/+st2YadnCIU1iNmQy
Mozilla/5.0 (Windows NT 10.0; Win6-4; x6-4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Telegram 频道
解密获得 C&C 地址后,SSLoad 解密另一个 User-Agent 为 SSLoad/1.1。再向 http://C&C/api/g 发出 GET 请求,下载后续 Payload。
字符串解密
SSLoad 使用 RC4 算法对数据进行加密,只不过每个字符串都使用独特的密钥进行加密,密钥和加密字符串存放在一起。以某个字符串为例来解释解密算法,如下数据包含加密字符串与 RC4 密钥:
uTjvTPJayj/5Af1pr+qBtvkwh9KKDV2mKF0C+7lBoOJHnmLwZJzKE
转换为十六进制为:
75 54 6A 76 54 50 4A 61 79 6A 2F 35 41 66 31 70 72 2B 71 42 74 76 6B 77 68 39 4B 4B 44 56 32 6D 4B 46 30 43 2B 37 6C 42 6F 4F 4A 48 6E 6D 4C 77 5A 4A 7A 4B 45
每个字符串的解密密钥由编码字符串的前 6 个字节与后 7 个字节连接而成,上述的密钥为:
75 54 6A 76 54 50 4C 77 5A 4A 7A 4B 45
其余部分由自定义函数处理,函数使用以下逻辑计算加密字符串的长度:
scaled_length = (length >> 2)
if (length & 3) == 1:
scaled_length -= 1
scaled_length *= 3
本质上讲,加密字符串从数据的第 7 个字节开始,scaled_length 的值决定其长度。 该恶意软件使用 base6-4 编码,示例样本文件中 scaled_length 为 30(0x1E)。
base6-4 解码
然后使用 RC4 算法与之前得到的密钥对 base6-4 解码后的 Payload 进行解密,获取 Telegram 频道 URL 地址。
RC4 解密
最终载荷
获取得到另一个 Rust 文件,首先使用硬编码字符串创建互斥量,检查失陷主机是否为重复感染。
互斥量
SSLoad 检查 PEB 查看是否设置了 BeingDebugged 进行反调试:
反调试技术
紧接着动态定位内存中的 Advapi32.dll,使用多重算术运算来导出异或密钥。该密钥用于动态解密字符串,解密的每个字符串都有一组唯一对应的算术运算与输入,每个字符串也都有唯一的异或密钥。
部分代码
Advapi32.dll 调用函数 RtlGenRandom 生成随机数命名文件夹,文件夹都位于 AppData\Roaming\Microsoft 之下:
创建文件夹
类似的,恶意软件也通过哈希来解析函数,循环遍历匹配模块的函数,根据哈希找到相应的函数地址。再将这些针存储为局部变量,以便在适当的时候调用。攻击者在 winhttp.dll 模块中常用该技术,以逃避检测分析。
检索函数
DLL 文件进行指纹识别,整合成 JSON 对象回传 C&C 服务器。
支持字段
回传信息
JSON 信息通过 HTTP POST 请求回传给 C&C 服务器。上线成功后,C&C 服务器会将密钥和 ID 返回给受害者,密钥通常是 base6-4 编码的,后续用于 RC4 加密。而 ID 是失陷主机的唯一标识,主要用于标识自身。后续失陷主机向 C&C 服务器发送 POST 请求,并且使用 ID 作为 URL 路径。
POST /api/[unique_identifier]/tasks
如果有下发的任务,攻击者会下发 JSON 结构数据,其中包含任务与任务的 ID。任务是经过 RC4 加密的,再使用 base6-4 编码。任务主要包含命令与参数两部分,分析人员只发现了 exe 命令,参数是用于下载后续 Payload 的 URL。攻击者通过这种方法实现更好的可扩展性,便于支持更多命令。
结论
SSLoad 十分复杂,在收集数据、检测逃避等多种方面都展现了不俗的实力。攻击者基于 Rust 开发了多个恶意软件,也使用了极为复杂的加密措施与反调试措施。
IOC
90f1511223698f33a086337a6875db3b5d6fbcce06f3195cdd6a8efa90091750
09ffc4188bf11bf059b616-491fcb8a09a474901581f46ec7f2c350fbda4e1e1c
73774861d946d62c2105fef4718683796cb77de7ed42edaec7affcee5eb0a0ee
6aa3daefee979a0efbd30de15a1fc7c0d05a6e8e3f439d5af3982878c3901a1c
265514c8b91b96062fd2960d52ee09d67ea081c56ebadd7a8661f479124133e9
6329244cfb3480eae11070f1aa880bff2fd52b374e12ac37f1eacb6379c72b80
https://t[.]me/+st2YadnCIU1iNmQy
85.239.53[.]219