1. 静态分析PE文件基础

任务目标

对一个已知恶意样本(sample.exe)执行静态分析:使用DIE(Detect It Easy)识别其编译器/加壳器,并通过解析PE导入表判断样本可能的功能。本案例聚焦于静态分析的基础流程,不涉及动态执行。

环境准备

  • 操作系统:Windows 10/11 或 Linux(以下命令以Linux为例,Windows下使用对应GUI或命令行版本)
  • 工具:die(Detect It Easy,命令行版本)、python3、pefile库(pip install pefile)
  • 样本:一个已知的恶意PE文件(如远程访问木马RAT样本),本案例使用sample.exe作为占位文件名

实现步骤与代码

第一步,使用DIE识别加壳器/编译器。第二步,使用Python的pefile库提取导入表并输出关键信息。以下代码完成导入表提取与功能推断:

import pefile
import sys

def analyze_imports(file_path):
    """提取PE导入表并输出关键DLL与函数,推断可能功能"""
    try:
        pe = pefile.PE(file_path)
    except Exception as e:
        print(f"[!] 无法解析PE文件: {e}")
        return

    print(f"[*] 文件: {file_path}")
    print(f"[*] 入口点地址: 0x{pe.OPTIONAL_HEADER.AddressOfEntryPoint:X}")
    print(f"[*] 镜像基址: 0x{pe.OPTIONAL_HEADER.ImageBase:X}")

    # 节区信息(辅助判断加壳:异常节区名或熵值高)
    print("\n[*] 节区列表:")
    for section in pe.sections:
        name = section.Name.decode('utf-8', errors='replace').rstrip('\x00')
        entropy = section.get_entropy()
        print(f"    {name:10s} 虚拟大小: 0x{section.Misc_VirtualSize:X} 熵: {entropy:.2f}")

    # 导入表
    if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
        print("\n[*] 导入表:")
        suspicious_funcs = []
        for entry in pe.DIRECTORY_ENTRY_IMPORT:
            dll_name = entry.dll.decode('utf-8', errors='replace')
            print(f"  DLL: {dll_name}")
            for imp in entry.imports:
                if imp.name:
                    func_name = imp.name.decode('utf-8', errors='replace')
                    print(f"      {func_name}")
                    # 收集敏感API用于功能推断
                    if any(kw in func_name.lower() for kw in ['socket', 'send', 'recv', 'url', 'http', 'connect', 'createprocess', 'winhttp', 'internetopen']):
                        suspicious_funcs.append(f"{dll_name}!{func_name}")
                else:
                    print(f"      (序号: {imp.ordinal})")
        if suspicious_funcs:
            print("\n[+] 发现敏感API调用:")
            for f in suspicious_funcs:
                print(f"    {f}")
        else:
            print("\n[-] 未发现明显网络/进程操作相关API")
    else:
        print("\n[-] 无导入表(可能已加壳或纯资源型样本)")

    pe.close()

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("用法: python3 analyze_pe.py <样本路径>")
        sys.exit(1)
    analyze_imports(sys.argv[1])

DIE命令行识别加壳器(若样本已加壳,导入表通常被压缩或加密,此时上述脚本可能只显示少量系统DLL):

die -d sample.exe   # 深度扫描模式

运行与验证

  1. 保存上述代码为analyze_pe.py,在样本所在目录执行:python3 analyze_pe.py sample.exe
  2. 观察输出:若样本未加壳,导入表应列出完整DLL和函数;若加壳,节区熵值通常高于7.0且导入表仅包含LoadLibraryA/GetProcAddress等少量API。
  3. 结合DIE结果判断:DIE显示“Microsoft Visual C++ 6.0”且导入表包含ws2_32.dll的socket/send/recv,则高度怀疑是网络通信型恶意代码;若DIE显示“UPX”或“ASPack”,则需先脱壳再分析。

通过条件:能正确输出样本的编译器/加壳器类型,并基于导入表列出至少3个关键API调用,且能据此给出功能倾向(如网络后门、键盘记录、下载器)。若样本加壳导致导入表不可见,则通过节区熵值和DIE结果说明加壳事实,并指出需脱壳后继续分析。

PE静态分析决策流程 恶意样本 sample.exe 步骤1: DIE 检测 识别编译器 / 加壳器类型 是否加壳? (熵值>7.0 / 节区异常) 是(加壳) 需先脱壳 否(未加壳) 直接分析导入表 脱壳后重新检测 步骤2: 提取导入表 pefile 解析 DLL 与 API 函数 功能推断: 网络通信 / 文件操作 / 进程注入 / 持久化

常见问题

  • DIE检测为“未知”:尝试die -d深度扫描,或使用die -e显示熵值辅助判断;若仍无法识别,可能为自定义壳或编译语言较新。
  • 导入表为空:样本可能加壳或使用延迟导入。加壳样本需先脱壳(如UPX可用upx -d);延迟导入需在运行时解析,静态分析阶段可跳过。
  • 误报风险:某些合法软件也调用socket或CreateProcess,需结合样本来源、数字签名、节区异常等综合判断,不可仅凭单个API定论。