XenoStealer变种借邮件附件传播,基于开源框架扩大窃密范围
-
作者:火绒安全
-
发布时间:2025-07-16
-
阅读量:5
近期,火绒安全实验室检测到一种包含附件 Purchase Order.vbe 的邮件。而这看似普通的邮件其实是一封钓鱼邮件,其中的附件本质上是一个恶意文件,一旦打开,藏在其中的恶意程序就会“苏醒”,悄悄窃取受害者的各种重要信息。这类攻击就是钓鱼攻击。
火绒工程师对邮件中的附件进行分析发现,该 VBE 文件实际是经过编码的 VBS 脚本,运行后会将注入器和下载器载荷写入注册表,并通过 Powershell 指令调用注入器,将带有反虚拟机、反沙箱机制的下载器注入至指定进程中。该下载器运行时会接收基于开源窃密项目 XenoStealer 的自定义变种窃密模块数据,而此模块不仅会窃取 Chrome,Edge 等浏览器存储的 Cookie 和密码,还会窃取聊天软件、邮箱客户端、直播软件、下载工具等各类软件的配置文件。其中,第一个 VBS 脚本和窃密模块分别利用了 Microsoft Script Encoder 和 .NET Reactor 进行混淆,从而干扰逆向分析。火绒安全产品可对上述木马进行拦截查杀,建议广大用户及时更新病毒库以提高防御能力。
查杀图
该病毒窃密模块所参考的 XenoStealer 窃密项目的开发者仓库截图如下。该开发者自 2024 年 7 月开始上传此项目的代码,其中包含浏览器 Cookies、密码、历史记录等数据的窃取代码,以及 Steam、邮箱、Telegram 等其他软件数据的窃取代码。
XenoStealer 项目开发者仓库
一、样本分析
样本执行流程图如下:
流程图
该样本前期通过 VBS 脚本和 Powershell 指令内存加载程序集,并调用其中的注入函数;随后创建傀儡进程 MSBuild.exe,以进程镂空的方式注入下载器代码;然后,在接收窃密模块后进行窃密。
其中,VBS 脚本被 Microsoft Script Encoder 混淆,可在系统解密时直接通过 dump 获取解码后的原代码;部分 C# 程序集被 .NET Reactor 混淆,可利用开源 .NET 反混淆器和解包器项目 de4dot,针对 .NET Reactor 混淆器进行部分修改,能够去除部分(字符串、代理函数调用、控制流)混淆。
在对该样本窃密能力的实际测试中,针对部分软件进行了验证,发现该窃密模块能够解析最新 Chrome 浏览器 v20 版本的加密方式。
VBS 脚本阶段
VBS 和 VBE 介绍:该样本为 .vbe 文件,这种文件源于 VBS 脚本(.vbs 文件),是通过微软早期提供的 Microsoft Script Encoder 工具对 VBS 脚本进行编码生成的弱混淆文件。编码后的文件整体结构以开头(#@~^)、长度(base64 编码)、编码后数据、校验和(base64 编码)、结尾(^#~@)组成。该文件执行时,会先进行解码,接着再执行原 VBS 脚本。
Microsoft Script Encoder 编码工具和使用方法以及前后区别
逆向分析解码原理:通过逆向分析和跟踪 wscript.exe 程序对该 .vbe 文件数据的处理过程发现,在 vbscript.dll 动态库中, ParseScriptTextCore 函数调用 MapString 函数传入参数 0 时会进行解码(参数为 1 时进行编码),从而获取到原 VBS 脚本代码。
编解码函数
Purchase Order.vbe 解码前后对比
数据写入至注册表:随后发现,该脚本会动态计算出部分字符串。对这些字符串手动解码后分析发现,该 VBS 脚本会将数据写入注册表 HKCU\Software\JpAonJmBGEONpex 中。
样本写入注册表的数据含义
检查安全软件:VBS 脚本会通过遍历以下注册表路径判断是否存在安全软件。如果不存在则会将注册表 in 写为 1(标识为无安全软件),随后直接执行调用器。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Security and Maintenance\Providers
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center\Provider\Av
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Security Center\Monitoring
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Security Center\Providers
直接执行调用器
持久化:样本会创建新的 VBS 脚本至 %APPDATA%\JpAonJmBGEONpex.vbs 路径。该脚本承担绕过安全软件执行调用器的功能。
随后,创建计划任务调用该 VBS 脚本。首先,该脚本会检查 MSBuild.exe 进程是否运行,若未检测到运行,则检查是否存在安全软件,如果存在则创建最小化窗口的 powershell 进程。然后,利用 SendKeys 向 powershell 窗口输入“执行调用器”指令,并输入 [Enter] 回车键执行命令。接着,输入 Stop-Process -Name conhost -Force 指令关闭所有控制台窗口。
创建计划任务函数调用关系图
绕过安全软件执行调用器
调用器和注入器
.NET 版本选择:VBS 脚本通过判断 C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe 文件是否存在,选择对应版本的 .NET 程序(4.8 或 3.5 版本)。
.NET 版本选择
调用器和注入器:不同版本的.NET 程序均包含两个程序,这两个程序分别作为调用器和注入器。调用器程序中 roy.roy 类中的 roy 为恶意函数,其主要目的是调用注入器中 r.r 类中的 r 函数。其中,roy 函数的参数为 JpAonJmBGEONpex,是病毒放置配置的注册表项名。注入器的注入方式为进程镂空(替换掉进程原本数据),注入时会选择 MSBuild.exe 进程注入 C# 代码。
调用器代码
注入器细节和原理:注入器会按照优先级从低到高的顺序检查以下三个路径中的文件是否存在。其中,EdgeUpdate 的优先级最高。
C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
C:\Program Files (x86)\Microsoft\EdgeUpdate\MSBuild.exe
随后,创建进程以阻塞进程 CREATE_SUSPENDED。然后进行进程镂空,利用 NtUnmapViewOfSection 取消映射原始进程数据节区的内存,之后申请内存并写入将要注入的恶意代码。该恶意代码用于解密处窃密木马下载器。
进程镂空
解密器和下载器
解密器和下载器:注入的恶意代码是一个解密器,其中含有被加密的下载器的代码。代码注入后,样本会利用 AES 算法进行解密。之后,利用 gzip 算法解压缩出窃密模块下载器。接着,调用下载器中 G0c16SfdYc8i9XXt4Q.wue4bKtj9qpQy2DwFo 类中的 jH5uD8oxm 函数。
秘钥(key):ca9cfc5d87e5784a6004600bbce5f6d051b322288a6a807a6dff8361e0735b9d
初始化向量(iv):bb654c307c5cbb0ce4336d5c65a108d3
解密解压缩
去混淆:该下载器由 .NET Reactor 进行混淆,该混淆可以利用开源项目 de4dot 并通过修改代理调用相关代码,并添加解密资源代码进行解密后,可以去掉代理函数调用的混淆。同理,也可以通过类似的方法还原字符串加密。
字符串混淆原理:.NET Reactor 会将字符串加密后存放至资源中。当需要使用该字符串时,会通过全局类下的字段值和硬编码异或获取该字符串在资源中的偏移,然后通过偏移获取字符串。
字符串去混淆原理:可以通过动态获取全局类下的字段值,利用 de4dot 中的 dnlib 对 C# 代码的支持和特征定位字符串获取函数。通过异或出字符串偏移,并从解密后的资源中提取字串符。随后,将字符串写入替换原字符串解密函数,并重新编译,从而获取去除字符串混淆。
去混淆前后对比图
下载器会通过 base64 解码和反序列化获取配置数据。配置数据包含远程服务器 IP 地址(198.135.51.90)、端口(62520)、互斥体(aMdFrsHoGcGgAKUyLCoEIuoHpvwCAzaz,后续也会用于解密数据的秘钥)、是否检测沙箱和虚拟机等数据。随后,计算 MD5 值并创建互斥体 2b6544ea00955c960336111232300c68 ,以确保只运行一个下载器进程。
创建 MD5 值互斥体
反沙箱反虚拟机:查看其中的 wcDqCGA6k0 字段值,从而选择是否检查沙箱或虚拟机。检查内容如下:
当前进程中是否存在 SbieDll.dll 和 cuckoomon.dll
检查当前父进程是否为 cmd.exe 创建
检查 Win32_BIOS 中 version 中是否存在 VMware、VIRTUAL、A M I、Xen 等字符串
检查 Win32_ComputerSystem 中 manufacturer 和 model 中是否含有 Microsoft|VMWare|Virtual 等字符串
是否存在文件 C:\Windows\System32\vmGuestLib.dll
检查屏幕分辨率是否过小
检查是否为 32 位系统
查看用户名是否为 john、anna 或是否含有 xxxxxxxx 字符串
反沙箱反虚拟机
接收窃密模块并调用入口点函数:连接远程服务器 198.135.51.90:62520 获取数据。接着,利用 DES 算法解密、Gzip 解压、反序列化等操作将接收的数据转化为窃密模块。之后,加载窃密模块。然后,调用入口点函数 YYGtqkVPfd5UkbTmqE.EhSU9UnsienGKbd9Lk 类中的 fFMLPn3SQ 入口点函数,并将序列化数据作为参数传入。
接收并解密加载调用函数
窃密模块
该窃密模块是基于开源窃密项目 XenoStealer 的自定义变种。
原项目会窃取浏览器密码和 Cookies、历史记录、OBS 中直播推流码、本地邮箱客户端存储的授权码、聊天软件配置信息(可用于跨设备登录)等数据。
而该变种在原项目的基础上,增加了一些自创内容或加入了其他开源项目中的内容。例如:获取系统详细信息、在 Chrome 浏览器中额外获取登录的 Google 账号的用户头像和 Token 以及搜索记录、更多插件和信息的收集、获取 MailBird 存储的授权码等内容。
初始化:窃密模块会先反序列化参数,从而获取远程服务器的 IP 和端口,以及其他配置数据(如要获取的文件夹路径等)。但在分析过程中,获取到的配置数据中并不包含文件夹路径。随后,利用 SetProcessDPIAware 函数防止系统自动缩放,从而提高截图时的精确度。
入口点函数反序列化
获取系统信息:通过 WMI 服务和 C# 自带的 .NET API 获取系统信息。其中,标记用户是通过用户名和其他主板信息计算 MD5 值组合实现的。此外,窃密模块还会获取当前屏幕、剪切板、杀毒软件、网关 IP 等数据,从而多方面掌握受害者信息。
获取系统信息
1.浏览器窃密
窃取浏览器数据:该窃密模块能够解析下图内多种浏览器的数据,被解析的数据包括自动填充登录账号密码、历史下载记录、访问记录、搜索记录、自动填充内容、信用卡号以及安全码(CVV)、Cookies 以及 Google 账户登录 Token。
窃取的浏览器种类
Login Data(存放密码相关的 SQLite 数据库):
支持的加密方式:支持两种加密方式,分别为 v10 和 v20。分类依据是密码存储时的开头是否为 v10 或 v20。其中,密码存储在浏览器配置文件夹中的 Login Data 数据库(SQLite)中 logins 表的 password_value 字段中。可以恢复原密码是因为浏览器本身具备解密功能,能够恢复存储在 password_value 字段中的原密码。例如谷歌浏览器在自动填充密码时,能够调用其内置的解密功能,将加密的密码还原为原密码,从而实现自动填充原密码。
v10 解密方式:从 Local State 文件(JSON)中获取 os_crypt.encrypted_key 值,之后通过 base64 解码和 CryptUnprotectData 解密获取 32 字节秘钥。随后,使用该秘钥和 AES GCM 算法,并利用 BCryptDecrypt 函数解密 password_value 字段(去掉 v10 或 v20 字符),从而获取原密码。
v20 解密方式:从 Local State 文件(JSON)中获取 os_crypt.app_bound_encrypted_key 值,通过注入代码以及被加密秘钥,调用 GoogleChromeElevationService 中的 DecryptData 函数,从而解密出 32 字节秘钥。随后,使用与 v10 解密中同样的方法进行解密,从而获取原密码。
History(历史 SQLite 数据库):以下内容均为非加密内容,且都是 SQLite 数据库表。
downloads(下载记录表):获取 tab_url(文件下载链接)和 target_path(文件下载文件路径)。
urls(访问地址表):获取 title(标题)、url(域名)、visit_count(访问次数)。
keyword_search_terms(关键词搜索表):获取 normalized_term 字段,该字段内记录着用户搜索过的历史记录。获取该表的功能是此自定义构建的 XenoStealer 窃密木马的一个创新点。
Web Data(SQLite 数据库):
AutoFill(自动填充):获取 name 与 value 字段值,分别为 HTML 中 input 标签中 name 属性和填入的数据。
信用卡相关:读取 credit_cards 表,获取 guid、name_on_card(卡名)、expiration_month(到期月份)、expiration_year(到期年份)、card_number_encrypted(被加密卡号)。其中, guid 用于从 local_stored_cvc 表获取 value_encrypted 字段,该字段为被加密的 CVV(信用卡安全码)。以上被加密数据会通过 v10 或 v20 解密方式进行解密。
NetWork\Cookies(SQLite 数据库):
获取 host_key(所属域名)、name(Cookie 名)、path(作用路径)、expires_utc(过期时间)、is_secure(HTTPS 传输)、is_httponly(限制脚本读取) 字段值,最后读取解密 encrypted_value 字段值,即 Cookie 内容。
该窃密模块与原项目相比,新增功能如下:
获取 Google 账号头像:获取配置目录(AppData\Local\Google\Chrome\User Data\Default)下的第一个 *.png 文件。测试发现,此为 Google 账号的头像。
获取 Google 账号 Token:通过读取 Preferences 文件中的匹配 "email": ".*?",获取当前登录的 Google 账号;然后,打开数据库 Web Data 中的 token_service 表,获取并解密 encrypted_token 字段值。该 token 值用于无密码登录。
2.浏览器插件窃密
该窃密模块会窃取 Chrome 浏览器下 118 个插件中的文件。首先,通过检查 Local Extension Settings 文件夹下是否存在插件 ID 文件夹(例如 mijjdbgpgbflkaooedaemnlciddmamai)来判断插件是否存在,若插件存在,则压缩打包排除 User Data\Default 文件夹下含有插件 ID 字符串的文件夹(排除特定文件夹)。其中的插件主要与加密货币、密码管理、双因素身份验证器相关。
插件列表
压缩打包插件相关文件夹
此外,针对不同浏览器(如 Edge 和 Opera 浏览器)的插件 ID 存在差异的情况,该窃密模块会进行兼容处理。例如,SafePal 插件的 ID 在 Chrome 浏览器中为 lgmpcpglpngdoalbgeoldeajfclnhafa,而在 Edge 浏览器中为 apenkfbbpmhihehmihndmmcdanacolnh。因此,窃密模块会通过判断当前浏览器名称,将两个字典合并以实现兼容。
兼容其他浏览器
而针对特定浏览器,例如 Brave 浏览器(加密货币相关),则只压缩打包 Preferences 文件,条件为文件内是否存在 encrypted_mnemonic 字符串。
Brave 浏览器
3.邮箱窃密
本地邮箱客户端软件通常通过 POP3/IMAP 协议或直接登录的方式本地管理多个邮箱账号,无需通过网页登录逐一管理,所以客户端数据库中一般会包含被加密的授权码或往来的重要邮件信息。因此,窃密模块往往会将这些客户端作为窃密目标。
FoxMail 窃密:样本首先通过注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Foxmail.url.mailto\Shell\open\command 获取 FoxMail 的安装路径。随后,遍历 Storage\[Email]\Accounts\Account.rec0 文件并进行解析,获取其中的 Account(邮箱)、Password(授权码)、IncomingServer(接收服务器)、OutgoingServer(发送服务器)字段。其中,授权码需要用硬编码秘钥和异或算法进行解密,从而获取明文授权码,利用邮箱地址和明文授权码即可实现在另一个设备进行接收邮件。
Foxmail 授权码获取
MailBird 窃密:溯源发现,该窃密模块利用了开源项目 Pillager 中的 MailBird 模块,能够获取授权码和 OAuth 登录凭证,还会将整个 Store 目录进行压缩打包。测试发现,替换 Store 目录即可直接接收邮件。
MailBird 窃取表
MailMaster 窃密:MailMaster(邮箱大师)支持登录多个邮箱。窃密模块首先会读取 app.db 数据库中 Account 表中 DataPath 字段值,该字段值为数据库存放目录。随后压缩打包该目录。观察发现,其目录下存在 mail.db 数据库,数据库的 MailMeta 表中含有邮件数据。
MailMaster 窃取表
Outlook 窃密:窃密模块会通过注册表路径列表和字段名列表进行遍历,从而窃取 Outlook 数据。其中,注册表路径为 Outlook 不同版本的数据存放路径。
如果字段名中含有 Password 且不存在 2 字符(例如 IMAP Password)时,会选用 CryptUnprotectData 函数进行解密,获取授权码。其中,传入 CryptUnprotectData 的参数为 Password 去掉首字节。
两个列表
Outlook 配置信息
4.文件传输工具窃密
FileZilla 和 WnSCP 2 是用于在本地与远程计算机间复制文件的工具,能够利用各种协议传输数据。这类工具在连接时会存储账号密码等数据,因此会成为被窃取和恶意利用的目标。
FileZilla 窃密:窃密模块会获取 ApplicationData\FileZilla 目录下的 RecentServers.xml 和 sitemanager.xml,前者是通过快速连接时的记录,后者是手动添加站点时的记录。其中包含完整的信息,例如服务器地址、服务器端口、账号密码等重要信息。
RecentServers.xml 文件
WinSCP 2 窃密:窃密模块会窃取 WinSCP 记录在注册表中的 HostName、UserName、Password 字段。其中,Password 字段值为被加密的密码,其算法利用了异或、取反、数据替换等方式。
解密算法和 WinSCP 注册表数据
5.Steam 平台窃密
窃密模块读取 HKEY_CURRENT_USER\Software\Valve\Steam 注册表路径,获取 SteamPath(安装路径)并遍历 Apps 路径下的 Name(游戏名)。随后,通过安装路径寻找 ssfn 和 vdf 文件。此外还会从 loginusers.vdf 文件中提取所有登录过的用户 ID。从这一窃密逻辑来看,其主要是通过获取受害者安装的 Steam 游戏列表等信息以评估受害者的经济价值。
获取账号和游戏列表
6.通讯软件窃密
窃密模块还会获取通讯软件数据或配置信息,如 Pidgin、Signal、Telegram、Discord 等。实测发现,在这些软件中,Telegram 的跨设备登录通过替换 Telegram 的文件数据即可实现。
Pidgin 窃密:Pidgin 是一款支持多种协议的聊天软件,当用户设置账号密码及相应协议时,相关数据会存储在 ApplicationData\.purple\accounts.xml 文件中。该文件会记录 protocol(协议)、name(账号)、password(密码,勾选保存密码时记录),且密码以明文形式存储。窃密模块通过窃取上述信息,可用于伪装账号主人进行恶意操作。
获取账号数据
Signal 窃密:窃密模块会窃取 ApplicationData\Signal 路径中的 Local State 和 config.json 文件以及 sql 文件夹。其中,Local State 和 config.json 中分别存在 encrypted_key 与 encryptedKey,推测这两个文件是用于解密 sql 文件夹中被加密的 sqlite 数据库,从而提取聊天记录或其他数据。
打包 Signal 文件
Telegram 窃密:窃密模块会通过注册表获取 Telegram 安装路径,随后通过下图中的正则表达式过滤掉低价值的文件或文件夹,将剩余内容全部使用 Zip 压缩打包。经过测试发现,替换整个 tdata 文件夹即可实现跨设备登录账号。
Telegram 过滤表
Discord 窃密:窃密模块会通过匹配 Token 的正则表达式,匹配 leveldb 目录中所有文件。如果匹配到 Token,则将 Authorization: Token 附加到 Headers 中,进而向 https://discordapp.com/api/v9/users/@me 和 https://discordapp.com/api/v9/users/@me/guilds 发起请求,以此获取受害者 Discord 个人信息与所属群组的信息。
Discord 关键操作表
获取到的 Discord 个人和群组信息
7.其他信息窃密
下载器 IDM 窃密:窃密模块会窃取 IDM 存放数据的注册表中记录的信息,包括正版用户激活所填写的明文邮箱、姓名、序列号。
读取 IDM 注册表
IDM 注册表
内网穿透 Ngrok 窃密:窃密模块窃取内网穿透工具 Ngrok 的配置文件 ngrok.yml,其中包含 authtoken、服务端口、隧道名称等信息。
ngrok.yml 读取
视频直播录制 OBS窃密:窃密模块对 AppData\Roaming\obs-studio\basic\profiles 文件夹进行压缩打包。测试发现,用户开启直播时设置的推流码会写入至该 profiles 文件夹中,这些推流码可能被恶意利用,用于实施假冒直播等恶意操作。
推流码文件
加密货币窃密:加密货币路径表如下图所示。其中列出的均为加密货币客户端在本地计算机中的配置文件或者钱包的路径。窃密模块会将这些路径加入到字典中,最后将这些文件夹或文件压缩打包后上传。
加密货币路径表
二、附录
C&C:
HASH: