技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
performing-static-malware-analysis-with-pe-studio【数据与研究】使用 PEStudio 对 Windows PE(可移植可执行文件)恶意软件样本进行静态分析, 检查文件头、导入表、字符串、资源和指标,无需执行二进制文件。 识别可疑特征,包括加壳、反分析技术和恶意导入。适用于静态恶意软件分析、 PE 文件检查、Windows 可执行文件分析或执行前恶意软件分级等请求场景。
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
不适用于需要执行的动态行为分析;运行时行为观测请使用沙箱(Cuckoo、ANY.RUN)。
pefile 库进行脚本化 PE 分析(pip install pefile)生成加密哈希用于识别和情报查询:
# 生成 MD5、SHA-1 和 SHA-256 哈希
md5sum suspect.exe
sha1sum suspect.exe
sha256sum suspect.exe
# 对照 VirusTotal 检查哈希
curl -s -X GET "https://www.virustotal.com/api/v3/files/$(sha256sum suspect.exe | cut -d' ' -f1)" \
-H "x-apikey: $VT_API_KEY" | jq '.data.attributes.last_analysis_stats'
# 使用魔术字节验证获取文件类型
file suspect.exe
在 PEStudio 中打开样本并检查结构属性:
PEStudio 分析要点:
━━━━━━━━━━━━━━━━━━━━━━━━━
文件头: 编译时间戳、目标架构(x86/x64)
可选头: 入口点地址、镜像基址、子系统(GUI/控制台)
节表: 节名称、虚拟/原始大小、熵值
.text/.rsrc 中高熵(>7.0)提示加壳
签名: Authenticode 签名的存在与有效性
使用 pefile 进行脚本化 PE 头分析:
import pefile
import hashlib
import math
pe = pefile.PE("suspect.exe")
# 编译时间戳
import datetime
timestamp = pe.FILE_HEADER.TimeDateStamp
compile_time = datetime.datetime.utcfromtimestamp(timestamp)
print(f"编译时间:{compile_time} UTC")
# 带熵计算的节分析
for section in pe.sections:
name = section.Name.decode().rstrip('\x00')
entropy = section.get_entropy()
raw_size = section.SizeOfRawData
virtual_size = section.Misc_VirtualSize
ratio = virtual_size / raw_size if raw_size > 0 else 0
print(f"节:{name:8s} 熵:{entropy:.2f} 原始:{raw_size:>10} 虚拟:{virtual_size:>10} 比率:{ratio:.2f}")
if entropy > 7.0:
print(f" [!] 高熵 - 可能已加壳或加密")
if ratio > 10:
print(f" [!] 高虚拟/原始比率 - 可能存在解包桩")
识别揭示恶意软件能力的可疑 API 导入:
# 提取并分类导入
suspicious_imports = {
"进程注入": ["VirtualAllocEx", "WriteProcessMemory", "CreateRemoteThread", "NtCreateThreadEx"],
"键盘记录": ["GetAsyncKeyState", "SetWindowsHookExA", "GetKeyState"],
"持久化": ["RegSetValueExA", "CreateServiceA", "SchTasksCreate"],
"规避": ["IsDebuggerPresent", "CheckRemoteDebuggerPresent", "NtQueryInformationProcess"],
"网络": ["InternetOpenA", "HttpSendRequestA", "URLDownloadToFileA", "WSAStartup"],
"文件操作": ["CreateFileA", "WriteFile", "DeleteFileA", "MoveFileA"],
"加密": ["CryptEncrypt", "CryptDecrypt", "CryptAcquireContextA"],
}
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll_name = entry.dll.decode()
for imp in entry.imports:
if imp.name:
func_name = imp.name.decode()
for category, funcs in suspicious_imports.items():
if func_name in funcs:
print(f"[!] {category}:{dll_name} -> {func_name}")
使用 FLOSS 提取混淆字符串,并进行标准字符串提取:
# 标准字符串提取(ASCII 和 Unicode)
strings -a suspect.exe > strings_ascii.txt
strings -el suspect.exe > strings_unicode.txt
# 使用 FLOSS 提取解码/反混淆后的字符串
floss suspect.exe --output-json floss_output.json
# 在字符串中搜索网络指标
grep -iE "(http|https|ftp)://" strings_ascii.txt
grep -iE "([0-9]{1,3}\.){3}[0-9]{1,3}" strings_ascii.txt
grep -iE "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}" strings_ascii.txt
# 搜索注册表键
grep -i "HKLM\\|HKCU\\|SOFTWARE\\|CurrentVersion\\Run" strings_ascii.txt
# 搜索文件路径和扩展名
grep -iE "\.(exe|dll|bat|ps1|vbs|tmp)" strings_ascii.txt
检查 PE 资源节中嵌入的载荷或配置:
# 从 PE 文件中提取资源
if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
if hasattr(resource_type, 'directory'):
for resource_id in resource_type.directory.entries:
if hasattr(resource_id, 'directory'):
for resource_lang in resource_id.directory.entries:
data = pe.get_data(resource_lang.data.struct.OffsetToData,
resource_lang.data.struct.Size)
entropy = calculate_entropy(data)
print(f"资源类型:{resource_type.id} 大小:{len(data)} 熵:{entropy:.2f}")
if entropy > 7.0:
print(f" [!] 高熵资源 - 可能嵌入了载荷")
# 检查资源中的 PE 签名(嵌入的可执行文件)
if data[:2] == b'MZ':
print(f" [!] 在资源中检测到嵌入的 PE")
with open(f"extracted_resource_{resource_type.id}.bin", "wb") as f:
f.write(data)
确定二进制文件是否已加壳或受保护:
# 使用 Detect It Easy(DIE)检测加壳程序
diec suspect.exe
# 使用 PEiD 签名检查(命令行版本)
python3 -c "
import pefile
pe = pefile.PE('suspect.exe')
# 检查常见加壳程序节名称
packer_sections = {'.upx0': 'UPX', '.aspack': 'ASPack', '.adata': 'ASPack',
'.nsp0': 'NsPack', '.vmprotect': 'VMProtect', '.themida': 'Themida'}
for section in pe.sections:
name = section.Name.decode().rstrip('\x00').lower()
if name in packer_sections:
print(f'[!] 检测到加壳程序:{packer_sections[name]}(节:{name})')
# 检查导入表大小(极少导入提示可能已加壳)
import_count = sum(len(entry.imports) for entry in pe.DIRECTORY_ENTRY_IMPORT)
if import_count < 10:
print(f'[!] 只有 {import_count} 个导入 - 可能已加壳')
"
将所有发现汇总为结构化分级报告:
每个分析样本须记录以下内容:
- 文件标识(哈希、文件类型、大小、编译时间戳)
- 加壳/保护状态及已识别的加壳程序
- 按能力分类的可疑导入
- 从字符串中提取的网络指标(IP、域名、URL)
- 嵌入资源及其特征
- 整体威胁评估和建议后续步骤(沙箱执行、YARA 规则创建)
| 术语 | 定义 |
|---|---|
| PE(可移植可执行文件) | Windows 可执行文件(.exe、.dll、.sys)的文件格式,包含定义操作系统如何加载二进制文件的头、节、导入表和资源 |
| 导入地址表(IAT) | PE 结构,列出可执行文件在运行时调用的外部 DLL 函数;揭示程序能力和意图 |
| 节熵 | PE 节中随机性的统计度量;值超过 7.0(满分 8.0)表示存在压缩、加密或加壳 |
| FLOSS | FireEye Labs 混淆字符串求解器;自动提取和解码标准 strings 命令无法发现的混淆字符串 |
| 加壳 | 对 PE 文件代码节进行压缩或加密以阻碍静态分析;需要运行时解包桩才能执行 |
| PE 资源 | PE 文件中的数据节,可包含图标、对话框、版本信息,或攻击者嵌入的载荷和配置数据 |
| 编译时间戳 | PE 头中的时间戳,指示二进制文件的编译时间;可被伪造,但通常能揭示开发时间线 |
背景:SOC 收到关于钓鱼邮件中可疑可执行文件附件的告警。在投入沙箱资源前,需要对文件进行快速分级以确定是否恶意。
方法:
注意事项:
静态恶意软件分析报告
=================================
样本: suspect.exe
MD5: d41d8cd98f00b204e9800998ecf8427e
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
文件大小: 245,760 字节
文件类型: PE32 可执行文件(GUI)Intel 80386
编译时间: 2025-09-14 08:23:15 UTC
加壳状态
检测到加壳: 无(原生二进制文件)
节熵: .text=6.42 .rdata=4.89 .data=3.21 .rsrc=7.81
备注: .rsrc 节熵偏高 - 请检查资源
可疑导入
[注入] kernel32.dll -> VirtualAllocEx
[注入] kernel32.dll -> WriteProcessMemory
[注入] kernel32.dll -> CreateRemoteThread
[规避] kernel32.dll -> IsDebuggerPresent
[网络] wininet.dll -> InternetOpenA
[网络] wininet.dll -> HttpSendRequestA
[持久化] advapi32.dll -> RegSetValueExA
提取的指标
URL: hxxps://update.malicious[.]com/gate.php
IP: 185.220.101[.]42、91.215.85[.]17
注册表键: HKCU\Software\Microsoft\Windows\CurrentVersion\Run\svchost
文件路径: C:\Users\Public\svchost.exe
嵌入资源
资源 101: 大小=98304 熵=7.89 [!] 检测到嵌入的 PE
资源 102: 大小=4096 熵=2.14(配置 XML)
评估结果
威胁级别: 高
分类: 具有进程注入能力的投放器
建议措施: 在沙箱中执行,对嵌入的 PE 进行单独分析