本帖最后由 火绒工程师 于 2025-4-17 10:37 编辑
近期,火绒工程师在日常监测安全动态时发现,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(非)等指令进行解密,最终解密出一段代码。 解密出来的代码
该代码的主要内容如下: 第一个入口 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 手动加载并调用
通用恶意模块加载阶段 该阶段目的:获取通用恶意模块并加载该模块。 下图左右两边被加密数据需要使用不同解密:左边部分直接参与 sm4 解密,右边部分需要进行一次初步解密再进行 sm4 解密。 被加密内存
右边被加密数据初步解密:右边部分的被加密数据用以下规则解密,主要思想是:对 A-Z、a-z、0-9,以及特殊字符 "!?#$%&()*+-,/:;<>=@[\\]^`{|}~\n" 分别进行特殊处理,从而完成解密。 字符特殊处理
将两者组合起来利用 sm4 解密并调用入口点:随后将两部分被加密数据组合起来,并利用秘钥 916F0EE05D0AE457A1959EF88B32D960 进行 sm4 解密,解密出入口点代码并调用。 sm4 解密并调用入口点
获取通用恶意模块:获取通用恶意模块(该模块为病毒作者自定义的 PE 结构,文件开头为 0x58 0x53,即 XS。),样本将解析该自定义结构并进行手动加载,此时可以通过手动构造 PE 的方式,使 IDA 能够识别模块内容,从而利用 IDA 分析。 手动加载 xs 结构
通用恶意模块第一阶段 该阶段目的: 入口点基本处理:通用恶意模块入口点会进行重定位、修复 IAT、修改调用 ZwQueryInformationProcess API 地址、禁用线程通知、报错静默处理等操作。 入口点 支持异常处理:通过 Hook RtlDispatchException 函数内的 call ZwQueryInformationProcess 偏移,修改其返回值中的 ProcessExecuteFlags 标志位,将 ImageDispatchEnable 设置为真,从而支持手动映射 PE 文件时的异常处理。 异常处理支持
解密出远程服务器链接:通过类似 base64 的方式将编码数据解码,随后利用 chacha20 算法(将 64 位计数器的低 32 位初始化为 0x80)解密,接着再次通过异或解密,解密出远程服务器链接。 解密算法 解出远程服务器链接
检测杀毒软件:通过 ZwQueryDirectoryObject 遍历 \GLOBAL??,检测是否存在杀毒软件。 杀毒软件检测
伪造父进程:首先循环进程列表获取进程句柄,然后利用天堂之门 Hook NtCreateUserProcess 函数,即调用 NtCreateUserProcess 函数的前一刻,设置新进程的父进程属性为任意其他进程句柄,从而完成伪造父进程。 下图是天堂之门 Hook NtCreateUserProcess 的调用入口截图,再下一个图是设置新进程的父进程属性为任意其他进程句柄的代码截图。 天堂之门入口 Hook NtCreateUserProcess
创建傀儡进程:创建进程时将 dwCreationFlags 设置为 CREATE_SUSPENDED | CREATE_NO_WINDOW 从而进行阻塞和无窗口处理。 创建傀儡进程
再一次将通用恶意模块注入至傀儡进程:通过文件数据表获取 early.x64(注入模块),随后手动加载并利用天堂之门调用该注入模块,将通用恶意模块(与上面通用恶意模块入口点不同)注入至傀儡进程中。 注入 两个入口点
通用恶意模块第二阶段 最终目的: Hook EtwEventWrite 函数。 反沙箱、反调试、反虚拟机、检测分析环境等。 下载窃密模块将其注入至傀儡进程。
Hook EtwEventWrite:通过文件数据表获取 unhook.bin,利用天堂之门执行,将 EtwEventWrite 设置为空,从而使函数失效。 Hook EtwEventWrite
加载 strategy.x86 进行反沙箱:通过文件数据表获取 strategy.x86,手动加载后调用入口点,以下是入口点。 入口点
以下是入口点内执行的函数细节,分别是: 测试 COM 组件是否能运行,从而检测沙箱(因有些沙箱模拟并不全面)。 检测指定程序是否正在运行,从而规避分析环境。 通过判断屏幕是否小于 800x600,检测虚拟机或沙箱。 通过获取屏幕壁纸与 triage 沙箱壁纸进行 sha1 对比,从而判断是否在 triage 沙箱中。 通过桌面上是否有异常的文件数量,异常的文件大小、异常的软件数量来判断是否在沙箱中。 通过检测用户名和 DNS 名是否与沙箱用户名一致,从而检测沙箱。 通过判断桌面上的 password 文件是否存在异常情况,从而检测沙箱。
strategy.x86 反沙箱具体代码
下图是将会进行检测的进程名。(通过文件数据表获取 processes.x) 进程名
以下是 triage 沙箱壁纸图。 triage 沙箱壁纸
获取 User-Agent:通过文件数据表获取 ua.txt,用于与远程服务器通信。 ua.txt
加载 dt.x86 进行反沙箱反调试反虚拟机:通过文件数据表获取 dt.x86,其中使用了 al-khaser 开源项目中的反沙箱、反调试、反虚拟机等功能。 dt.x86 入口
下图是部分代码截图。 反调试、反沙箱、反虚拟机
下载窃密模块并注入至傀儡进程:将解密出的远程服务器与 User-Agent 当做参数传递至 netclient.x86(通信模块)下载窃密模块,随后将窃密模块复制到共享内存中,利用 NtDuplicateObject 复制共享内存句柄并将其注入至傀儡进程中,通过该句柄读取并执行窃密模块。 netclient.x86 调用传参
自解密:进入 netclient.x86 模块时,首先利用 proto.x86 加解密模块进行加密,从而使入口点以及整个 9D0000 堆被加密,结束后再次利用proto.x86 加解密模块进行解密。 proto.x86 模块
下图是利用异或加密之后的调用 netclient.x86 的入口点和异或算法。 异或算法
窃密阶段 总共可以分为三个模式: 常规窃密:获取系统信息、Chrome、Steam 等软件信息。 Lua 窃密:利用 Lua 脚本,通过 Lua 解释器解释执行,窃取钱包、SSH 客户端、邮件、V*N 等软件中信息。 C# 窃密:通过开源项目 KeePassHax 窃取 KeePass 数据。
常规窃密 下图是获取时区、Windows 版本信息、用户名、工作组名称、用户帐户控制相关、屏幕壁纸哈希、内存大小、CPU 信息等数据的截图。 样本还会收集设备唯一标识(MachineGuid)、Windows 产品密钥(BackupProductKeyDefaul)、分辨率、显示器描述(DeviceString)、计算机名、安装软件列表、进程列表等数据。 收集系统信息
此外,样本会收集 Chrome、Edge、Steam、IE、Firefox、OpenV*N、WinSCP、Telegram、Simple Sticky Notes、CoreFTP、TeamViewer 软件信息。 下图是窃取 Chrome 和 Edge 浏览器 和 Steam 平台中文件代码截图: Chrome、Edge、Steam 文件窃取
Lua 窃密 样本会循环读取名称为 00000001.xs 至 000000041.xs 的Lua 脚本,并利用 Lua 解释器进行解释执行,同时窃取钱包、SSH 客户端、邮件、V*N 等软件中的信息,最后利用 MessagePack 序列化数据并发送至远程服务器。 加密货币钱包窃取:扫描 %AppData%\<钱包名>\ 等目录,窃取 Armory、Blockstream Green、Electrum、Exodus、Monero、Litecoin、Qtum 等钱包软件中的配置文件,下图是 Armory 钱包的窃取脚本。 Armory 钱包窃取脚本
FTP/SSH 客户端窃取:窃取 PuTTY、CuteFTP、FlashFXP、SmartFTP、Total Commander 等 FTP/SSH 客户端秘钥信息,下图是 PuTTY 客户端相关秘钥的窃取脚本。 PuTTY 客户端相关秘钥窃取脚本
邮件与通讯软件窃取:窃取 Outlook、The Bat!、eM Client、Pidgin 等软件秘钥信息,下图是 Outlook 秘钥信息的窃取脚本。 Outlook 秘钥信息窃取脚本
V*N 配置窃取:窃取 NordV*N、ProtonV*N、Windscribe、AzireV*N 等 V*N 配置,下图是 NordV*N 配置文件的窃取脚本。 NordV*N 配置文件窃取脚本
C# 窃密 该 C# 模块通过文件数据表获取 /bin/KeePassHax.dll 得到,该模块为开源项目 KeePassHax 编译后的动态库。 通过注入至 KeePass 进程中逐步获取 m_formMain、m_docMgr、m_dsActive、m_pwDb 等字段以获取秘钥数据,随后发送至远程服务器。 KeePassHax
二、附录 C&C:
HASH:
讲点大白话: 有的小伙伴表示没有学过计算机知识,看不太懂这篇文章,那么你可以参考如下说明。
简单来说,Rhadamanthys 窃密木马就是一个数字小偷,专门偷你房子里重要的东西,他会乔装打扮成普通人,进入你的家中实施盗窃。这个小偷非常狡猾,偷盗时会先踩点,随后进入你房子里的各个房间,开始翻箱倒柜,接着撬开你存放重要宝物的箱子,盗走你的宝物,事件发生后,你却很难追踪到他的具体行踪。而火绒则像是带有监控作用的锁,可以有效监测到这个小偷,将他拦截在门外! “房子”就像你的电脑,“普通人”是普通程序,“踩点”是检测沙箱、虚拟机、调试工具,判断是否处于分析环境,“具体行踪”指全程均在内存中完成,无文件落地。不过,别担心,目前火绒已练就“火眼金睛”,可对该窃密木马进行有效拦截和查杀,建议您及时更新病毒库,给家里的大门及时加固哦~
|