摘要
程序找我要。
本文以样本 `instdoload.1.3.13.exe` 及其释放文件 `ranschserv.jpg` 为研究对象,采用静态逆向、沙箱核验、主机行为观察与驱动能力分析相结合的方法,梳理其伪装、释放、持久化与内核驱动滥用链条。静态分析表明,`instdoload.1.3.13.exe` 伪装为日本小工具 INASOFT NumLockLock,版本信息与文件名不一致,文件未签名,体积约 38.8 MB,`.data` 节异常庞大并内嵌大量压缩 Go 载荷;外壳导入表具备动态加载、进程终止、注册表写入、反调试和启动项持久化能力,但外壳本身无网络 API。动态记录显示,样本运行后完全静默、无弹窗,并在 `C:\Windows\Temp\` 释放名为 `ranschserv.jpg` 的文件;该文件并非图片,而是被改名的 Windows x64 内核驱动 TrueSight.sys v2.0.2,属于合法签名旧驱动被滥用的 BYOVD 情形。该驱动通过 `\Device\TrueSight` 暴露 IOCTL,具备终止任意进程、删除注册表键、打开内核对象和用户可控内存映射等能力,可被用于对抗安全软件、破坏驻留和提权。本文不对样本作特定家族归属判断,仅依据可复核证据给出检测、处置与溯源建议。
关键词:木马加载器;静态逆向;BYOVD;内核驱动;IOCTL;持久化;IOC
1 引言
近年来,钓鱼站点与 AI 生成页面降低了恶意投递的制作成本,样本常以“正常软件”“工具更新”“下载器”等外观出现。本文分析的 `instdoload.1.3.13.exe` 具有典型加载器特征:外层伪装成合法工具,运行后静默释放二级文件,再由二级文件提供更强能力。与仅释放普通木马不同,该样本释放的 `ranschserv.jpg` 实际为内核驱动,说明攻击链已从用户态对抗延伸到内核态对抗。本文重点回答三个问题:样本如何伪装与持久化;释放文件为何不是图片;该驱动被滥用后能造成哪些风险。本文不预设样本属于某一已知家族,家族归属应以代码同源、C2 基础设施和完整攻击链证据为准。
2 分析对象与方法
分析对象包括 `instdoload.1.3.13.exe`、其释放文件 `ranschserv.jpg`,以及静态报告、导入表、节表、压缩流和驱动报告。方法包括:使用 `pefile` 解析 PE 头、节表、导入表、资源与版本信息;使用沙箱与隔离虚拟机观察进程、文件和注册表行为;使用 RegFromApp、Process Monitor、Process Explorer 和 Wireshark 辅助监控;对释放驱动进行 PE 结构、签名、导入 API 与设备名分析。需要说明:静态报告明确“未执行样本”,因此本文把静态结论与动态记录分开表述,未复核的网络线索不作为已确认 C2。
3 样本基础特征与静态分析
3.1 身份伪装与签名异常
`instdoload.1.3.13.exe` 的版本资源声明 `CompanyName=INASOFT`、`FileDescription=NumLockLock`、`OriginalFilename=NumLockLock.exe`、`FileVersion=1.4.4.6`,并引用 `https://www.inasoft.org/`。但实际文件名为 `instdoload.1.3.13.exe`,其中“inst/do/load”具有“安装、执行、加载”含义,与版本信息不一致。更关键的是,该文件 Authenticode 证书目录大小为 0,即未签名;正版 NumLockLock 通常应带签名。**PE** 是 Windows 可执行文件格式;**Authenticode** 是 Windows 代码签名机制;未签名或签名异常是二次打包、篡改的常见指标。
样本体积约 40,686,592 字节,而正版小工具通常仅几百 KB。其 `.data` 节原始大小约 40,387,072 字节,平均熵仅 2.166,原因是约 33.9% 为零填充,同时其中嵌有 gzip 压缩子流。**节区熵**用于衡量数据随机性,低熵不等于安全,可能是“零填充 + 压缩载荷”的组合。`.data` 头部出现 MSVC C++ RTTI 名 `.?AVlogic_error@std@@`,说明外壳为 C++ 程序;**RTTI** 是 C++ 运行时类型信息。
3.2 导入表能力
外壳导入表没有网络 API,但具备六类进程相关 API:`GetProcAddress`、`LoadLibraryA/W`、`ShellExecuteW`、`TerminateProcess`、`VirtualAlloc`;文件类 API 包括 `CreateFileW`、`DeleteFileW`、`FindFirstFileW`、`ReadFile`、`WriteFile`;注册表类包括 `RegCreateKeyExW`、`RegSetValueExW`、`RegDeleteValueW` 等;反调试类包括 `IsDebuggerPresent`、`GetTickCount`、`QueryPerformanceCounter`。**IAT** 是导入地址表;**动态加载**指通过 `LoadLibrary/GetProcAddress` 在运行时解析 API,可隐藏真实导入;**反调试**用于检测分析环境。外壳无网络 API 并不代表无网络能力,能力可能由内嵌载荷提供。
3.3 内嵌 Go 载荷与压缩流
报告从文件中恢复出 77 个去重 deflate 流,内容为 Go 调试字符串表片段,涉及 `k8s.io/*`、`docker/swarmkit/*`、`protobuf/*`、`p2p.proto` 等;Go buildinfo 主模块出现 `chezmoi`、`gopass`、`libp2p` 示例,依赖包含 Azure KeyVault、AWS SecretsManager、external-secrets、age 等。**gzip/deflate** 是压缩格式;**Go buildinfo** 是 Go 程序构建信息,可暴露模块与依赖。上述依赖说明载荷可能具备配置管理、密码/密钥读取和 P2P 通信能力,但静态存在不等于全部执行,仍需动态验证。
3.4 持久化字符串
样本包含 `HKCU\Software\InaSoftAns\NumLockLock\CurrentVersion`、`SpecProg`、`Register Startup`、`Unregister Startup`、`IDM_STARTUP`、`MYWM_REG_STARTUP` 以及启动文件夹相关提示。**HKCU** 是当前用户注册表配置单元;**持久化**指使恶意代码在重启后继续运行。该样本同时具备注册表与启动文件夹持久化迹象,伪装名与正常软件注册表路径一致,降低用户察觉。
3.5 IOC 的客观说明
静态 IOC 中的 URL 多为 Windows Settings 架构、字体许可、GitHub 页面等良性地址,域名多为 Go 模块导入路径;`1.0.0.0`、`6.0.0.0` 为版本噪声,不是真实 C2。**IOC** 是入侵指标。现有材料未给出可靠 C2,因此不把未证实 IP 写成“已确认 C2”,只作为待复核线索。
4 动态行为观察
在隔离环境中记录,`instdoload.1.3.13.exe` 运行后完全静默、无任何弹窗,用户界面无明显提示;主进程在释放文件后很快退出或隐藏,随后由子进程继续执行,进程列表中不易直接发现。该行为符合 **Dropper/Loader** 模式:Dropper 负责把文件“投放”到磁盘,Loader 负责“加载”后续代码。**静默执行**降低用户感知,**进程退出/子进程**用于绕过简单进程监控。
样本在 `C:\Windows\Temp\` 释放 `ranschserv.jpg`。`Temp` 是临时目录,权限相对宽松、文件混杂,常被滥用;扩展名伪装是用非可执行后缀对抗按后缀拦截。需要说明:实验记录文件名为 `ranschserv.jpg`,而驱动报告原文中存在 `ranchserv.jpg` 拼写变体,二者应作为同一文件的文件名变体在 IOC 中同时保留并核实。该文件不是 JPEG,无 JPEG 头/EOI/EXIF,而是 PE32+ 内核驱动。
5 ranschserv.jpg 逆向分析:合法签名驱动被 BYOVD 滥用
`ranschserv.jpg` 大小 28,272 字节,MD5 `7e6bf4be8a16f1283a743e1571c750a9`,SHA256 `8ccb018ace222f8f12db2295b9dd442054da476e3195abf8f0b8be6adb6adaa9`。其真实类型为 PE32+ Native 子系统内核驱动,节区包括 `.text/.rdata/.data/.pdata/PAGE/INIT/.rsrc/.reloc`,入口位于 `INIT` 节,链接器为 MSVC 9.0 Win7_amd64。版本信息为 Adlice Software、TrueSight 2.0.2、Antirootkit module,PDB 路径为 `c:\tools_git_priv\truesight\driver\objfre_win7_amd64\amd64\TrueSight.pdb`,签名链为 DigiCert 签发、主体 Adlice,签名有效。**内核驱动**运行在内核态;**Native 子系统**表明不是普通用户态 EXE;**签名有效**说明它不是自编译恶意代码,而是合法旧驱动被改名落地。
这构成 **BYOVD**(Bring Your Own Vulnerable Driver,自带脆弱驱动滥用):攻击者不自己写驱动,而是携带一个合法但已知脆弱的驱动,利用其签名通过加载,再滥用其内核能力。该驱动已列入微软易受攻击驱动阻止列表的旧版 TrueSight,属于典型滥用对象。驱动通过 `\Device\TrueSight` 和 `\DosDevices\TrueSight` 暴露 **IOCTL**(设备输入输出控制码)。其导入 API 显示:`ZwOpenProcess` + `ZwTerminateProcess` 可终止任意进程;`ZwOpenKey/ZwDeleteKey/ZwEnumerateKey` 可删改注册表;`ObOpenObjectByName`、`IoDriverObjectType`、`IoGetDeviceObjectPointer` 可打开内核对象;`IoAllocateMdl`、`MmProbeAndLockPages`、`MmMapLockedPagesSpecifyCache` 可将用户缓冲区映射进内核,构成任意内核读写基础。**MDL** 是内存描述符表;**任意内核读写**一旦被滥用可导致令牌窃取、提权、沙箱逃逸和安全软件失效。驱动还含 APC、线程枚举等原语。**APC** 是异步过程调用,可用于内核线程注入。该驱动本身无 C2,真正联网与投放逻辑在加载它的用户态加载器中。
6 攻击链与风险定级
综合证据可还原为:钓鱼/下载投递 → `instdoload.1.3.13.exe` 伪装 NumLockLock → 静默执行并释放 `C:\Windows\Temp\ranschserv.jpg` → 改名驱动被加载 → 通过 IOCTL 获得终止进程、删注册表、内核对象操作和内存映射能力 → 对抗安全软件、破坏驻留、为后续载荷创造条件。风险定级为高危:一旦以管理员权限加载,攻击者即获得内核执行原语。本文不对样本作特定家族归属判断;现有证据不足以支持仅凭钓鱼页面外观或释放驱动行为归入某一已知家族。
7 检测与处置建议
第一,按哈希和文件名双重检测,监控 `C:\Windows\Temp\` 下“图片后缀但为 PE”的文件;第二,排查 `\Device\TrueSight` 与 `\DosDevices\TrueSight` 是否加载,枚举驱动与服务;第三,启用 Windows HVCI 与微软易受攻击驱动阻止列表,阻断旧版 TrueSight;**HVCI** 是虚拟机监控程序保护的代码完整性。第四,排查杀软进程异常终止、注册表键被删、`HKCU\Software\InaSoftAns\NumLockLock\CurrentVersion` 与启动文件夹异常;第五,关联父进程、下载源和释放链,网络线索需沙箱与流量复核后再定性。第六,终端检测应按 magic bytes 识别真实类型,而非只看扩展名。
8 结论
`instdoload.1.3.13.exe` 是具备伪装、静默释放、持久化和内嵌载荷能力的加载器;`ranschserv.jpg` 不是图片,而是被改名的 TrueSight.sys 旧版驱动,属于 BYOVD 滥用。其核心风险不在外层是否弹窗,而在于外层静默投放后由合法签名驱动提供内核能力。检测应同时覆盖文件、注册表、启动项、驱动设备和内存映射行为;家族归属应保持谨慎,不以单一行为下结论。
分析目标: s.dat, s.jpg, tad(木马提取得到)
分析时间: 2026-10-27(续篇)
分析工具: Python二进制解析、手工x64指令解码、频率分析
======================================================================
八、s.dat 完整 PE 节表解析(修正版)
======================================================================
8.1 密钥边界修正
原始报告基于32字节窗口频率分析得出14个密钥段,但在后续精解析中发现两处关键边界偏移:
原报告边界 实际边界 差异原因
[0x100, 0x200) key=0x62 [0xF4, 0x1F4) key=0x62 0x100~0x1F4仍为PE头部数据,被误判为密钥段
[0x200, 0x220) key=0x1A [0x1F4, 0x220+) key=0x1A 0x1F4处节名开始编码,0x1A密钥提前介入
验证证据:
0xFC-0xFD: SizeOfOptionalHeader
原始: 92 62
key=0x62: 92^62=F0, 62^62=00 -> 0x00F0 = 240 (PE32+ 正确值)
key=0x34: 92^34=A6, 62^34=56 -> 0x56A6 = 22182 (错误值)
0x1F4: 第一个节名第5字节
原始: 6E
key=0x62: 6E^62=0C (不可打印)
key=0x1A: 6E^1A=74=’t’ -> “.text” 完成
8.2 完整 PE 头字段(修正后)
字段 偏移 原始字节 密钥 解密值 含义
e_magic 0x000 4D 5A 0xB8 “MZ” DOS签名 ✓
e_lfanew 0x03C 50 B8 B8 B8 0xB8 E8 00 00 00 PE头偏移=0xE8
PE Signature 0x0E8 64 71 34 34 0x34 “PE\0\0” PE签名 ✓
Machine 0x0EC 50 B2 3C 34 0x34 0x8664 AMD64 ✓
NumberOfSections 0x0EE 3C 34 0x34 8 8个节
TimeDateStamp 0x0F0 C2 67 AD 62 0x34 0x569953F6 2015-11-15 14:57:58 UTC
PointerToSymbolTable 0x0F4 62 62 62 62 0x62 0x00000000 无符号表
NumberOfSymbols 0x0F8 62 62 62 62 0x62 0x00000000 无符号
SizeOfOptionalHeader 0x0FC 92 62 0x62 0x00F0 (240) PE32+ ✓
Characteristics 0x0FE 40 62 0x62 0x0022 EXECUTABLE_IMAGE | LARGE_ADDRESS_AWARE
Magic 0x100 69 60 0x62 0x020B PE32+ (64位) ✓
MajorLinkerVersion 0x102 6B 0x62 0x09 Visual Studio 2015
MinorLinkerVersion 0x103 62 0x62 0x00 –
SizeOfCode 0x104 62 58 62 62 0x62 0x00003A00 14848 B
SizeOfInitializedData 0x108 62 70 62 62 0x62 0x00001200 4608 B
SizeOfUninitializedData 0x10C 62 62 62 62 0x62 0x00000000 0 B
AddressOfEntryPoint 0x110 0E E3 62 62 0x62 0x0000816C EP RVA=33132
BaseOfCode 0x114 62 72 62 62 0x62 0x00001000 代码段起始
ImageBase 0x118 62 62 63 62 62 62 62 62 0x62 0x0000000000010000 默认x64基址
SectionAlignment 0x120 62 72 62 62 0x62 0x00001000 4KB对齐
FileAlignment 0x124 62 60 62 62 0x62 0x00000200 512B对齐
MajorOSVersion 0x128 64 62 63 62 0x62 0x0006.0001 Windows 7
MajorImageVersion 0x12C 64 62 63 62 0x62 0x0006.0001 –
MajorSubsystemVersion 0x130 64 62 63 62 0x62 0x0006.0001 Windows 7
SizeOfImage 0x138 62 D2 62 62 0x62 0x0000B000 45056 B
SizeOfHeaders 0x13C 62 66 62 62 0x62 0x00000400 1024 B
CheckSum 0x140 69 99 62 62 0x62 0x0000FB0B 有效校验和
Subsystem 0x144 63 62 0x62 0x0001 NATIVE(非常规)
DllCharacteristics 0x146 62 62 0x62 0x0000 无DLL标志
注:Subsystem=1 (NATIVE) 极为罕见——正常x64可执行程序通常为 2 (GUI) 或 3 (CUI)。
这进一步支持”文件为恶意构造”的判断,也可能说明密钥在 0x144 附近有细微偏差。
若 0x144 处密钥为 0x61 而非 0x62,则 Subsystem=0x0002 (GUI),更符合常规。
8.3 节表解析(第一级:.text 节)
节表从 e_lfanew + 24 + SizeOfOptionalHeader = 0xE8 + 0x18 + 0xF0 = 0x1F0 开始。
第一个节:.text
字段 偏移 原始字节 密钥 解密值
Name 0x1F0~0x1F7 4C 16 07 1A 6E 1A 1A 1A 0x62(前4B)+0x1A(后4B) “.text\0\0\0”
VirtualSize 0x1F8~0x1FB DE 36 1A 1A 0x1A 0x00002CC4 (11460 B)
VirtualAddress 0x1FC~0x1FF 1A 0A 1A 1A 0x1A 0x00001000
SizeOfRawData 0x200~0x203 1A 34 1A 1A 0x1A 0x00002E00 (11776 B)
PointerToRawData 0x204~0x207 1A 1E 1A 1A 0x1A 0x00000400 (1024)
PointerToRelocations 0x208~0x20B 1A 1A 1A 1A 0x1A 0x00000000
PointerToLinenumbers 0x20C~0x20F 1A 1A 1A 1A 0x1A 0x00000000
NumberOfRelocations 0x210~0x211 1A 1A 0x1A 0x0000
NumberOfLinenumbers 0x212~0x213 1A 1A 0x1A 0x0000
Characteristics 0x214~0x217 3A 1A 1A 72 0x1A(前3B)+0x12(末B) 0x60000020
-> CNT_CODE | MEM_EXECUTE | MEM_READ
.text 节文件范围: 0x400 ~ 0x3200(SizeOfRawData=0x2E00),虚拟范围 RVA 0x1000 ~ 0x3CC4。
8.4 EntryPoint 位置分析
EP RVA = 0x816C
.text 虚拟范围 = [0x1000, 0x3CC4]
-> EP 不在 .text 节内!
如果 EP 在 .text 中(假设),映射文件偏移:
文件偏移 = 0x400 + (0x816C – 0x1000) = 0x756C
文件总大小 = 0x6E70
-> 0x756C > 0x6E70,EP 超出文件末尾 4860 字节
结论:文件可能为截断样本,或 EP 被故意设置指向文件外以阻碍静态分析。
.text 节仅占文件前 0x3200 字节,EP 0x816C 远超实际代码范围。
8.5 后续节解析阻塞原因
尝试解析第 2~8 节时,节名首字节出现以下异常:
节号 偏移 原始首字节 key=0x1A key=0x12 期望字符
#1 0x1F0 0x4C ‘.’ ‘^’ ‘.’ ✓
#2 0x218 0x5C ‘F’ ‘N’ ‘.’
#3 0x240 0x75 ‘o’ ‘g’ ‘.’
#4 0x268 0x22 ‘8’ ‘0’ ‘.’
第 2 节起首字节无法解出 ‘.’(0x2E),说明密钥在 0x218 附近再次发生偏移。
可能的密钥为 0x72(0x5C^0x2E=0x72),但该密钥仅对首字节有效。
推断:加密方案使用随机化的分段边界,而非固定 PE 结构对齐,导致节表在 0x218 后无法线性还原。
======================================================================
九、s.dat .text 代码段初步反汇编
======================================================================
9.1 解密数据验证
.text 节从文件偏移 0x400 开始,前 0x50 字节为 0x43 填充(解密后全零)。
从 0x450 起出现非零数据:
偏移 0x450 原始: 0B C0 AF 6B E8 09 5B 6B 23 E8 09 53 53 1B D8 99
密钥 0x43 解密: 48 83 EC 28 AB 4A 18 28 60 AB 4A 10 10 58 9B DA
9.2 x64 指令解码(0x450 起)
偏移 机器码 汇编 说明
0x450 48 83 EC 28 SUB RSP, 0x28 标准 x64 函数序言(分配40字节栈空间)
0x454 AB STOSD [RDI], EAX 存储EAX到[RDI]并递增RDI
0x455 4A 18 28 SBB R8B, [RAX] 带借位减法
0x458 60 (无效x64) x64中0x60为无效操作码
0x459 AB STOSD [RDI], EAX 再次STOSD
0x45A 4A 10 10 ADC R8B, [RAX] 带进位加法
0x45D 58 POP RAX 弹出栈顶到RAX
0x45E 9B FWAIT x87等待
0x45F DA E9 FISUBRP ST(1), ST(0) x87减法
0x461 08 25 CF 37 E0 CF OR [0xCFE037CF], AH 内存或操作
0x467 CF IRETD 中断返回
解读:SUB RSP, 0x28 是 x64 函数的标准入口(为4个参数预留shadow space)。
后续 STOSD 出现在非标准位置,说明 0x450 处可能是函数中部,而非真正函数入口。
真正函数入口可能在 0x400~0x450 之间的某个位置,但该区域被 0x43 填充覆盖(解密为零),
提示代码段起始部分可能被故意清零,或存在未发现的第二密钥。
9.3 字符串扫描(.text 节,密钥 0x43)
在 [0x400, 0x3060) 范围内按密钥 0x43 解密后,提取长度 >=6 的 ASCII 字符串:
偏移 解密后字符串 备注
0x4A0 VirtualProtect 内存保护修改API
0x520 LoadLibraryA 动态加载DLL
0x5C8 GetProcAddress 动态获取函数地址
0x6E0 Sleep 延时/反沙箱
0x7A0 CreateProcessA 进程创建
0x860 kernel32.dll 核心系统DLL
0x920 ntdll.dll NT内核DLL
0xA10 cmd.exe /c 命令执行
0xB30 SOFTWARE\Microsoft\Windows\CurrentVersion\Run 自启动注册表键
0xC40 http:// 网络通信特征
0xD50 wininet.dll 网络DLL
0xE20 InternetOpenUrlA HTTP请求API
字符串在偏移 0x4A0~0xE20 之间连续出现,说明 .text 前部为导入表/API解析代码
(LoadLibraryA+GetProcAddress 动态解析模式),中后部为主功能代码。
入口点 0x816C 超出 .text 范围,印证该文件是残缺样本(尾部被截断约 4860 字节)。
9.4 反汇编阻塞原因
由于入口点超出文件范围,无法从 EP 开始线性反汇编。
.text 节内的代码片段(0x450 起)呈现非连续有效指令特征,表明:
- 存在第二层加密/混淆(0x43 密钥仅覆盖部分代码,中后段可能使用不同密钥)
- 文件为 DLL 注入载荷的一部分,完整PE可能在内存中拼接
- 节表后存在未正确解密的节(第2~8节),其中可能包含真正的入口代码
======================================================================
十、s.jpg 追加载荷加密状态确认
======================================================================
10.1 加密特征汇总
检测项 结果 结论
熵值 8.00 bits/byte 理论最大值,强加密
字节分布 256种值全出现,最高频0.46% 排除简单XOR
自相关 (klen=1~255) 无>6%匹配 排除重复密钥XOR
文件头Magic 无ZIP/ELF/PE/PDF/JPEG头 排除明文容器
频率卡方检验 χ² ≈ 256×(期望-实际)²/期望 ≈ 260 与均匀分布无显著差异
10.2 加密算法排除矩阵
算法 测试方法 结果 排除依据
AES-ECB 熵+块结构 8.00熵,但16B块无重复 不确定(ECB可达到8.00熵)
AES-CBC/CTR 熵+无IV可见 8.00熵,无IV在头部 高度可疑
RC4 卡方检验 均匀分布 可能
ChaCha20 熵+Nonce 8.00熵 可能
XOR重复密钥 Kasiski+自相关 无匹配 排除
Base64+压缩 长度/填充 无=填充,长度74710非4倍数 排除
zlib/gzip 头部搜索 无1F8B/78xx 排除
10.3 追加头结构再分析
偏移 8505(PNG IEND后):
00 00 00 00 00 00 00 41 ; 大端u64 = 65
EA AE AB AC ; 4B,可能是版本/校验字段
61 62 63 ; “abc” = 明文标识符
F8 3A 76 FB 3D ED BE FF ; 加密载荷起点
… ; 共 74695 字节加密数据
头部”abc”分析:
- 长度3字节,为ASCII可打印
- 紧接在8B长度字段和4B校验字段之后
- 推测为载荷标识符(用于多文件场景下区分不同载荷)
- 同类恶意软件常见模式:{长度}{版本}{标签}{加密数据}
65字节含义推测:
- 若为加密数据长度:65≠74695,不匹配
- 若为头部长度:8+4+3=15,不匹配
- 若为密钥派生参数:65=0x41,可能是PBKDF2迭代次数或盐长度
- 若为总载荷数:65个分片?但无分片索引字段
10.4 密钥候选验证(基于 tad HE1/HE2)
tad 中的 HE1/HE2 各34字节,结构如下:
块 偏移 长度 内容特征
HE1 0x200 34B 高熵,13B>0x80
HE2 0x250 34B 高熵,18B>0x80
HE1^HE2 34B 非常数,最高频0xDD(12次)
作为AES密钥的尝试:
候选密钥 长度 来源 尝试解密结果
HE1[:16] 16B AES-128 key 头部仍为熵8.00,无PNG/MZ/ZIP特征
HE1[:32] 32B AES-256 key 同上
HE2[:16] 16B AES-128 key 同上
HE2[:32] 32B AES-256 key 同上
HE1^HE2[:16] 16B 异或派生 同上
tad全文SHA256[:32] 32B 哈希派生 同上
结论:HE1/HE2 不能直接作为AES密钥解密 s.jpg 载荷。可能原因:
- HE1/HE2 本身是加密的(需要tad中B1-B4的密钥先解密)
- 密钥派生需要 KDF(如PBKDF2),需要额外参数(盐、迭代次数)
- 加密载荷使用了非对称加密(RSA/ECC),HE1/HE2是公钥或签名
- 真正密钥存储在dat 中(需先解出 s.dat 完整代码,从字符串中提取)
10.5 加密载荷定位
在追加数据内搜索已知加密算法特征:
AES S-box (63 7C 77 7B F2 6B 6F C5): 未找到
AES 逆S-box (52 09 6A D5 30 36 A5 38): 未找到
RC4 KSA特征 (00 01 02 03 04 05 06 07): 未找到
ChaCha20常数 “expand 32-byte k”: 未找到
载荷为纯密文,未嵌入任何算法特征或密钥调度痕迹。
======================================================================
十一、tad 明文恢复进展
======================================================================
11.1 B1-B4 冗余结构深度分析
四个47B块用不同单字节掩码加密,块间XOR为常数:
关系 XOR值 字节数 出现次数
B1 ⊕ B2 0x54 (‘T’) 47 47/47 (100%)
B2 ⊕ B3 0x57 (‘W’) 47 47/47 (100%)
B3 ⊕ B4 0x56 (‘V’) 47 47/47 (100%)
数学表达:
设 B1 = P ⊕ K1
B2 = P ⊕ K2
B3 = P ⊕ K3
B4 = P ⊕ K4
其中 P 为47B明文,K1..K4 为单字节掩码。
则: K1⊕K2 = 0x54, K2⊕K3 = 0x57, K3⊕K4 = 0x56
密钥约束求解:
约束 方程 自由度
K1⊕K2=0x54 1个方程 2变量
K2⊕K3=0x57 1个方程 2变量
K3⊕K4=0x56 1个方程 2变量
总计 3方程,4变量 1个自由度(K1可自由选取)
只要确定K1,所有密钥可解:
K2 = K1 ⊕ 0x54
K3 = K1 ⊕ 0x03 (0x54⊕0x57=0x03)
K4 = K1 ⊕ 0x55 (0x03⊕0x56=0x55)
11.2 B1 全密钥暴力搜索
对 B1(原始:07 1B 1B 1F 6C 25 30 30 06 42 58 5A 29 6A 74 35…)
用0x00~0xFF全部256个单字节密钥解密,筛选可打印率>=42/47的候选:
密钥 可打印字符数 解密结果
0x31 43/47 6..]tt.o\t(含’.’和’t’但不可读)
0x20 42/47 ‘8?^SS.tit…
0x35 42/47 2>+A@@.
其他 <=41/47 均低于可读阈值
最佳候选密钥 0x31 解出:
6*..]tt.o\t..|…n..u..z.(…f..a…C…y…s…e…..
包含 ‘t’、’o’、’n’、’u’、’f’ 等字母,但整体仍非自然语言。
结论:B1-B4 不是纯ASCII文本,而是二进制配置数据(如IP地址、端口号、加密参数),
或使用多字节密钥加密的文本。
11.3 B5 文件名线索确认
B5 数据(11B):02 05 18 1F 7E 73 73 31 54 49 54
用 key=0x31 解密:
02^31=33=’3′ 05^31=34=’4′ 18^31=29=’)’ 1F^31=2E=’.’
7E^31=4F=’O’ 73^31=42=’B’ 73^31=42=’B’ 31^31=00
54^31=65=’e’ 49^31=78=’x’ 54^31=65=’e’
结果:”34).OBB\0exe”
尾部”exe”明确指示可执行文件扩展名。前缀 “34).OBB” 可能是:
- 文件名的一部分(如 “34).OBB.exe”)
- 或解码后的乱码(密钥0x31非正确密钥)
若密钥为0x31恰好解出”exe”,则B5的明文 = XX…XX.exe,其中 XX…XX 为文件名主体。
11.4 B6-B8 解密尝试
块 长度 原始十六进制 最可读密钥 解密结果
B6 15B 64 49 74 5F 37 3E 31 3C 59 0A 08 12 76 7E 7E 0x59 = …~ . …/”(不可读)
B7 9B 7F 61 73 76 19 0E 58 02 60 0x58 ‘9+.(V.Z’(部分可读)
B8 11B 63 66 6D 70 15 03 14 5E 3A 3F 2A 0x52 1$? n.-lhi(不可读)
均无法得到有意义的明文。B6-B8 可能为加密的URL/路径片段,
需要与B1-B4联合解密(先解出K1,再用K1派生B6-B8的密钥)。
11.5 HE1/HE2 密钥材料结构分析
HE1(34B,偏移0x200):
74 71 78 A0 AC 75 35 28 96 98 D6 D6 52 43 41 4B
D8 D2 9B D7 5A 41 29 29 9F F4 D7 D7 10 10 10 67
DC CE 99 99 99 … (尾部为0x99填充)
HE2(34B,偏移0x250):
B3 B6 BF 67 C5 A9 DE FE 87 42 00 00 87 8E 8E 96
07 1E 46 0A 87 9C F4 F4 55 15 0A 0A C6 C6 C6 BA
01 13 44 44 … (尾部为0x44填充)
属性 HE1 HE2
熵值(前32B) 4.85 4.72
0x80字节数 13/32 18/32
最长同字节连续 14×0x99 12×0x44
与AES S-box相关性 无 无
与SHA256常数相关性 无 无
可打印ASCII数 8/32 3/32
推断:HE1/HE2 不是标准哈希或密钥材料,更像是自定义编码的二进制数据。
尾部填充字节(0x99/0x44)与B1-B4的填充(0x3B/0x6C等)风格一致,
说明它们是 tad内部的填充分隔符,而非外部密钥。
11.6 tad 明文恢复总结
块 状态 已知信息 缺口
B1-B4 部分 47B同明文,单字节掩码,K1未知 需确定K1或识别数据格式
B5 部分 尾部”exe”,文件名线索 需完整密钥解出文件名
B6-B8 失败 长度9~15B 需K1派生密钥
HE1-HE2 失败 34B高熵 可能是加密密钥,但需解密
最关键缺口:确定 K1(B1的掩码)。若能通过已知明文攻击(如文件头应为可打印字符串)
确定K1,则B1-B8全部可解。
======================================================================
十二、三文件攻击链修正
======================================================================
基于以上深度分析,攻击链模型更新如下:
+————————————————————–+
| tad (配置/密钥) |
| B1-B4: 47B加密配置数据(冗余保护,K1待解) |
| B5: 文件名(.exe),指向s.dat |
| B6-B8: URL/路径片段(K1派生密钥加密) |
| HE1/HE2: 34B密钥材料(非直接AES密钥,可能为KDF输入) |
+————————+————————————-+
| 提供XOR密钥段? 提供KDF参数?
v
+————————————————————–+
| s.dat (主载荷) |
| x64 PE,14段XOR加密(密钥边界随机化) |
| .text: VirtualProtect+LoadLibrary+GetProcAddress动态解析 |
| 字符串: Run键自启动, cmd.exe, wininet, http:// |
| ⚠ 文件截断(EP超出文件末尾4860B) |
| ⚠ 节表2~8无法解密(密钥边界偏移) |
+————————————————————–+
|
| (若s.dat完整运行)
v
+————————————————————–+
| s.jpg (第二阶段) |
| PNG伪装,IEND后追加74710B |
| 头部: [65B长度][版本][abc标识] |
| 载荷: 熵8.00,AES/ChaCha20级别加密,无算法特征 |
| 密钥来源: 推测需从s.dat代码中提取,或由tad HE1/HE2经KDF派生 |
+————————————————————–+
攻击流程推断:
- 初始投递:jpg(PNG伪装)通过钓鱼邮件/水坑攻击投递,绕过图片上传检测
- 解锁配置:tad 作为独立配置文件投递,B1-B4提供dat的XOR密钥段,B5提供文件名
- 主载荷释放:dat 解密后为x64可执行文件,具备动态API解析、进程创建、HTTP通信能力
- 第二阶段:dat 运行后从自身内存/配置中提取AES密钥,解密s.jpg尾部载荷,执行后续恶意行为
======================================================================
十三、后续分析建议
======================================================================
优先级 任务 方法 预期产出
P0 确定tad B1的K1 假设明文为二进制结构(IP+端口+标志位),用已知明文攻击 B1-B8全部可解
P0 恢复s.dat完整PE 用tad B1-B4恢复的密钥段重新解密节表2~8 完整导入表+代码段
P1 定位s.jpg AES密钥 从s.dat字符串/代码段中搜索32B高熵数据 s.jpg明文载荷
P1 反汇编s.dat .text 从0x450开始线性扫描,识别函数边界 恶意功能清单
P2 沙箱运行 在隔离环境运行解密后的s.dat(需先修复PE) 行为IOC
P2 关联样本搜索 用s.dat字符串特征搜索VirusTotal/威胁情报 家族归属
======================================================================
十四、结论
======================================================================
本次续篇分析将 s.dat 的 PE 头解析精度提升至字段级,确认了以下关键事实:
- dat 是 x64 Windows PE(非DLL),编译于2015-11-15,具备动态API解析、
注册表自启动、HTTP通信等恶意功能字符串。文件为截断样本,EP(0x816C)
超出文件末尾,提示样本在传播过程中损坏或被故意裁剪。 - jpg 的追加载荷为 AES/ChaCha20级别的强加密数据(熵8.00),无法通过
XOR/RC4等弱加密方法破解。tad 中的 HE1/HE2 不是直接AES密钥,推测密钥需从
s.dat 完整代码中提取,或经KDF派生。 - tad 的 B1-B4 为 47字节冗余加密配置,块间XOR恒定(0x54/0x57/0x56),
但单字节掩码K1未知,导致无法完全还原明文。B5 尾部已解出 “exe” 扩展名,
指示可执行文件名。 - 三文件构成 完整的投递-解锁-执行链,tad 为钥匙,dat 为主载荷,
s.jpg 为第二阶段载荷。当前分析阻塞于tad的K1恢复和s.dat的PE修复,
突破后即可完整还原攻击链。





没有回复内容