e1 电子取证案件(程序功能分析·流量·服务器检材)

证据集概况

项目 值
证据集根目录 C:\Users\glj07\Downloads\e1
组成 e1_20260903100051N/、服务器检材.E01/、流量/、程序功能分析/
压缩包哈希(哈希值.txt) 程序分析(请在安全的环境下运行).zip MD5 = 9F0911003E942318B8B93D651C7CA9F1(33909 字节)
本地工作区 Writeup\Forensic\未归类案件\e1_程序功能分析(赛事名确认后可迁移归位)

三、计算机取证

待归题号:winaudio.exe 版本资源中伪装的”公司名称”

题目原文:通过对 winaudio.exe 分析,该样本在版本资源中伪装的”公司名称”是什么?[答案格式:按实际值填写]

  • 证据类型:Windows PE 可执行文件(程序功能分析)
  • 检材来源:程序功能分析/程序分析(请在安全的环境下运行)/audctl/winaudio.exe(63177 字节,PE 头 @0x80);本地工作区副本 originals/winaudio.exe
  • 样本哈希:MD5 6cdd957eb59f0dae88fa372c96d29586;SHA-256 512b9bb4b278c377ffa037753c79caf96ec96acf51ba11fba1d8383e98c60e8f
  • 关键证据/关键路径:PE 资源区 VS_VERSION_INFO → StringFileInfo(080404B0),CompanyName 键 @文件偏移 0xF0F6,值串起始 0xF112(UTF-16LE)

提取方法

Python3 直接解析 PE 内的 UTF-16LE 版本资源字符串块,并对 CompanyName 逐字符核验码点:

1
2
3
4
5
import re
data = open('winaudio.exe','rb').read()
tail = data[0xF090:0xF380].decode('utf-16-le','ignore')
m = re.search(r'CompanyName\x00*([^\x00]+)', tail)
print(m.group(1)) # -> Micros0ft Corporation

摘录(StringFileInfo 全部字段)

1
2
3
4
5
6
7
8
CompanyName      = 'Micros0ft Corporation'          <-- 实际值:第7个字符是数字零 U+0030,不是字母 o
FileDescription = 'Windows Audio Device Graph'
FileVersion = '10.0.19041.1'
InternalName = 'winaudio'
LegalCopyright = '(c) Micros0ft Corporation. All rights reserved.'
OriginalFilename = 'winaudio.exe'
ProductName = 'Windows Audio Component'
ProductVersion = '10.0.19041.1'

CompanyName 值串原始字节(hexdump,0xF112 起):

1
2
3
4
00F112: 4d 00 69 00 63 00 72 00   M i c r
00F11A: 30 00 66 00 74 00 20 00 0 f t (空格) <-- 30 00 = '0' U+0030(数字零)
00F122: 43 00 6f 00 72 00 70 00 C o r p
... "o f t Corporation"

推理

  • 版本号 10.0.19041.1(Windows 10 build 19041)、文件描述 “Windows Audio Device Graph”、产品名 “Windows Audio Component” 均在模仿 Windows 系统自带音频组件,属典型的版本资源伪装。
  • CompanyName 与 LegalCopyright 两处一致地把字母 o 写成数字零 0(Micros0ft),为样本作者有意使用的变体拼写;题目要求”按实际值填写”,故答案取字段原始值。

最终答案

Micros0ft Corporation(即伪装 Microsoft / 微软公司;注意其中是数字零 0,非字母 o)

待归题号:winaudio.exe 防重复运行互斥体的名称

题目原文:通过对 winaudio.exe 分析,程序为防止重复运行创建了互斥体,互斥体的名称是什么?[答案格式:按实际值填写]

  • 证据类型:Windows PE 可执行文件(程序功能分析)
  • 检材来源:同上一题 winaudio.exe(MD5 6cdd957eb59f0dae88fa372c96d29586)
  • 关键证据/关键路径:调用点 sub_14000B1D0 @ VA 0x14000b228(CreateMutexA(0i64, 1, v158));密文位于 .rdata 段 unk_14000E5E0(RVA 0xE5E0,文件偏移 0xC7E0),共 20 字节

提取方法

互斥体名在 IDA 字符串表中不存在明文(全量核验 list_strings),属于运行时解码的混淆数据。定位过程:import thunk(CreateMutexA @ VA 0x14000B1B0)的 xref 查询在该分析环境下不可用,改为对全部 172 个函数批量 Hex-Rays 反编译并正则检索 “mutex”,唯一命中即主函数 sub_14000B1D0。其伪代码相关片段:

1
2
3
4
5
for ( i = 0i64; i != 20; i += 4i64 )                       // VA 0x14000b1f4–0x14000b20b
*(_DWORD *)&v158[i] = *(_DWORD *)((char *)&unk_14000E5E0 + i) ^ 0x3F3F3F3F; // DWORD 粒度 XOR 0x3F
v158[20] = 0; // VA 0x14000b220
CreateMutexA(0i64, 1, v158); // VA 0x14000b228(lpAttributes=NULL,bInitialOwner=TRUE)
if ( GetLastError() == 183 ) return 0i64; // VA 0x14000b239:ERROR_ALREADY_EXISTS → 直接退出

即:把 0xC7E0 起的 20 字节密文逐字节 XOR 0x3F(以 DWORD 为单位加载、与 0x3F3F3F3F 异或,等价于逐字节),补 NUL 后作为互斥体名传入。本地 Python3 解码:

1
2
3
data = open('winaudio.exe','rb').read()
raw = data[0xC7E0:0xC7E0+20] # 7853505d5e53637e737e6a7b7e1276716c120f0e
print(''.join(chr(b ^ 0x3F) for b in raw)) # -> Global\ALAUDA-INS-01

摘录(密文与解码对照)

1
2
3
raw @file 0xC7E0 : 78 53 50 5d 5e 53 63 7e 73 7e 6a 7b 7e 12 76 71 6c 12 0f 0e
XOR 0x3F : 'G' 'L' 'o' 'b' 'a' 'l' '\' 'A' 'L' 'A' 'U' 'D' 'A' '-' 'I' 'N' 'S' '-' '0' '1'
=> Global\ALAUDA-INS-01 (其后紧跟 0x00 NUL,长度与 v158[20] 完全一致)

推理

  • GetLastError()==183(ERROR_ALREADY_EXISTS)时立即返回,是标准的”单实例互斥体”防重复运行手法;带 Global\ 前缀使对象位于全局命名空间,跨会话也能阻止多开。
  • 旁证:样本内 base64 混淆串解码结果含 ...OPS-ALAUDA-2024,与互斥体名中的家族标识 ALAUDA 相互印证。

最终答案

Global\ALAUDA-INS-01(含 Global\ 前缀;密文 @文件偏移 0xC7E0,逐字节 XOR 0x3F)