|
981| 6
|
[PC样本分析] Install_098k_银狐木马静态分析报告(二) |
|
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子! 病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途! 禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
4.3 加载 ntdll 并再解析 2 个函数
于是引导代码在栈上( 4.4 读载荷描述符(
|
| 偏移 | 字节 | 值 | 含义 |
|---|---|---|---|
0x65C |
00 |
0 | 标志:0 = 直接反射加载(非 0 走“先拷贝/解密到临时缓冲再反射”分支) |
0x65D |
00 00 00 00 |
0 | 预拷贝源/长度字段(本样本未启用) |
0x669 |
75 00 00 00 |
0x75 |
内嵌 PE 相对描述符的偏移 → 0x65C + 0x75 = 0x6D1 |
call ReflectiveLoader(r13=API表, rsi/rdx=PE@0x6D1, …)
—— DLL 被反射映射,DllMain/入口在反射器内部即被调用
返回后:call [rbp+38h] —— 反射器写回的目标导出/入口地址,木马核心由此激活
整段引导只见
call [r13+0x10]这类寄存器间接调用,看不到任何静态导入/导出引用;模块名、函数名、参数字符串全部哈希化或运行时压栈。这是典型的"自给自足"加载器写法。
h = 0
for c in 字符串: h = h * 0xB1(177) + c // 32 位回卷
return h & 0x7FFFFFFF // 清掉最高位
KERNEL32.DLL);Hash_GetProcAddress(0x8)就是按这个哈希手写遍历导出表:e_lfanew → 导出目录 → AddressOfNames / AddressOfNameOrdinals / AddressOfFunctions,比对名字哈希后返回函数地址;传入真 GetProcAddress 指针时还能处理转发函数(forwarder),与外层 Loader 的解析器一脉相承。
| 用途 | 字符串 | 计算哈希 |
|---|---|---|
| 模块名(先转大写) | KERNEL32.DLL |
0x13D21720 |
| 导出名 | GetProcAddress |
0x196495CA |
| 导出名 | LoadLibraryA |
0x5214D8E6 |
| 导出名 | VirtualAlloc |
0x299DEE32 |
| 导出名 | VirtualFree |
0x72B66139 |
| 导出名 | lstrcmpiA |
0x04B320BF |
| 导出名 | RtlZeroMemory |
0x74CC03AB |
| 导出名 | RtlMoveMemory |
0x6DE0C632 |
第 1 篇 Loader 找模块用的哈希、与本篇反射器找函数用的哈希,系数都是 0xB1、收尾都是 &0x7FFFFFFF。哈希函数是作者自己写的、特征极强的代码,两阶段共用同一原语,基本可以断定 Loader 与载荷出自同一作者 / 同一框架。这种“自研哈希贯穿多阶段”的写法,也常作为同源聚类(家族归属)的判据。
ReflectiveLoader(0xDC)深入内嵌 DLL 是标准 PE32+、带 .reloc、带完整导入表——这正是反射器能把它搬进内存的前提。反射器工作流:
ReflectiveLoader(api表, pe=0x6D1, …)
├─ 1. PE 校验:'MZ' && e_lfanew 可读 && 'PE' && Machine==0x8664 && Magic==0x20B
├─ 2. 内存申请:
│ base = VirtualAlloc(NULL, SizeOfImage, MEM_COMMIT|RESERVE, PAGE_EXECUTE_READWRITE)
│ RtlMoveMemory(base, pe, SizeOfHeaders) // 先拷头
├─ 3. 逐节映射(对每个 IMAGE_SECTION_HEADER):
│ dest = base + VirtualAddress
│ SizeOfRawData 非 0 → RtlMoveMemory(dest, pe+PointerToRawData, SizeOfRawData)
│ VirtualSize > SizeOfRawData → RtlZeroMemory 补零到 VirtualSize // BSS 补零
├─ 4. 重定位(若带 .reloc):
│ baseDelta = 新基址 − ImageBase(0x180000000)
│ 0x3000 HIGHLOW → *(u32*) += baseDelta
│ 0xA000 DIR64 → *(u64*) += baseDelta
├─ 5. 导入修复:
│ for 每个 IMAGE_IMPORT_DESCRIPTOR:
│ hMod = LoadLibraryA(该 DLL 名) // 明文加载
│ for thunk in FirstThunk:
│ 名字导入 → GetProcAddress(hMod, 明文函数名) // 明文按名解析
│ 序号导入 → 直接取 AddressOfFunctions
├─ 6. TLS 回调(可选):AddressOfCallBacks 非空则逐个调用 // 本 DLL 无 TLS,跳过
├─ 7. 调用入口:
│ (base + AddressOfEntryPoint)(…, reason=1(DLL_PROCESS_ATTACH), …)
└─ 8. (可选)按名解析导出并写回输出槽,供 bootstrap 调用
值得说明的两个反直觉点:
LoadLibraryA + GetProcAddress ——说明作者的混淆投入集中在加载/投递链路,而不是业务 DLL 内部。| 项目 | 值 |
|---|---|
| 模块名(导出表自报) | 登录模块.dll(UTF-8) |
| 架构 / ImageBase | AMD64 / 0x180000000 |
| 编译时间戳 | 0x6A60597D = 2026-07-22(比 Loader 早 1 天,同批次构建) |
| 入口 / SizeOfImage | 0x18F20 / 0x56000 |
| 节区 | 6:.text/.rdata/.data/.pdata/.rsrc/.reloc(带重定位,可被反射) |
| 导出 | 2:dao、hello(占位/混淆式命名) |
| 函数规模 | 862 个函数 |
| 导入 | 14 个 DLL:KERNEL32/USER32/GDI32/ADVAPI32/SHELL32/ole32/OLEAUT32/WS2_32/bcrypt/WINMM/gdiplus/dxgi/DINPUT8/VERSION |
| 字符串 | 关键串均 XOR 0x4B 的 UTF-16LE 混淆,运行期解码 |
导入面已经很能说明问题:CreateRemoteThread/VirtualAllocEx/WriteProcessMemory(注入)、OpenClipboard/GetClipboardData(剪贴板)、GetKeyState/DirectInput8Create(输入监听)、GDI+GDI+DXGI(截图)、WS2_32 + bcrypt(网络 + AES)、注册表 API(配置/持久化)、ClearEventLogW(清日志)。其中 DINPUT8 / VERSION / gdiplus / dxgi 组合与游戏组件相似——典型的“白加黑”侧加载布局:若该 DLL 落盘,可伪装成被带这些依赖的合法程序侧加载。
DLL 入口 sub_180018DF8(AddressOfEntryPoint=0x18F20)
└─ StartMainThread (0x180017680)
└─ CreateThread(主线程体 StartAddress)
└─ 按需拉起 C2 通信、命令分发、键盘/剪贴板、截屏、守护等线程
导出 hello / dao 都通向这条启动链。反射器调用导出或入口,效果等价于让木马核心在当前进程内直接初始化——这是“内存运行、不落盘”的临门一脚。
配置存注册表:HKCU\…\Software\Microsoft\Hello(值名 Hello)——项名 Hello 与导出 hello 呼应,像是作者自己的命名习惯标记。读不到 HKCU 再读 HKLM(兜底)。
值格式(管道分隔):p1:IP|o1:port|t1:proto|p2|o2|t2|p3|o3|t3|ur:url…
p{n}/o{n}/t{n}:最多 3 组 C2 的 IP/端口/传输协议(TCP/UDP);ur::备用 URL 型 C2。通信帧(bcrypt AES-CBC):
收帧:[4B 长度 N][16B IV][N 字节 AES-CBC 密文] // 每帧独立 IV
发帧:同构
另有 [0]=0xCC 这类“特殊首字节 + 紧凑结构”用于状态/心跳上行,与 AES 数据帧区分。
sub_18000F8C0,203-case switch)主循环收到命令后进一个按命令号分发、含 203 个 case 的巨型 switch(类 CLoginManager 虚表驱动)。已梳理出代表性子集:
| 命令号 | 行为 |
|---|---|
| 0 / 1 | 载荷/任务下发执行 |
| 2 | 事件上报(键盘/剪贴板等) |
| 3 | 速率/节流控制 |
| 4 | 截图信息(宽高/数量)上报 |
| 5 | 缩略图截图(首字节 0xCD) |
| 6 | 接收文件 + 注册表文件关联启动 |
| 7 | URL 下载(wininet,校验 MZ)→ 隐藏执行(C:\Users\Public\Downloads + 隐藏进程) |
| 8 | 备注/分组 设置、删除 |
| 9 | 进程枚举上报 |
| 10 | 心跳 |
| 11 | 全屏截图(0x12 标识) |
| 12 | 清事件日志(ClearEventLogW) |
| 13 | 异常过滤设置 |
| 14 | ExitProcess 自杀 |
| 15/16/17 | 注销 / 重启 / 关机 |
| 18 | 上报加载模式 |
| 19 | 配置迁移 + 重新解析 |
| 20 | 拉起 C2 线程 |
| 100/101 | 写/删 HKCU\…\Console\IpDatespecial(感染标记) |
| 201/202 | 状态上报(0xCC 帧):空闲时长/前台窗口/IM 进程扫描/持久化存活/驱动 k32.sys 检测 |
命令面覆盖 侦察 → 控制 → 数据窃取 → 反取证 → 自杀 的完整生命周期。0xCC 状态帧里的 IM 扫描与 k32.sys(银狐常用内核对抗驱动)字段是家族行为的强特征。
① 键盘记录 + 剪贴板监视
DirectInput8Create + 轮询取键(非全局钩子,规避常见的钩子检测),叠加 GetLastInputInfo;CF_UNICODETEXT;记录前台窗口标题;%LOCALAPPDATA%\DisplaySessionContainers.log,50MB 轮转;HKCU 下某值 open == "1" 才启用——记录功能可被 C2 远程开关。② 双进程守护(自愈对抗)
RemoteThreadInject(0x18000BCF0):VirtualAllocEx RWX + WriteProcessMemory 向 svchost.exe 注入守护 shellcode + 小 API 表 → CreateRemoteThread(挂起)→ Sleep 60s → ResumeThread;ProcessGuardLoop(0x18000C110):宿主死亡后由 svchost 里的守护体拉回;若被注入进程退出码 ≠ 259(STILL_ACTIVE)则重新注入。③ TCP 连接表隐藏
InitBackupC2AndHooks(0x1800147A0):先备份 C2 端点到内存向量,再对 iphlpapi 的 GetExtendedTcpTable / AllocateAndGetTcpExTableFromStack / InternalGetTcpTable2 打 14 字节 FF25(jmp [rip+…])内联 Hook;netstat、第三方网络监视都看不到它的 C2 连接。④ 屏幕截图:GDI StretchBlt 抓屏 → GDI+ JPEG 编码,按命令号(4/5/11)不同规格回传。
⑤ 插件 / 附加载荷:onlyloadinmyself / plugmark 标记——仅当进程名/标记匹配才加载附加 DLL 插件(数据区 0x180051D00),避免在分析环境被动释放附加能力。
| 手法 | 内容 |
|---|---|
| 启动项 | Run 键 迅雷服务 |
| 计划任务 | \MicrosoftEdgeUpdate\Update |
| WMI | SvcHostUpdate |
| 侧加载 | DINPUT8/VERSION 布局,“白加黑” |
| 界面伪装 | 资源仅清单,配合“文件损坏”类假报错 |
Install_098k.exe
├─ 环境门禁(反VM/反沙箱) → 自复制二次启动 → 预载 amsi/ws2_32
└─ XTEA 解密 → ExecuteShellcode
└─ _payload_dec.bin(反射器 shellcode)
├─ bootstrap 0x448:PEB→kernel32 → 哈希解析 7 函数 → LoadLibraryA("ntdll")
├─ 描述符 0x65C(flag=0)→ PE@0x6D1
└─ ReflectiveLoader:校验 → VirtualAlloc(RWX) → 映射 6 节 → .reloc 重定位
→ 明文修 IAT → 调 DllMain(1)
└─ 登录模块.dll(内存运行、不落盘)
├─ StartMainThread → 主 C2 线程
├─ 注册表读 C2(Software\Microsoft\Hello) → TCP/UDP 外联
├─ AES-CBC 帧 → C2 Dispatcher(203-case) 分发
├─ 键盘/剪贴板(DINPUT8 轮询 + 注册表开关)
├─ 注入 svchost 双进程守护
├─ FF25 内联 Hook TCP 表 → 隐藏 C2 连接
└─ 截图/文件/插件/清日志/注销/关机/自杀…
×0xB1 哈希循环、XOR-0x4B UTF-16、导出 dao/hello、14 字节 FF25 Hook 模板、p1:IP|o1:port 管道串;Software\Microsoft\Hello、Console\IpDatespecial;迅雷服务、MicrosoftEdgeUpdate\Update、SvcHostUpdate。svchost.exe 中驻留的守护 shellcode 高敏(netstat/任务管理器不可见也不代表干净)。DisplaySessionContainers.log;netstat(TCP 表可能被 hook),配合抓包确认外联。h = h×0xB1 + c, &0x7FFFFFFF 贯穿 Loader 与 Shellcode 两阶段,是家族聚类的硬指纹。.reloc 重定位 → LoadLibraryA+GetProcAddress 明文修 IAT → 以 reason=1 调入口。本文为纯静态分析产物,样本及解密载荷均未运行,仅载入 IDA / 十六进制工具比对。样本仅用于安全技术研究,请勿在真实环境运行或传播。本文涉及的哈希、注册表项、文件路径均为样本分析所得,仅作检测/应急参考。
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。
|
推荐
发表于 2026-9-2 19:33
| ||
|
3#
发表于 2026-9-2 17:58
| ||
|
4#
发表于 2026-9-3 08:52
| ||
|
5#
发表于 2026-9-3 14:31
| ||
RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )
GMT+8, 2026-9-9 17:01
Powered by Discuz!
Copyright © 2001-2020, Tencent Cloud.