银狐(Silver Fox)木马 Loader 变种静态分析报告(一)
分析对象:Install_098k.exe
本样本来源:https://www.52pojie.cn/thread-2118861-1-1.html 原帖里已经给了一些相关的行为了,这里只是研究学习,目前只是分析了这个exe本体,它释放的载荷以及载荷中自带的dll的相关行为还没有分析完,后续还会继续更新
分析方式:纯静态分析(IDA Pro 反汇编/反编译 + pefile 解析),全程未运行样本
家族:银狐 / Silver Fox 木马变种(Loader / Dropper)
摘要
Install_098k.exe 是一个典型的银狐(Silver Fox)家族 Loader 变种。程序体积 351 KB,但实际代码量极小(约 13 KB),约 95% 的文件体积是附加在 overlay 中的加密载荷。样本采用「配置驱动」的执行模型:
- 启动后把自己完整读入内存;
- 从文件尾部 overlay 中解析内嵌配置(
_]P[ 标记 + 证书表定位边界);
- 按配置决定是否执行反虚拟机 / 反沙箱检测、是否自复制到
%TEMP% 二次启动;
- 用 XTEA 解密出下一阶段载荷 —— 一个 PE 反射加载器 shellcode;
- 借
EnumSystemLocalesA 回调机制在内存中执行 shellcode;
- shellcode 反射加载内嵌的木马核心 DLL 「登录模块.dll」(约 320 KB,功能完整的后门核心)。
样本同时具备:单字节 XOR 字符串混淆、完全手写的 PEB 遍历 + 导出表动态 API 解析、13 项反虚拟机检测、7 组反沙箱条件、自复制 + 自删除、假报错弹窗等典型银狐特征。
1. 样本信息与 IoC
| 项目 |
值 |
| 文件名 |
Install_098k.exe |
| 文件大小 |
351,806 字节(0x55F3E) |
| 类型 |
银狐(Silver Fox)家族 Loader / Dropper |
| 架构 |
AMD64,PE32+(Magic = 0x20B) |
| MD5 |
2355241846B80ACB46365901F222CBBE |
| SHA1 |
7782F303BBCE540924F0017E6FE976DD7E362072 |
| SHA256 |
13318172D6B2C13BA9846338B3C030991C9EE5DA6FA398CAE73DFD5D9142C286 |
| 编译时间戳 |
0x6A6197D0 = 2026-07-23 04:25:52 UTC(注意恶意样本常伪造时间戳,仅作参考) |
| 编译工具链 |
MSVC / Visual Studio 2022 17.14(Linker 14.44) |
衍生 IoC(解密后的下一阶段产物,均为静态提取):
| 产物 |
说明 |
MD5 / SHA256 |
| 解密后 shellcode |
XTEA 解密,PE 反射加载器 |
77EC4A38ED9EDFF097E1E68E9CD309C0 / 3EFB753257A9908796E5849C33FB2E9D2BDA1BE26384F62D90FA9C4487F06C5A |
| 内嵌 DLL |
「登录模块.dll」木马核心 |
1D098FBA1D445A0D711B47430820B9EB / B0DA2419D06C6867A13972B1318FF5C777C24B0CB0F80D703DD38CC71F97A96F |
2. 编译特征与加壳判断
| 项目 |
值 |
| Machine / Magic |
0x8664(AMD64)/ 0x20B(PE32+) |
| e_lfanew / OEP |
0xD8 / 0x10F0(即 start) |
| ImageBase |
0x140000000 |
| SectionAlignment / FileAlignment |
0x1000 / 0x200 |
| Subsystem |
2(Windows GUI) |
| DllCharacteristics |
0x8160 = HIGH_ENTROPY_VA + DYNAMIC_BASE(ASLR) + NX_COMPAT(DEP) |
| 导入表 |
仅 3 个:KERNEL32.dll → { GetProcessHeap, HeapAlloc, HeapFree } |
节区(含熵):
| 节区 |
VA |
VSize |
RawSize |
权限 |
熵 |
.text |
0x1000 |
0x3383 |
0x3400 |
R-X |
6.392 |
.rdata |
0x5000 |
0xAD8 |
0xC00 |
R-- |
4.923 |
.data |
0x6000 |
— |
0(空) |
RW- |
— |
.pdata |
0x7000 |
— |
0x200 |
R-- |
2.774 |
.rsrc |
0x8000 |
0x1E0 |
0x200 |
R-- |
5.083 |
关键判断:
.text 熵 ≈ 6.39,处于正常代码区间 → 未加壳,为 MSVC 直接编译的原生二进制。
- Rich Header(手工解码)产品 ID
0x0101–0x0104、build 35227,对应 VS2022 17.14 工具链;调试目录含 Type=13(IMAGE_DEBUG_TYPE_VC_FEATURE)条目 → 进一步佐证 MSVC 构建。
- 导入表只留 3 个堆函数,是刻意为之 —— 其余 API 全部运行时动态解析(见 §4)。
- 没有
.reloc 节却声明了 ASLR → 重定位被有意剔除,程序固定加载到 0x140000000。
- 无导出、无版本信息、无图标,资源仅 1 个
RT_MANIFEST —— 恶意样本常规做法。
3. 字符串混淆:单字节 XOR 0x13
所有敏感字符串(API 名、注册表键、路径、进程名、用户名黑名单)在 .rdata 中以 XOR 0x13 加密存储,运行时解密到堆上再使用。
- 密钥:
xmmword_140005660 = 0x13 × 16(解密代码常直接 _mm_xor_ps / _mm_load_si128 一次处理 16 字节)。
部分解码示例:
| 加密存储 |
明文 |
_|rw_zqarajR |
LoadLibraryA |
PavrgvG{avrw |
CreateThread |
Ezagfr\x7fR\x7f\x7f|p |
VirtualAlloc |
Ezagfr\x7fCagvpg |
VirtualProtect |
xmmword_1400054C8 |
GetModuleFileNameW |
xmmword_1400050B0 |
EnumSystemLocalesA |
ZWvqfttvaCavv}g |
IsDebuggerPresent |
gCa|pv`` !Uzag|Process32FirstW` |
4. 完全手写的动态 API 解析(对抗 API Hook)
程序完全不依赖 IAT(导入表仅 3 个堆函数),所有 API 都通过自实现的 Get_Module_Handle / Get_Proc_Address 解析:
Get_Module_Handle(0x140002C20)— 手写 PEB 遍历
- 遍历
PEB → Ldr → InMemoryOrderModuleList 双向链表,大小写不敏感比较模块基名,绕过 GetModuleHandleA 的 Hook。
Get_Proc_Address(0x1400026A0)— 手写 PE 导出表解析
- 校验
MZ / PE\0\0 签名,按 SizeOfOptionalHeader == 0x20B 判断 PE32+,定位导出目录;
- 遍历
AddressOfNames → AddressOfNameOrdinals → AddressOfFunctions 取函数地址;
- 支持转发函数(forwarder)递归解析(如
KERNEL32.Sleep),递归深度上限 4 层。
这套「PEB 遍历 + 导出表手写解析 + 转发递归」是银狐对抗 API 监控/挂钩的典型手法。
5. 反分析技术
5.1 反虚拟机:IsVirtualMachinePresent(0x140003920)— 13 项检测
任一命中即判定为虚拟机:
- 注册表(3 条):
SOFTWARE\VMware, Inc.\VMware Tools、SOFTWARE\Oracle\VirtualBox Guest Additions、SOFTWARE\Microsoft\Virtual Machine\Guest\DetectedComponents
- 文件/设备(6 条):
\\.\vmci、\\.\HGFS、\\.\VBoxMiniRdrDN、vmmouse.sys、vmhgfs.sys、VBoxGuest.sys
- 进程(4 条):
vmtoolsd.exe、vmwaretray.exe、vboxservice.exe、vboxtray.exe
5.2 反沙箱:IsSandboxEnvironment(0x140002E20)— 7 组条件
所有条件必须全部满足才算“非沙箱”,任一不满足立即退出:
| 检查 |
判定条件 |
| 反调试 |
!IsDebuggerPresent() |
| 分辨率 |
GetSystemMetrics(SM_CXSCREEN) >= 800 |
| CPU |
处理器数 ≥ 2 |
| 运行时长 |
GetTickCount() >= 300000ms(5 分钟) |
| 内存 |
总物理内存 ≥ 2 GB |
| 进程数 |
当前进程数 ≥ 10 |
| 用户名 |
不在黑名单内 |
用户名黑名单(6 个,大小写不敏感):sandbox、malware、virus、sample、analysis、analyst
6. 内嵌配置解析(Overlay)
6.1 定位方式
start() 把自身读入内存后:
- 用
e_lfanew(0x3C)定位 PE 头;
- 取数据目录下标 4(Security / 证书表)的 RVA(此处为
0x533DA)作为搜索上限;
- 从后向前扫描 4 字节标记
_]P[(5F 5D 50 5B);
- 命中后把标记之后的数据交给
ParseEmbeddedConfig。
6.2 本样本实测配置值
| 字段 |
值 |
_]P[ 标记位置 |
文件偏移 0x48CF |
| 配置起始(version) |
0x48D3,version = 1 |
| 载荷指针 / 长度 |
0x48E1 / 0x4EAD8(322,264 字节) |
| 执行标志 |
1(解密后作为 shellcode 执行) |
| 模式字节 |
2(先 XTEA 解密再执行) |
| XTEA 密钥 |
51 53 1F F4 A8 AC 0B 6A A3 09 BF A9 6A 41 8E 3E(16 字节) |
| 反VM 标志 / 反沙箱标志 |
1 / 1(均启用) |
| 自复制标志 / 假报错标志 |
1 / 1(均启用) |
即本样本把反 VM、反沙箱、自复制、假报错全部打开,走「XTEA 解密 → 反射加载 shellcode → 执行内嵌 DLL」的完整行为链。
6.3 Overlay 布局
0x4800 …… 0x48CF 对齐填充
0x48CF 内嵌配置标记 "_]P["
0x48D3 配置体(version=1)
0x48E1 XTEA 加密载荷(322,264 字节)
0x533BF XTEA 密钥(16 字节)
0x533DA …… 0x55E0A 证书表(Authenticode 签名,0x2A30 字节)
0x55E0A …… 0x55F3E 尾部数据
证书表为标准的 WIN_CERTIFICATE(wCertificateType=2,PKCS_SIGNED_DATA),内部是 DER 编码的 PKCS#7 签名 —— 样本带数字签名外壳。
7. 解密算法:XTEA(易被误判为 TEA)
逐轮核对轮函数与密钥索引后确认是标准 XTEA:
| 参数 |
值 |
| 密钥 |
16 字节(4 个 DWORD) |
| 块大小 |
8 字节(size & 7 == 0 校验) |
| delta |
0x9E3779B9(运算中表现为 +0x61C88647 = -delta) |
| 初始 sum |
0xC6EF3720 |
| 轮数 |
32 轮 |
| 轮函数 |
v -= ((v' + ((v'<<4) ^ (v'>>5))) ^ (sum + k[(sum>>11)&3])),第二个半轮在 sum 递减后取 k[sum&3] |
| Padding |
宽松 PKCS7:末字节 v ∈ [1,8] 时减去 v(不校验整段) |
TEA 与 XTEA 的 delta、初值、轮数完全相同,仅轮函数与密钥索引不同,极易误判。验证方法:对载荷解密后,尾部 7 字节均为 0x07(PKCS7 填充自洽),明文熵从 7.916 降至 6.043、头部为可识别的 jmp 跳板 —— 证明算法与密钥正确。
8. 载荷分析:PE 反射加载器 + 内嵌木马 DLL
8.1 解密结果(shellcode)
| 项目 |
值 |
| 密文 / 明文熵 |
7.916 / 6.043 |
| 明文头 |
E9 43 04 00 00(jmp +0x443 跳板)→ 90 90 90 NOP 滑板 → 48 8B C4 序言 |
| 特征指令 |
48 63 41 3C(movsxd rax,[rcx+0x3C] 取 e_lfanew)—— 直接读取 PE 头字段 |
| 尾部填充 |
07 × 7(PKCS7 自洽) |
开头即读取 e_lfanew、访问可选头字段 —— 典型的内存中反射加载 PE 的加载器 shellcode。在解密后偏移 0x6D1 处内嵌一个完整 PE。
8.2 内嵌模块「登录模块.dll」
| 项目 |
值 |
| 模块名(导出表自报) |
登录模块.dll(UTF-8) |
| 格式 |
AMD64,PE32+,ImageBase 0x180000000 |
| 编译时间戳 |
0x6A60597D = 2026-07-22 05:47:41 UTC(比 Loader 早 1 天,同批次构建) |
| 入口 / SizeOfImage |
0x18F20 / 0x56000(≈ 344 KB) |
| 节区 |
6 个(含 .reloc,可被反射重定位) |
| 导出 |
2 个:dao、hello(占位/混淆式命名) |
| 导入 |
14 个 DLL:KERNEL32 / USER32 / GDI32 / ADVAPI32 / SHELL32 / ole32 / OLEAUT32 / WS2_32 / bcrypt / WINMM / gdiplus / dxgi / DINPUT8 / VERSION |
能力画像(由导入推断):
- 进程注入:
CreateRemoteThread + VirtualAllocEx + WriteProcessMemory + SetThreadContext
- 键盘/剪贴板监听:
GetKeyState / GetLastInputInfo / DirectInput8Create、OpenClipboard/GetClipboardData
- 屏幕截图:GDI + gdiplus + dxgi 全套(
CreateDIBSection / GdipSaveImageToStream / CreateDXGIFactory)
- 网络 C2:Winsock(
WS2_32)+ bcrypt AES 加解密(BCryptEncrypt/Decrypt/GenRandom)
- 持久化:注册表(
RegCreateKeyExW / RegSetValueExW / RegDeleteValueW)
- 提权/UAC:
AdjustTokenPrivileges / OpenProcessToken / LookupAccountSidW
- 反取证:
ClearEventLogW / CloseEventLog(清事件日志)
DINPUT8.dll / VERSION.dll / gdiplus / dxgi 的组合与游戏组件高度相似,符合银狐家族「白加黑」侧加载布局特征(若该 DLL 落盘,可被伪装成被合法 exe 侧加载)。
9. 行为链全景
start()
├─ 1. PEB 遍历取得 kernel32 / ntdll / user32 / advapi32(缺失则 LoadLibraryA 动态加载)
├─ 2. 动态解析:GetModuleFileNameW / CreateFileW / GetFileSizeEx / ReadFile / CloseHandle /
│ Sleep / DeleteFileW / ExitProcess / CreateThread / GetCommandLineW 等
├─ 3. GetCommandLineW 扫描 "--child" 参数 → 命中则解析其后的引号路径,置子进程标志
├─ 4. 读自身文件到堆(GetModuleFileNameW → CreateFileW → ReadFile)
├─ 5. 取证书表(Security dir)RVA 定位 overlay → 从后向前找 "_]P[" 标记
│ → ParseEmbeddedConfig 解析配置
├─ 6. 分支决策:
│ ├─ 无配置 / 子进程 / 未置自复制标志 → 直接进 payload 执行路径
│ └─ 置自复制标志 且 非子进程 → 自复制二次启动:
│ %TEMP%<pid><tickcount>.exe + "--child" 重新启动
│ 成功 → ExitProcess(0);失败 → 降级当前进程执行
└─ 7. payload 执行路径:
├─ 反VM(IsVirtualMachinePresent)命中 → 退出
├─ 反沙箱(IsSandboxEnvironment)命中 → 退出
├─ 置假报错 → CreateThread("文件已损坏" MessageBoxW)
├─ LoadLibraryA("amsi.dll"); LoadLibraryA("ws2_32.dll")
├─ switch(模式):
│ 1|3 → 退出
│ 2 → XTEA 解密(payload, key) → 若执行标志==1 → ExecuteShellcode
│ 0 → 原样拷贝 → 若执行标志==1 → ExecuteShellcode
└─ ExecuteShellcode:
VirtualAlloc(0, size, MEM_COMMIT|RESERVE, PAGE_READWRITE)
→ memcpy(shellcode)
→ VirtualProtect(..., PAGE_EXECUTE_READ)
→ EnumSystemLocalesA(shellcode, LCID_INSTALLED) // 借回调执行
└─ shellcode:反射加载内嵌「登录模块.dll」,调用其导出
关键点:
- 自复制自删除:子进程
Sleep(300) 后 DeleteFileW(原始路径) 自删原文件,只留 %TEMP% 临时副本。
- shellcode 执行规避:用
EnumSystemLocalesA 的回调参数执行 shellcode,而非直接 CreateThread,规避敏感 API 监控。
- 前置加载:主动
LoadLibraryA("amsi.dll"/"ws2_32.dll"),为后续 C2 通信 / 环境准备。
- 假报错:
MessageBoxW(NULL, "文件已损坏", "错误", MB_ICONERROR) 伪装文件损坏,迷惑用户与分析人员。
10. 检测与防御建议
静态检测(YARA 示例):
rule SilverFox_Loader_XTEA_Overlay
{
meta:
description = "Silver Fox loader: XTEA-encrypted overlay payload + '_]P[' marker"
family = "SilverFox"
strings:
$m = { 5F 5D 50 5B } // "_]P[" overlay 配置标记
$xor = "_|rw_zqarajR" ascii // "LoadLibraryA" XOR(0x13) 混淆串
$xor2 = "Ezagfr\x7fR\x7f\x7f|p" ascii // "VirtualAlloc" XOR(0x13) 混淆串
condition:
uint16(0) == 0x5A4D
and pe.overlay.size > 0x20000 // 大 overlay(本样本 333 KB)
and $m at pe.overlay.offset // 标记位于 overlay 起点附近
and any of ($xor, $xor2)
}
注意:overlay 起点因样本而异,实际检测建议结合哈希拦截 + 沙箱行为特征。
行为检测 / 响应建议:
- 文件侧:拦截上述三个 SHA256(Loader / 解密 shellcode / 内嵌 DLL);关注「PE 代码量极小 + 超大体量 overlay + 无版本信息」的样本。
- 行为侧(EDR/Sysmon):告警以下特征组合 ——
- 进程自复制到
%TEMP% 且命名形如 <pid><tickcount>.exe,并带 --child 参数二次启动;
- 调用
EnumSystemLocalesA 且回调地址落在刚 VirtualProtect 过的 RWX→RX 内存;
VirtualAllocEx + WriteProcessMemory + CreateRemoteThread 远程线程注入;
OpenEventLogW + ClearEventLogW 事件日志清理;
LoadLibraryA("amsi.dll"/"ws2_32.dll") 的前置加载行为。
- 分析处置:样本绝不可在实体机执行,需在隔离的沙箱/虚拟机中验证动态行为;提取并解密 overlay 载荷时使用静态手段。
11. 附录:关键函数地址表
| 地址 |
函数 |
说明 |
0x1400010F0 |
start |
主入口 / 主流程 |
0x1400026A0 |
Get_Proc_Address |
手写导出表解析(含 forwarder 递归,深度 4) |
0x140002C20 |
Get_Module_Handle |
PEB 模块遍历 |
0x140002170 |
GetProcessCount |
进程数量统计 |
0x1400023D0 |
IsProcessRunning |
进程名检测 |
0x1400028C0 |
IsFilePresent |
文件/设备检测 |
0x140002D00 |
IsRegistryKeyPresent |
注册表检测 |
0x140002E20 |
IsSandboxEnvironment |
反沙箱门禁 |
0x140003920 |
IsVirtualMachinePresent |
13 项反虚拟机检测 |
0x140003C80 |
TeaDecrypt |
XTEA 解密(IDA 命名,实为 XTEA) |
0x1400029A0 |
DisplayErrorMessage |
“文件已损坏”假报错 |
0x140002A20 |
ExecuteShellcode |
shellcode 内存执行(EnumSystemLocalesA 回调) |
0x140001C60 |
SelfCopyAndExecuteChild |
自复制 + --child 二次启动 |
0x140003390 |
ParseEmbeddedConfig |
overlay 配置解析 |
12. 总结
本样本是银狐家族一个结构清晰、规避手段丰富的 Loader 变种,其技术栈可归纳为:
- 极小代码 + 超大 overlay:真正的“内容”都藏在加密载荷里,静态体积分析容易漏报;
- 字符串全量混淆:单字节 XOR
0x13,配合 _mm_xor_ps 一次解密 16 字节;
- 零 IAT 依赖:手写 PEB 遍历 + 导出表解析 + forwarder 递归,对抗 API Hook 与静态导入分析;
- 多层反分析:反虚拟机 + 反沙箱 + 反调试三重门禁,且全部由配置开关控制;
- 配置驱动:overlay 内嵌结构化配置(多段数据 + 密钥 + 执行模式 + 功能开关),一份 Loader 可复用打包不同载荷;
- 双层载荷:XTEA → 反射加载器 shellcode → 内嵌木马核心 DLL,层层解包,对抗纵深检测;
- 执行规避:
EnumSystemLocalesA 回调执行、%TEMP% 自复制 + 自删除、amsi/ws2_32 前置加载。
免责声明:本报告基于静态分析生成,未运行样本;样本及提取物仅供安全研究与威胁分析使用,请勿在真实环境执行。
报告完 · 分析工具:IDA Pro / pefile