信息盗取的隐性威胁:Rhadamanthys木马无痕窃密

近期,火绒工程师在日常监测安全动态时发现,Rhadamanthys 窃密木马家族包含多种模块。这些模块采用自定义的 PE 结构,与正常的 PE 结构相似,因此需要手动构造 PE 文件进行分析。进一步分析表明,该样本会通过天堂之门注入到伪造父进程创建的傀儡进程中,随后进行杀软检测和反沙箱操作,且整个处理过程均在内存中完成,无文件落地。最终,该木马会下载窃密模块,窃密模块会窃取 Steam 登录验证文件和 Chrome 浏览器数据库文件。此外,它还会利用 Lua 脚本和 C# 动态库窃取加密货币钱包及密码管理软件中的秘钥等敏感数据。目前,火绒安全产品已能够对该窃密木马进行有效拦截和查杀,建议广大用户及时更新病毒库,以防范潜在安全风险。

 

 

 

该样本基于AeroAdmin.exe(远程桌面控制软件),通过篡改其___strncnt 函数的内容,实现伪装。

 

原 AeroAdmin 官网

因原文件被篡改,导致恶意文件的数字签名失效。

 

原文件与恶意文件区别(右边为恶意文件)

 

___strncnt 函数对比(右边为恶意文件)

一、样本分析

该样本在前期通过反复解密和手动加载实现代码执行,期间会进行杀软检测并获取远程服务器 URL。随后,样本伪造父进程创建傀儡进程进行注入,此时进入中期阶段,即通用恶意模块的第二阶段。(此阶段模块包含多种功能,最终目的是下载并执行窃密模块。)

在中期阶段,样本会执行一系列对抗操作,例如反沙箱、反虚拟机和反调试等。之后,样本下载窃密模块,并再次利用伪造父进程创建傀儡进程进行注入,从而进入窃密阶段。

在窃密阶段,样本会获取系统信息和其他软件数据。此外,它还会利用 Lua 和 C# 获取加密货币钱包和密码管理软件中的重要数据,如钱包信息和密码,并将这些数据发送至远程服务器。

此外,该样本在内存中维护了一张文件数据表。样本通过传递文件名来定位数据地址,并返回文件数据地址和文件大小,涉及的具体文件名如下。

  • early.x64:注入模块。

  • unhook.bin:使 EtwEventWrite 函数失效。

  • strategy.x86:反沙箱及检测分析环境。

  • processes.x:需要检测的进程名列表。

  • ua.txt:User-Agent 列表,用于与服务器通信。

  • dt.x86:开源项目 al-khaser(具有反沙箱反调试反虚拟机等功能)。

  • proto.x86:加解密指定区域代码。

  • netclient.x86:通信模块,会利用该模块下载窃密模块,与服务器通信。

  • /bin/KeePassHax.dll:开源项目 KeePassHax(窃取 KeePass 中的秘钥信息)。

 

初始阶段

该阶段目的:获取 rh_0.9.0.exe 并调用(rh_0.9.0.exe 是通用恶意模块加载器)。

使沙箱超时:通过执行三次无意义的计算耗费时间,从而导致沙箱模拟超时。

分配内存:通过地址 0x54C956(GetModuleHandle)、0x54D20A(GetProcAddress)、0x54D8F4(VirtualAlloc),获取函数地址并执行 VirtualAlloc 函数分配 0x6DE04 大小的 PAGE_EXECUTE_READWRITE(可读可写可执行)权限的内存,用于存储区段 .reloc 中的汇编代码(前半段为解密循环,后半段为被加密代码)。

解密:解密循环中使用 xor(异或)、sub(减法)、not(非)等指令进行解密,最终解密出一段代码。

该代码的主要内容如下:

  • 通过哈希获取 kernel32.dll 基址和若干函数地址。

  • 将数据(些许函数地址和地址偏移)写入 PEB + 0xF00 地址内,以便后续读取或调用。

  • 创建线程,执行下一段代码。

手动加载并调用入口点:通过自定义 PE 结构提取入口点偏移、模块名哈希、函数名哈希、重定位偏移等数据进行手动加载并调用入口点函数。

解密解压缩出 rh_0.9.0.exe:进行提取和异或解密,随后利用 RtlDecompressBuffer 函数进行解压缩,可以发现文件名为 rh_0.9.0.exe,且文件大小有 0x7BA00。

手动加载并调用:随后进行导入表修复、IAT 修复、重定位、TLS 回调、设置区段内存权限等操作进行手动加载,接着创建阻塞线程、修改线程入口、恢复线程等方式调用 rh_0.9.0.exe。

通用恶意模块加载阶段

该阶段目的:获取通用恶意模块并加载该模块。

正常代码中包含恶意代码:rh_0.9.0.exe 是一个以 https://github.com/libfann/fann/blob/master/examples/xor_test.c 为主要代码编译的文件,其中掺杂了恶意代码。

下图左右两边被加密数据需要使用不同解密:左边部分直接参与 sm4 解密,右边部分需要进行一次初步解密再进行 sm4 解密。

 

右边被加密数据初步解密:右边部分的被加密数据用以下规则解密,主要思想是:对 A-Z、a-z、0-9,以及特殊字符 “!?#$%&()*+-,/:;<>=@[\\]^`{|}~\n” 分别进行特殊处理,从而完成解密。

将两者组合起来利用 sm4 解密并调用入口点:随后将两部分被加密数据组合起来,并利用秘钥916F0EE05D0AE457A1959EF88B32D960 进行 sm4 解密,解密出入口点代码并调用。

获取通用恶意模块:获取通用恶意模块(该模块为病毒作者自定义的 PE 结构,文件开头为 0x58 0x53,即 XS。),样本将解析该自定义结构并进行手动加载,此时可以通过手动构造 PE 的方式,使 IDA 能够识别模块内容,从而利用 IDA 分析。

通用恶意模块第一阶段

该阶段目的:

  • 解密出远程服务器 URL。

  • 检测杀毒软件。

  • 伪装父进程创建傀儡进程(例如 svchost.exe)并注入。

入口点基本处理:通用恶意模块入口点会进行重定位、修复 IAT、修改调用 ZwQueryInformationProcess API 地址、禁用线程通知、报错静默处理等操作。

支持异常处理:通过 Hook RtlDispatchException 函数内的 call ZwQueryInformationProcess 偏移,修改其返回值中的 ProcessExecuteFlags 标志位,将 ImageDispatchEnable 设置为真,从而支持手动映射 PE 文件时的异常处理。

解密出远程服务器链接:通过类似 base64 的方式将编码数据解码,随后利用 chacha20 算法(将 64 位计数器的低 32 位初始化为 0x80)解密,接着再次通过异或解密,解密出远程服务器链接。

检测杀毒软件:通过 ZwQueryDirectoryObject 遍历 \GLOBAL??,检测是否存在杀毒软件。

伪造父进程:首先循环进程列表获取进程句柄,然后利用天堂之门 Hook NtCreateUserProcess 函数,即调用 NtCreateUserProcess 函数的前一刻,设置新进程的父进程属性为任意其他进程句柄,从而完成伪造父进程。

 

 

创建傀儡进程:创建进程时将 dwCreationFlags 设置为 CREATE_SUSPENDED | CREATE_NO_WINDOW 从而进行阻塞和无窗口处理。

再一次将通用恶意模块注入至傀儡进程:通过文件数据表获取 early.x64(注入模块),随后手动加载并利用天堂之门调用该注入模块,将通用恶意模块(与上面通用恶意模块入口点不同)注入至傀儡进程中。

通用恶意模块第二阶段

最终目的:

  • Hook EtwEventWrite 函数。

  • 反沙箱、反调试、反虚拟机、检测分析环境等。

  • 下载窃密模块将其注入至傀儡进程。

Hook EtwEventWrite:通过文件数据表获取 unhook.bin,利用天堂之门执行,将 EtwEventWrite 设置为空,从而使函数失效。

加载 strategy.x86 进行反沙箱:通过文件数据表获取 strategy.x86,手动加载后调用入口点,以下是入口点。

以下是入口点内执行的函数细节,分别是:

  • 测试 COM 组件是否能运行,从而检测沙箱(因有些沙箱模拟并不全面)。

  • 检测指定程序是否正在运行,从而规避分析环境。

  • 通过判断屏幕是否小于 800×600,检测虚拟机或沙箱。

  • 通过获取屏幕壁纸与 triage 沙箱壁纸进行 sha1 对比,从而判断是否在 triage 沙箱中。

  • 通过桌面上是否有异常的文件数量,异常的文件大小、异常的软件数量来判断是否在沙箱中。

  • 通过检测用户名和 DNS 名是否与沙箱用户名一致,从而检测沙箱。

  • 通过判断桌面上的 password 文件是否存在异常情况,从而检测沙箱。

下载窃密模块并注入至傀儡进程:将解密出的远程服务器与 User-Agent 当做参数传递至 netclient.x86(通信模块)下载窃密模块,随后将窃密模块复制到共享内存中,利用 NtDuplicateObject 复制共享内存句柄并将其注入至傀儡进程中,通过该句柄读取并执行窃密模块。

自解密:进入 netclient.x86 模块时,首先利用 proto.x86 加解密模块进行加密,从而使入口点以及整个 9D0000 堆被加密,结束后再次利用proto.x86 加解密模块进行解密。

窃密阶段

总共可以分为三个模式:

常规窃密:获取系统信息、Chrome、Steam 等软件信息。

Lua 窃密:利用 Lua 脚本,通过 Lua 解释器解释执行,窃取钱包、SSH 客户端、邮件、V*N 等软件中信息。

C# 窃密:通过开源项目 KeePassHax 窃取 KeePass 数据。

常规窃密

样本还会收集设备唯一标识(MachineGuid)、Windows 产品密钥(BackupProductKeyDefaul)、分辨率、显示器描述(DeviceString)、计算机名、安装软件列表、进程列表等数据。

此外,样本会收集 Chrome、Edge、Steam、IE、Firefox、OpenV*N、WinSCP、Telegram、Simple Sticky Notes、CoreFTP、TeamViewer 软件信息。

下图是窃取 Chrome 和 Edge 浏览器 和 Steam 平台中文件代码截图:

  • 窃取浏览器文件中的 .ldb 和.log 等数据库文件。

  • 窃取 Steam 平台文件中的 .vdf 文件和 SSFN 登录验证文件进行无密码登录。

Lua 窃密

样本会循环读取名称为 00000001.xs 至 000000041.xs 的Lua 脚本,并利用 Lua 解释器进行解释执行,同时窃取钱包、SSH 客户端、邮件、V*N 等软件中的信息,最后利用 MessagePack 序列化数据并发送至远程服务器。

加密货币钱包窃取:扫描 %AppData%\<钱包名>\ 等目录,窃取 Armory、Blockstream Green、Electrum、Exodus、Monero、Litecoin、Qtum 等钱包软件中的配置文件,下图是 Armory 钱包的窃取脚本。

FTP/SSH 客户端窃取:窃取 PuTTY、CuteFTP、FlashFXP、SmartFTP、Total Commander 等 FTP/SSH 客户端秘钥信息,下图是 PuTTY 客户端相关秘钥的窃取脚本。

邮件与通讯软件窃取:窃取 Outlook、The Bat!、eM Client、Pidgin 等软件秘钥信息,下图是 Outlook 秘钥信息的窃取脚本。

V*N 配置窃取:窃取 NordV*N、ProtonV*N、Windscribe、AzireV*N 等 V*N 配置,下图是 NordV*N 配置文件的窃取脚本。

C# 窃密

该 C# 模块通过文件数据表获取 /bin/KeePassHax.dll 得到,该模块为开源项目 KeePassHax 编译后的动态库。

通过注入至 KeePass 进程中逐步获取 m_formMain、m_docMgr、m_dsActive、m_pwDb 等字段以获取秘钥数据,随后发送至远程服务器。

新闻资讯

NEWS

首页    新闻咨询    信息盗取的隐性威胁:Rhadamanthys木马无痕窃密