初学者如何分析真实的恶意样本?Hancitor 实战全流程记录
字数 3409
更新时间 2026-04-01 15:59:55

Hancitor恶意样本分析实战教学文档

1. 样本背景与基本信息

  • 样本家族: Hancitor
  • 样本类型: 32位DLL文件
  • 主要功能: 远控木马 (C2类型)
  • SHA256哈希: 8ff43b6ddf6243bd5ee073f9987920fa223809f589d151d7e438fd8cc08ce292
  • 来源与下载: 可于MalwareBazaar平台获取,微步情报中心有记录,为2021年样本。

2. 初步信息收集与加壳判断

  1. 查看区段信息: 使用PE-bear等工具查看PE文件区段,发现.data段的原始大小与虚拟大小差异显著,这通常提示文件可能被加壳。
  2. 查看信息熵: 使用DIE等查壳工具查看样本的信息熵,高熵值进一步支持存在加密/压缩壳的推测。
  3. 查看导出函数: 分析DLL导出表,发现一个名为Callrun的函数,推测为恶意代码的自定义主入口函数。

3. 动态调试与脱壳

目标: 获取内存中解密后的真实载荷。

3.1 调试环境与启动

  1. 调试器: x32dbg (样本为32位)。
  2. 调试目标: 运行rundll32.exe并加载恶意DLL样本。
  3. 命令行示例:
    "C:\Windows\SysWOW64\rundll32.exe" C:\Users\Administrador\Desktop\sample_1.bin,#1
    
    (#1对应导出函数序号,需根据实际情况调整路径和序号)。

3.2 设置关键API断点

在调试会话中,在以下三个Windows API函数上设置断点,它们是恶意软件解壳和代码注入过程中的关键节点:

  • VirtualAlloc (在函数退出点RET指令处下断点)

    • 作用: 申请新的内存区域。加壳程序通常在此处申请内存,用于存放解密后的代码或Payload。
    • 操作: 中断后,查看EAX寄存器,其值为新分配内存的起始地址。此地址是后续监控和Dump数据的关键。
  • VirtualProtect (在函数开始处下断点)

    • 作用: 修改内存区域的保护属性(如,从PAGE_READWRITE改为PAGE_EXECUTE_READ)。
    • 意义: 当代码解密完成,需要执行时,恶意软件会调用此API为内存添加可执行权限。在此处中断,通常意味着解密工作已完成,即将跳转到原始入口点(OEP)。
  • ResumeThread (在函数开始处下断点)

    • 作用: 恢复一个被挂起的线程。
    • 关联技术: 常与进程镂空(Process Hollowing) 技术结合使用。恶意软件创建挂起的合法进程,注入自身代码后,调用此函数使恶意代码在合法进程的掩护下执行。在此处中断是拦截注入行为的最后机会。

3.3 脱壳与Dump过程

  1. 定位解密后内存: 在调试器中按F9运行,程序会在VirtualAlloc断点处停下。记录EAX中的地址。重复此过程,直到在VirtualProtect处中断。观察VirtualProtect调用前的内存内容,在ASCII视图中出现“MZ”等PE文件头标志,表明解密成功。
  2. 内存转储(Dump): 在内存布局窗口中找到包含解密后PE数据的内存区域,使用调试器的“内存转到文件”或类似功能,将指定范围的内存数据Dump到本地文件。

3.4 PE文件修复

  1. 定位PE头: 使用十六进制编辑器(如010 Editor)打开Dump下来的文件,搜索MZ(4D 5A)和PE(50 45 00 00)标志,定位到有效PE头的起始位置。
  2. 裁剪无效数据: 删除PE头之前的所有无关数据,保存文件。
  3. 验证: 用PE分析工具查看修复后的文件,应能看到完整的导入表(如出现WININET.dll等网络相关API),表明已获得可分析的解包后载荷。

4. 静态分析 (使用IDA Pro)

目标: 分析核心功能、信息收集、配置解密与C2通信逻辑。

4.1 主逻辑分析

  • 主任务轮询器: 函数sub_100013F6()是主逻辑函数,内部包含一个循环。每轮执行完任务后,会调用Sleep()函数休眠约120秒,然后继续下一轮。

4.2 主机信息收集

恶意软件会收集以下信息,拼接成字符串后上报给C2服务器。

  • GUID生成 (sub_10001CFF, sub_10001652):

    • 调用GetAdaptersAddresses获取所有网络适配器的PhysicalAddress (MAC地址)。
    • 将MAC地址逐字节进行异或累积运算,生成一个唯一值作为受害者主机的GUID。
    • 计算结果被缓存,后续上报使用。
  • 身份信息构造 (sub_10002406):

    • 构造格式为 计算机名@域名\用户名 的字符串。
    • 关键点: 用户名并非直接获取当前进程用户,而是通过枚举explorer.exe进程并读取其Token,来获取当前交互式桌面用户的用户名。这增加了隐蔽性。
  • 公网IP获取 (sub_10001C45):

    • 通过访问 http://api.ipify.org 来获取受害者的公网IP地址。
    • 获取结果会缓存到全局缓冲区。如果获取失败,则使用 0.0.0.0 作为默认值。

4.3 配置解密流程

核心解密函数为 sub_10001CB7()sub_10002131()

  1. 数据来源: 解密目标为样本内部偏移 unk_10004018 处的0x2000字节密文数据。
  2. 密钥派生:
    • 使用种子密钥 pbData,其内容为固定字节序列: [0xC5, 0x8B, 0x00, 0x15, 0x7F, 0x8E, 0x92, 0x88]
    • 调用CryptAcquireContextA获取CSP上下文。
    • 调用CryptCreateHash创建CALG_SHA1哈希对象。
    • 调用CryptHashData,将pbData作为输入,计算其SHA1哈希值。
    • 调用CryptDeriveKey,以SHA1哈希值为基础,派生CALG_RC4算法的密钥。参数0x280011u表示密钥长度为40位(5字节) (高位0x28),并设置CRYPT_EXPORTABLECRYPT_NO_SALT标志。
  3. 执行解密:
    • 调用CryptDecrypt,使用上一步派生的RC4流密钥,对unk_10004018处的密文进行原地解密
  4. 解密结果: 解密得到明文字符串,格式示例如下:
    1910_nsw http://newnucapi.com/8/forum.php|http://gintlyba.ru/8/forum.php|http://stralonz.ru/8/forum.php|
    
    • 该字符串包含了木马的通信基础设施配置,即一个或多个C2服务器的URL。

4.4 数据上报流程

  1. 请求体构造: 函数wsprintfA将收集到的所有信息拼接成HTTP POST请求体,格式大致为:
    GUID=%I64u&BUILD=%s&INFO=%s&EXT=%s&IP=%s&TYPE=1&WIN=%d.%d(x32)
    
    • 参数依次为:主机GUID、版本信息、主机身份信息(计算机名@域名\用户名)、扩展信息、公网IP、类型标识、操作系统版本。
  2. HTTP通信 (sub_10001E3B):
    • 使用WinINet库函数(InternetOpenA, InternetConnectA, HttpOpenRequestA)建立HTTP连接。
    • 调用HttpSendRequestA,以POST方法将拼接好的请求体发送到解密得到的C2 URL。
    • 调用HttpQueryInfoA检查HTTP响应状态码是否为200。
    • 调用InternetReadFile读取C2服务器返回的响应数据。

5. 总结分析

该Hancitor样本的分析流程遵循了经典的恶意软件分析方法:

  1. 初步评估: 通过哈希确认样本,利用静态特征(区段、熵值)初步判断存在加壳。
  2. 动态脱壳: 通过调试器对关键内存分配(VirtualAlloc)和权限变更(VirtualProtect)API下断,捕获内存中解密的Payload并Dump。
  3. 文件修复: 对Dump数据进行裁剪,修复为合法的PE文件以供静态分析。
  4. 静态剖析: 使用IDA Pro分析主循环、信息收集、配置解密和网络通信模块。
  5. 核心解密: 逆向出配置数据的加密方案:使用固定的8字节种子数据,经SHA1哈希后取前5字节作为RC4密钥,对密文进行解密,最终获取C2地址。
  6. 行为还原: 明确了其作为远控木马的行为链:收集主机指纹、用户身份、网络信息 -> 解密C2配置 -> 构造HTTP请求 -> 与C2服务器建立通信。
相似文章
相似文章
 全屏