APT 恶意 DLL 分析及 C2 配置提取(母 DLL 篇)
字数 2335 2025-08-06 20:12:41

APT 恶意 DLL 分析及 C2 配置提取技术详解

1. 样本基础信息

1.1 样本IOC

  • MD5: e5fcf505c25e66116f288a8ae28d2c8a
  • SHA1: e597f6439a01aad82e153e0de647f54ad82b58d3
  • SHA256: 63996a39755e84ee8b5d3f47296991362a17afaaccf2ac43207a424a366f4cc9

2. 动态获取技术分析

2.1 动态获取DLL基址技术

实现步骤

  1. 获取PEB结构
  2. 定位到LDR结构
  3. 遍历InLoadOrderModuleList链
  4. 比较BaseDllName
  5. 最终获取DllBase

关键偏移

  • PEB → 0xC → 0xC → 0x30(遍历) → 0x18

2.2 动态获取导出函数基址技术

PE结构解析流程

  1. 定位到PE头(DOS头 + 0x3c)
  2. 从PE文件头中找到数据目录表(PE头 + 0x78)
  3. 获取导出表(数据目录表第一项)
  4. 从导出表(IMAGE_EXPORT_DIRECTORY)中获取NumberOfNames字段(导出表 + 0x18)
  5. 定位AddressOfNames字段(导出表 + 0x20)
  6. 定位AddressOfNameOrdinals字段(导出表 + 0x24)
  7. 定位AddressOfFunctions字段(导出表 + 0x1c)

关键偏移

  • DOS头(DLL基址) → 0x3c → 0x78 → 0x0 → 0x18 → 0x20 → 0x24 → 0x1c

3. PE文件内存映像操作技术

3.1 PE文件结构基础知识

节的属性

  • 代码段:通常不允许修改
  • 数据段:允许读写
  • 常量段:只读
  • 特殊节:
    • .data?:磁盘中不存在,内存中存在
    • .reloc:磁盘中存在,内存中被抛弃

对齐规则

  • 文件对齐:通常为512字节(200h)
  • 内存对齐:
    • 32位系统:4KB(1000h)
    • 64位系统:8KB(2000h)

3.2 PE内存映像操作流程

操作步骤

  1. 定位PE结构

    • 从解密出的DLL文件开始
    • 0x3c处e_lfanew字段定位PE头
    • 检查ASCII "PE"标识(0x4555)
  2. 解析PE头

    • PE头 + 0x4:IMAGE_FILE_HEADER.Machine字段(应为14c,表示Intel 386架构)
    • PE头 + 0x38:IMAGE_OPTIONAL_HEADER32.SectionAlignment(获取内存对齐粒度)
    • PE头 + 0x14:IMAGE_FILE_HEADER.SizeOfOptionalHeader(获取扩展头大小)
  3. 定位节表

    • 节表位置 = PE头 + 0x18(IMAGE_FILE_HEADER大小) + SizeOfOptionalHeader
  4. 解析节表

    • 节表 + 0xc:IMAGE_SECTION_HEADER.VirtualAddress(节区RVA)
    • 节表 + 0x10:IMAGE_SECTION_HEADER.SizeOfRawData(文件中对齐后尺寸)
    • 每个节表项大小为40字节,+0x28可遍历下一个节表
  5. 内存操作

    • 申请空间
    • 划分区域
    • 填充数据
    • 分配段属性

4. 恶意行为分析

4.1 主要行为流程

  1. 开辟空间并解密内层核心DLL(文件格式)
  2. 检索系统信息(GetNativeSystemInfo)
  3. 检查参数:
    • 获取命令行(GetCommandLineW)
    • 截取逗号后字符
    • 比较是否为"DllRegisterServer"(lstrcmpiw)
  4. 拼接参数并开启线程:
    • 获取系统路径(SHGetFolderPathA)
    • 获取模块文件名(GetModuleFileName)
    • 格式化字符串:L"%s\rundll32.exe "%s",DllRegisterServer"
    • 创建进程(CreateProcessW)

4.2 函数调用链

  1. 分配空间

    • malloc → free
  2. PE内存映像操作

    • VirtualAllocExNuma → memcpy → malloc → "data_operation" → "PE文件" → VirtualAlloc(文件头和每个节表各一次) → VirtualProtect(除.reloc节表外各一次) → VirtualFree(释放.reloc段)
  3. 系统操作

    • GetNativeSystemInfo → GetCommandLineW → 截取参数 → lstrcmpiw → SHGetFolderPathA → GetModuleFileName → sprintfw → CreateProcessW

5. 母DLL与子DLL关联分析

5.1 关联机制

  1. 母DLL解密子DLL并进行PE内存映像操作
  2. 进入子DLL的入口点
  3. 获取并拼接路径和参数
  4. 开启新进程运行母DLL的DllRegisterServer导出函数
  5. 实际功能过渡到子DLL的相同导出函数中执行

5.2 执行流程

  1. 母DLL初始化
  2. 解密并加载子DLL
  3. 参数传递和验证
  4. 功能执行转移到子DLL
  5. 最终恶意操作执行

6. 防御检测建议

  1. 检测点

    • 异常的PE内存操作序列
    • 动态获取API的异常模式
    • 多层DLL加载行为
    • 异常的rundll32调用模式
  2. 防护措施

    • 监控关键API调用序列
    • 分析DLL的导出函数行为
    • 检查异常的进程创建模式
    • 关注.reloc节的异常处理
  3. IOC扩展

    • 监控文中提到的HASH值
    • 检测类似的API调用链
    • 分析异常的PE结构操作
APT 恶意 DLL 分析及 C2 配置提取技术详解 1. 样本基础信息 1.1 样本IOC MD5 : e5fcf505c25e66116f288a8ae28d2c8a SHA1 : e597f6439a01aad82e153e0de647f54ad82b58d3 SHA256 : 63996a39755e84ee8b5d3f47296991362a17afaaccf2ac43207a424a366f4cc9 2. 动态获取技术分析 2.1 动态获取DLL基址技术 实现步骤 : 获取PEB结构 定位到LDR结构 遍历InLoadOrderModuleList链 比较BaseDllName 最终获取DllBase 关键偏移 : PEB → 0xC → 0xC → 0x30(遍历) → 0x18 2.2 动态获取导出函数基址技术 PE结构解析流程 : 定位到PE头(DOS头 + 0x3c) 从PE文件头中找到数据目录表(PE头 + 0x78) 获取导出表(数据目录表第一项) 从导出表(IMAGE_ EXPORT_ DIRECTORY)中获取NumberOfNames字段(导出表 + 0x18) 定位AddressOfNames字段(导出表 + 0x20) 定位AddressOfNameOrdinals字段(导出表 + 0x24) 定位AddressOfFunctions字段(导出表 + 0x1c) 关键偏移 : DOS头(DLL基址) → 0x3c → 0x78 → 0x0 → 0x18 → 0x20 → 0x24 → 0x1c 3. PE文件内存映像操作技术 3.1 PE文件结构基础知识 节的属性 : 代码段:通常不允许修改 数据段:允许读写 常量段:只读 特殊节: .data?:磁盘中不存在,内存中存在 .reloc:磁盘中存在,内存中被抛弃 对齐规则 : 文件对齐:通常为512字节(200h) 内存对齐: 32位系统:4KB(1000h) 64位系统:8KB(2000h) 3.2 PE内存映像操作流程 操作步骤 : 定位PE结构 : 从解密出的DLL文件开始 0x3c处e_ lfanew字段定位PE头 检查ASCII "PE"标识(0x4555) 解析PE头 : PE头 + 0x4:IMAGE_ FILE_ HEADER.Machine字段(应为14c,表示Intel 386架构) PE头 + 0x38:IMAGE_ OPTIONAL_ HEADER32.SectionAlignment(获取内存对齐粒度) PE头 + 0x14:IMAGE_ FILE_ HEADER.SizeOfOptionalHeader(获取扩展头大小) 定位节表 : 节表位置 = PE头 + 0x18(IMAGE_ FILE_ HEADER大小) + SizeOfOptionalHeader 解析节表 : 节表 + 0xc:IMAGE_ SECTION_ HEADER.VirtualAddress(节区RVA) 节表 + 0x10:IMAGE_ SECTION_ HEADER.SizeOfRawData(文件中对齐后尺寸) 每个节表项大小为40字节,+0x28可遍历下一个节表 内存操作 : 申请空间 划分区域 填充数据 分配段属性 4. 恶意行为分析 4.1 主要行为流程 开辟空间并解密内层核心DLL(文件格式) 检索系统信息(GetNativeSystemInfo) 检查参数: 获取命令行(GetCommandLineW) 截取逗号后字符 比较是否为"DllRegisterServer"(lstrcmpiw) 拼接参数并开启线程: 获取系统路径(SHGetFolderPathA) 获取模块文件名(GetModuleFileName) 格式化字符串:L"%s\rundll32.exe \"%s\",DllRegisterServer" 创建进程(CreateProcessW) 4.2 函数调用链 分配空间 : malloc → free PE内存映像操作 : VirtualAllocExNuma → memcpy → malloc → "data_ operation" → "PE文件" → VirtualAlloc(文件头和每个节表各一次) → VirtualProtect(除.reloc节表外各一次) → VirtualFree(释放.reloc段) 系统操作 : GetNativeSystemInfo → GetCommandLineW → 截取参数 → lstrcmpiw → SHGetFolderPathA → GetModuleFileName → sprintfw → CreateProcessW 5. 母DLL与子DLL关联分析 5.1 关联机制 母DLL解密子DLL并进行PE内存映像操作 进入子DLL的入口点 获取并拼接路径和参数 开启新进程运行母DLL的DllRegisterServer导出函数 实际功能过渡到子DLL的相同导出函数中执行 5.2 执行流程 母DLL初始化 解密并加载子DLL 参数传递和验证 功能执行转移到子DLL 最终恶意操作执行 6. 防御检测建议 检测点 : 异常的PE内存操作序列 动态获取API的异常模式 多层DLL加载行为 异常的rundll32调用模式 防护措施 : 监控关键API调用序列 分析DLL的导出函数行为 检查异常的进程创建模式 关注.reloc节的异常处理 IOC扩展 : 监控文中提到的HASH值 检测类似的API调用链 分析异常的PE结构操作