NikitaNekhay/malware-analysis-report-cape
GitHub: NikitaNekhay/malware-analysis-report-cape
这是一份基于 CAPEv2 沙箱的恶意软件分析课程实验报告,完整演示了动态沙箱分析、Volatility 内存取证和静态逆向工程三种方法在分析 Themida 加壳样本时的协作与对比。
Stars: 0 | Forks: 0
# CCF 实验 3 — 沙箱与恶意软件分析
**报告名称:** `Sandboxing_LAB_3_Nikita_Niakhai`
**课程:** 取证
**执行人:** *Nikita Niakhai*
**提交日期:** 2026-04-28
**宿主机 OS:** Ubuntu Linux 6.8.0-110-generic
**Hypervisor:** QEMU/KVM via virt-manager
**沙箱:** CAPEv2
**分析虚拟机:** Windows 10 x64 (win10.qcow2)
## 环境概述
本实验在一台 Ubuntu 桌面机(SNE 实验室 PC,同时具有第二主要用户 `victor`)上运行,使用 `root` 和 `nikita` 用户。分析虚拟机隔离在 host-only 桥接网络上。CAPE 通过同一网络控制该虚拟机。
虚拟机管理器选择了 `Virtual Manager`。
**架构**
```
Host — 192.168.100.1 (virbr0)
└── win10 VM — 192.168.100.10 (static)
└── agent.py listening on :8000
└── reports back to resultserver at 192.168.100.1:2042
```
# 任务 1 — 准备工作
## 1.1 沙箱选择
**CAPEv2** (Config And Payload Extraction) 被选为沙箱解决方案。
关键原因:
- Cuckoo Sandbox 的活跃分支,定期更新
- 内置 PE 解包和 payload 提取引擎 — CAPE 可以解包加壳样本,并自动提交提取出的 payload 进行重新分析
- 原生支持 .NET 和 Themida
- 开箱即用的 YARA 和社区签名匹配
- 自托管,无样本隐私顾虑
安装:
```
git clone https://github.com/kevoreilly/CAPEv2 /opt/CAPEv2
cd /opt/CAPEv2
sudo -u cape poetry install
```
CAPE 作为一组独立的服务运行:
| 服务 | 角色 |
|---|---|
| `cape.service` | 核心调度器、虚拟机控制器、Hook 注入器 |
| `cape-web.service` | 端口 8000 上的 Web 仪表板 |
| `cape-processor.service` | 分析后报告生成 |
| `cape-rooter.service` | 每次分析的网络路由 |
| `mongodb.service` | 报告存储 |
| `postgresql@18-main.service` | 任务和元数据库 |
## 1.2 虚拟机设置
分析虚拟机在由 virt-manager 管理的 QEMU/KVM 下运行 Windows 10 x64。
| 参数 | 值 |
|---|---|
| OS | Windows 10 x64 |
| CPU | 3 vCPUs,host-passthrough 模式 |
| RAM | 6 GB |
| 磁盘 | `/var/lib/libvirtimages/win10.qcow2` |
| 机器类型 | pc-q35-6.2 |
| 磁盘总线 | SATA |
## 1.3 网络配置
虚拟机连接到 `virbr0` — 位于 `192.168.100.1/24` 的 libvirt 管理桥接。该虚拟机具有静态 IP `192.168.100.10`。
libvirt 默认网络启用了 NAT 转发。这意味着:
- 虚拟机可以通过宿主机访问互联网 — 这对于在网络日志中捕获 C2 回调非常有用
- 对于勒索软件等破坏性样本,应禁用 NAT 以保持虚拟机完全隔离

*图 1.1 — 宿主机上位于 192.168.100.1/24 的 virbr0 适配器*

*图 1.2 — libvirt NAT 网络配置*
指向虚拟机的 CAPE 配置:
```
# /opt/CAPEv2/conf/kvm.conf
[kvm]
machines = win10
interface = virbr0
[win10]
label = win10
platform = windows
ip = 192.168.100.10
snapshot = snapshot1
interface = virbr0
resultserver_ip = 192.168.100.1
resultserver_port = 2042
arch = x64
tags = win10
```
```
# /opt/CAPEv2/conf/cuckoo.conf
[resultserver]
ip = 192.168.100.1
port = 2042
```
## 1.4 CAPE Agent 设置
CAPE agent (`agent.py`) 在 Windows 虚拟机内部运行,充当 CAPE 在客户机中的操作手。它从 CAPE 接收 Hook DLL,执行样本,并将行为数据发送回结果服务器。
虚拟机内部的要求:
- 必须以管理员身份运行 — Hook 注入需要提升的权限
- 必须禁用 Windows 防火墙 — 否则端口 8000 会被阻止
文件通过宿主机上的 Python HTTP 服务器经 `virbr0` 网络传输到虚拟机:

*图 1.3 — 使用 `python3 -m http.server` 通过 virbr0 将 agent.py 传送到虚拟机*
在虚拟机内部(管理员 PowerShell):
```
netsh advfirewall set allprofiles state off
python C:\agent.py
```
从宿主机验证连接性:
```
nc -z -w2 192.168.100.10 8000 && echo "AGENT OK"
```

*图 1.4 — agent.py 在管理员 PowerShell 中的端口 8000 上监听*
## 1.5 CAPE 仪表板
服务运行后,可通过宿主机浏览器访问 Web 仪表板。

*图 1.5 — 显示活动任务队列的 CAPE 仪表板*

*图 1.6 — 从宿主机打开的仪表板,确认网络连接性*
## 1.6 快照
CAPE 需要处于 `running` 状态的 libvirt 快照 — 必须在 agent 已在内部活动时捕获虚拟机。CAPE 在每次分析运行之间恢复此快照,以保证环境干净。
```
virsh snapshot-create-as \
--domain win10 \
--name snapshot1 \
--description "CAPE clean state with agent running" \
--atomic
```
`--atomic` 标志是必需的,因为磁盘使用 SATA 总线 — SATA 不支持实时快照。`--atomic` 会短暂暂停虚拟机,拍摄快照,然后恢复。
```
# 验证 state = running (CAPE 在启动时会检查此项)
virsh snapshot-info win10 snapshot1
```

*图 1.7 — virsh 确认 snapshot1 处于运行状态*

*图 1.8 — `systemctl status cape.service` 显示为 active 且无错误*
## 1.7 设置过程中遇到的问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| `cape.service` 崩溃:"snapshot not found" | 尚不存在快照 | 使用 `virsh snapshot-create-as` 创建了 `snapshot1` |
| `cape.service` 崩溃:resultserver IP 不匹配 | 配置中是 `ip = 192.168.1.1` 而不是 `192.168.100.1` | 更新了 `cuckoo.conf` 中的 resultserver IP |
| 快照状态是 `shutoff` 而不是 `running` | 虚拟机暂停时在没有 `--atomic` 的情况下拍摄了快照 | 使用 `--atomic` 标志重新创建了快照 |
| Agent 未以管理员身份运行 | 从普通终端启动 | 移至管理员 PowerShell — Hook 需要提升的权限 |
# 任务 2 — 恶意软件样本
分析了两个样本。第二个是在分析第一个样本时由 CAPE 自动发现的。
## 样本 1 — 外部释放器/加载器
从 **MalwareBazaar** 下载。

*图 2.1 — 外部释放器的 MalwareBazaar 下载页面*

*图 2.2 — 确认 Zip 存档存在于 Downloads 文件夹中*

*图 2.3 — 使用密码 `infected` 提取(MalwareBazaar 标准)*
| 字段 | 值 |
|---|---|
| SHA256 | `560eebed...` |
| 类型 | PE32 .NET assembly (x86), GUI |
| 角色 | 外部释放器 — 解包并启动内部 payload |
## 样本 2 — 嵌套 Payload(由 CAPE 提取)
CAPE 的提取引擎在第一次分析运行期间发现了打包在样本 1 中的第二个 PE 二进制文件。它被自动存储并提交以进行单独分析。
| 字段 | 值 |
|---|---|
| SHA256 | `0ba17c89e787fee76c372b36e8db40ffc31f96420ae882a78f603e5c5e228005` |
| MD5 | `4b4b5334b25f14402d7d236e2c49713d` |
| 类型 | PE32 可执行文件 (GUI) Intel 80386, Mono/.NET assembly |
| 大小 | 1,107,456 字节 |
| Packer | Themida(商业保护器/DRM) |
| 来源 | 在任务 1 分析期间由 CAPE 从样本 1 中提取 |
这个嵌套的 PE 是实验其余部分的主要分析对象。
# 任务 3 — 沙箱分析
## 3.1 提交样本 1 — 行为捕获
样本 1 使用 CLI 工具提交给 CAPE:
```
cd /opt/CAPEv2
sudo -u cape .cache/pypoetry/virtualenvs/capev2-t2x27zRb-py3.10/bin/python \
utils/submit.py /opt/CAPEv2/storage/binaries/560eebed... \
--timeout 240 --enforce-timeout
```

*图 3.1 — submit.py 调用确认样本已作为任务 1 排队*

*图 3.2 — 具有不同选项组合的三个任务已排队等待外部释放器*

*图 3.3 — 实时 cape.service 日志:虚拟机快照已恢复,样本已注入,监控处于活动状态*
### 结果 — 样本 1
| 字段 | 值 |
|---|---|
| 恶意评分 | 2.0 / 10 |
| 捕获的进程 | 0 |
| 网络活动 | 无 |
| 提取的 Payload | 1 (样本 2) |
触发的签名:
| 签名 | 严重性 | 含义 |
|---|---|---|
| `packer_entropy` | 中 | 高熵节 — 二进制文件被加壳或加密 |
| `pe_compile_timestomping` | 高 | PE 时间戳是伪造的 — 故意的反取证 |
外部释放器执行后,将其 payload 解包到内存中并退出 — 这一切都在 CAPE 的 Hook 层能够观察到任何行为之前完成。唯一有用的输出是提取出的嵌套 PE。

*图 3.4 — 所有三个初始任务已完成。恶意评分 2.0,行为数据为零。*
## 3.2 提交样本 2 — 混淆逃避与对抗尝试
CAPE 发现了嵌套的 PE 并将其标记为需要单独分析。它作为任务 4 发送。

*图 3.5 — CAPE 报告发现 payload;已作为任务 4 自动提交*
样本 2 使用 **Themida** 加壳 — 这是一种商业保护器,既用于软件 DRM,也受到恶意软件作者的青睐。Themida 在解压缩和运行真实代码之前会执行一系列环境检查。如果它检测到沙箱或调试器,就会静默退出。
在样本 2 上检测到的逃避技术:
| 签名 | 技术 |
|---|---|
| `packer_themida` | Themida 保护器包装 |
| `antisandbox_cuckoocrash` | 通过名称或特征检测 CAPE/Cuckoo |
| `antide_guardpages` | 用于检测调试器的内存保护页 |
| `antidebug_outputdebugstring` | 通过 OutputDebugString 进行时间检查 |
| `antidebug_windows` | IsDebuggerPresent / NtQueryInformationProcess |
| `mouse_movement_detect` | 检查真实的鼠标输入 |
| `antisandbox_foregroundwindows` | 检查是否有真实窗口处于前台 |
| `antisandbox_sleep` | 长时间睡眠调用以超过沙箱超时时间 |
| `antisandbox_script_timer` | 检测加速的计时器 |
| `antiav_servicestop` | 尝试停止 AV/EDR 服务 |
| `stealth_network` | 隐藏网络活动 |
| `disable_driver_via_blocklist` | 阻止安全驱动程序加载 |
| `pe_compile_timestomping` | 伪造的编译时间戳 |
总共有 13 种逃避技术 — 这是一个异常高的数量,与 Themida 的 DRM 级别保护相符。
## 3.3 击败沙箱逃避 — 四次尝试
### 尝试 1 — 默认 CAPE Hook(任务 4)
带有完整 Hook 注入的标准提交。Themida 立即检测到了 Hook 特征并退出。
**结果:** 恶意评分 2.0,0 个进程,0 个网络活动。
### 尝试 2 — 宽松选项(任务 5)
使用旨在看起来更像真实系统的选项重新提交:
```
free=yes — disables CAPE hooks entirely
human=1 — simulates mouse movement
sleep=1 — patches sleep calls so Themida can't outlast timeout
clock=... — fakes system date
```

*图 3.7 — 应用了逃避对抗选项的 CAPE 提交表单*
`free=yes` 移除了 Themida 检测到的 Hook 特征。但结果是一样的 — Themida 仍然在没有执行的情况下退出了。
**结果:** 恶意评分 2.0,0 个进程,0 个网络活动。
结论:Hook 检测不是唯一的问题。Themida 还检测到了 QEMU 虚拟机本身。
### 尝试 3 和 4 — 虚拟机硬件硬化(任务 6 和 7)
Themida 通过四个主要向量检测 QEMU:
- **CPUID hypervisor 位** — KVM 在 CPU ID 响应中设置了一个标志,指示存在 hypervisor
- **SMBIOS 字符串** — QEMU 在任何应用程序都可读的 BIOS/主板信息中放入 "QEMU"
- **MAC 地址 OUI** — QEMU 使用注册给 QEMU 的 OUI 前缀 `52:54:00`
- **磁盘序列号** — Windows 设备管理器将该设备显示为 "QEMU HARDDISK"
修改了 libvirt 虚拟机 XML 以欺骗全部四个向量:
```
American Megatrends Inc.
F.71
09/14/2021
HP
HP EliteBook 840 G8 Notebook PC
CND1471B3M
WD-WCC4N2RKV8F3
```
应用方式:
```
virsh define /tmp/win10.xml
```
虚拟机重新启动以应用 SMBIOS 更改。

*图 3.6 — 虚拟机重新配置后 virsh snapshot-list 确认 snapshot1 处于运行状态*
任务 6 和 7 针对硬化后的虚拟机提交。

*图 3.9 — 尽管虚拟机已硬化,两项任务仍以零行为数据完成*

*图 3.10 — 从 CAPE 下载的任务 6 JSON 报告*

*图 3.11 — 任务 6 报告确认:零签名,零进程,零网络活动*

*图 3.8 — 任务 4 结果:恶意评分 2.0,0 个进程,0 个网络活动 — 与之前所有运行相同*
**结果:** 仍然一无所获。任务 6 和 7 的恶意评分均为 2.0,0 个进程,0 个网络活动。
### 为什么硬化仍然失败
在解决了四个向量之后,Themida 仍然检测到了该环境。剩余的检测点包括:
- **RDTSC 计时** — 测量 CPUID 指令之间的时钟周期。即使使用 host-passthrough CPU,虚拟机开销也是可测量的,因为 hypervisor 仍然会拦截某些指令
- **注册表特征** — QEMU/VirtIO 驱动程序键仍然存在于 `HKLM\SYSTEM\CurrentControlSet\Enum\` 下
- **SATA 控制器名称** — Windows 设备管理器仍然显示 QEMU SATA 控制器型号名称
- **进程扫描** — Themida 可能检查 CAPE 的监控进程或 agent 本身
### 所有四次尝试的总结
| 任务 | 选项 | 结果 |
|---|---|---|
| 4 | 默认 Hook,管理员 agent | 0 个进程,0 个网络活动 |
| 5 | free=yes, human=1, sleep=1 | 0 个进程,0 个网络活动 |
| 6 | 硬化虚拟机 (SMBIOS + MAC + KVM 隐藏) | 0 个进程,0 个网络活动 |
| 7 | 相同硬化虚拟机,第二次运行 | 0 个进程,0 个网络活动 |
**结论:** Themida 的反虚拟机层对于在 QEMU/KVM 上使用可用选项进行自动化沙箱分析来说过于深层。动态分析完全失败。静态分析是剩下的唯一方法。
## 3.4 内存转储与 Volatility 分析
由于样本逃避了所有沙箱运行,因此在 Windows 虚拟机的分析后状态下拍摄了内存转储。这捕获了完整的 Windows 环境:进程、网络连接、加载的模块以及任何注入的代码。
### 获取转储
```
virsh dump win10 /home/nikita/Downloads/win10_memdump.raw --memory-only
```
转储大小:**6.1 GB** — 与为虚拟机配置的 6 GB RAM 相匹配。
### 步骤 1 — OS 识别 (`windows.info`)
```
vol -f /home/nikita/Downloads/win10_memdump.raw windows.info
```
第一步始终是确认 Volatility 能正确解析转储并识别 OS 版本。这确立了所有后续插件使用的内存配置文件。

*图 4.1 — Volatility 确认 Windows 10 x64 Build 19041,3 个 CPU,正确的内核基地址*
**结果:** 确认 Windows 10 x64 Build 19041。转储有效且可解析。
### 步骤 2 — 进程列表 (`windows.pslist`)
```
vol -f /home/nikita/Downloads/win10_memdump.raw windows.pslist
```
列出内核 EPROCESS 双向链表中的所有进程。这是 Windows 维护的主要进程列表。显示 PID、PPID、名称、启动时间和退出时间。
需要注意的事项:
- 仿冒名称(如 `scvhost.exe` 对比 `svchost.exe`)
- 没有父进程的进程(孤儿进程)
- 已退出的进程 — 运行后终止的恶意软件

*图 4.2 — 转储时的完整进程列表*

*图 4.3 — 在 pslist 中可见的 powershell.exe (PID 3480) 和 python.exe (PID 5048)*

*图 4.4 — agent 链条条目的延续*
值得注意的进程:
| PID | 名称 | PPID | 备注 |
|---|---|---|---|
| 3480 | `powershell.exe` | 4108 (explorer) | 用于启动 agent 的管理员 PowerShell |
| 5048 | `python.exe` | 3480 | CAPE agent — `.\agent.py`,32 位 (Wow64=True) |
| 3128 | `MsMpEng.exe` | 688 (services) | Windows Defender — 活动状态,27 个线程 |
| 5420 | `svchost.exe` | 688 (services) | 于 09:54:27 退出,0 个线程,命令行为空 |
没有仿冒的进程名称。没有孤儿进程。已退出的 `svchost.exe` 是正常的 — 它是一个已完成服务的临时宿主进程。
### 步骤 3 — 进程树 (`windows.pstree`)
```
vol -f /home/nikita/Downloads/win10_memdump.raw windows.pstree
```
以父子层次结构的形式显示相同的进程。用于发现可疑的衍生链 — 例如,`winword.exe` 启动 `powershell.exe`,或 `explorer.exe` 衍生未知的子进程。

*图 4.5 — 完整的进程树*

*图 4.6 — agent 启动链在树中清晰可见*
关键链条:
```
explorer.exe (4108)
└── powershell.exe (3480) — admin PowerShell
├── python.exe (5048) — CAPE agent (.\agent.py)
└── conhost.exe (396) — console host
```
所有进程均可追溯到合法的系统祖先。没有异常的父子关系。
### 步骤 4 — 命令行 (`windows.cmdline`)
```
vol -f /home/nikita/Downloads/win10_memdump.raw windows.cmdline
```
从 Process Environment Block (PEB) 中提取每个进程的完整命令行字符串。揭示投放的文件路径、编码的 PowerShell payload 以及恶意软件参数。

*图 4.7 — 所有进程的完整 cmdline 输出*

*图 4.8 — PID 5048:`"...Python311-32\python.exe" .\agent.py` — 交互式启动的 agent*
值得注意的条目:
| PID | 进程 | 命令 |
|---|---|---|
| 5048 | python.exe | `"...Python311-32\python.exe" .\agent.py` |
| 3976 | slui.exe | `SLUI.exe RuleId=3482d82e... Action=AutoActivate Trigger=NetworkAvailable` |
| 5420 | svchost.exe | *(空 — 已退出的进程,PEB 已清除)* |
没有编码的 PowerShell。在预期位置之外没有投放的路径。Agent 是从 PowerShell 工作目录交互式运行的 — 而不是作为计划任务安装的。
### 步骤 5 — 网络连接 (`windows.netscan`)
```
vol -f /home/nikita/Downloads/win10_memdump.raw windows.netscan
```
扫描内存以查找 TCP/UDP 端点结构 — 活动的、已关闭的和正在监听的套接字,包含远程 IP、端口和拥有进程。用于发现 C2 通信的主要插件。

*图 4.9 — 完整的 netscan 输出*

*图 4.10 — python.exe (5048) 在 0.0.0.0:8000 上 LISTENING — agent 套接字*

*图 4.11 — CLOSED 条目:192.168.100.1:59252 → 192.168.100.10:8000 — CAPE 宿主机在任务执行期间连接到 agent*

*图 4.12 — 从 svchost.exe 到 Akamai CDN 和 Microsoft 的 ESTABLISHED 连接 — Windows Update 和遥测流量*
发现:
| 连接 | 拥有者 | 结论 |
|---|---|---|
| LISTENING `0.0.0.0:8000` |.exe (5048) | CAPE agent 套接字 |
| CLOSED `192.168.100.1:59252 → 192.168.100.10:8000` | python.exe | 分析期间连接的 CAPE 宿主机 |
| LISTENING `0.0.0.0:445`, `0.0.0.0:139` | System (PID 4) | Windows SMB — 标准 |
| ESTABLISHED 到 `23.38.x.x`, `72.145.x.x` | svchost.exe | 通过 Akamai CDN 的 Windows Update |
| ESTABLISHED 到 `65.52.241.40:443` | smartscreen.exe | Microsoft SmartScreen 云检查 |
| CLOSED 到 `48.192.1.65:443` | slui.exe | Windows 激活尝试 |
**没有恶意软件的 C2 连接。** 每个出站连接都属于与 Microsoft 或 Akamai 基础设施通信的合法 Windows 进程。Themida 在任何 payload 网络代码运行之前就退出了。
### 步骤 6 — 注入代码检测 (`windows.malfind`)
```
vol -f /home/nikita/Downloads/win10_memdump.raw windows.malfind
```
查找可执行的、私有的(磁盘上没有文件支持)并且包含类似 shellcode 字节模式的内存区域。这是检测进程注入和反射 DLL 加载的主要插件。

*图 4.13 — malfind 结果 — 所有命中都在合法的系统进程中*
结果:
| 进程 | PID | 命中数 | 结论 |
|---|---|---|---|
| `MsMpEng.exe` | 3128 | 12 | 误报 — Windows Defender JIT 引擎 |
| `SearchApp.exe` | 4612 | 2 | 误报 — .NET CLR JIT 调度存根 |
| `smartscreen.exe` | 3840 | 1 | 误报 — .NET CLR JIT 存根 |
| `powershell.exe` | 3480 | 5 | 误报 — PowerShell 是一个 .NET 应用,CLR 分配了 RWX 区域 |
| 恶意软件样本 | — | 0 | 无注入特征 |
所有 20 次命中都得到了解释。`MsMpEng.exe` 的模式在所有 12 次命中中完全相同:
```
55 48 8d 2c 24 48 83 ec 20 48 8b 01 48 8b 49 08
ff d0 48 8d 65 00 5d c3 cc cc cc cc cc cc cc cc
```
这是一个标准的 x64 函数序言,后跟 `INT3` 填充 (`cc`) — 一个已编译的 Defender 扫描存根,而不是 shellcode。`cc` 填充正是触发 malfind 启发式算法的原因。
**关键发现:** 任何进程的私有内存中都没有 MZ 头。没有 shellcode。Themida 干净地退出,没有向宿主进程注入任何东西。
### 步骤 7 — 加载的 DLL (`windows.dlllist`)
```
vol -f /home/nikita/Downloads/win10_memdump.raw windows.dlllist --pid 5048
```
从 PEB 加载器列表中列出加载到 CAPE agent 进程中的所有 DLL。用于验证没有意外模块被注入到 agent 中。

*图 4.14 — 加载到 python.exe (5048) 中的所有 DLL*
加载的关键模块:
| DLL | 用途 |
|---|---|
| `python311.dll` | Python 3.11 运行时 |
| `_socket.pyd` | 网络套接字模块 |
| `_ssl.pyd` + `libssl-1_1.dll` | TLS/SSL — agent 加密结果流量 |
| `_ctypes.pyd` + `libffi-8.dll` | 通过 ctypes 直接调用 Windows API |
| `IPHLPAPI.DLL` | 网络接口查询 |
| `wow64.dll / wow64win.dll` | WoW64 桥接 — 64 位 OS 上的 32 位进程 |
两个实际上是预期中的异常:
- `ntdll.dll` 在不同的基地址出现两次 — WoW64 进程的正常现象(32 位和 64 位的 ntdll 都被映射)
- 许多 DLL 显示 LoadTime 为 `1601-01-01` — 未初始化的 PEB 时间戳字段,在 WoW64 中常见
没有意外 DLL。没有从临时路径或异常位置加载的模块。
### Volatility 总结
| 插件 | 关键发现 |
|---|---|
| `windows.info` | Windows 10 Build 19041, x64,转储有效 |
| `windows.pslist` | 100 多个进程,全部合法;agent 在 PID 5048 可见 |
| `windows.pstree` | explorer → powershell → python.exe 链条已确认,无异常 |
| `windows.cmdline` | Agent 作为 `.\agent.py` 交互式启动;没有编码的 PowerShell |
| `windows.netscan` | Agent 套接字在 :8000;CAPE 握手可见;所有外部流量均为 Windows 遥测 |
| `windows.malfind` | 20 次命中,全部是 Defender 和 .NET CLR 的 JIT 误报 |
| `windows.dlllist` | 所有 agent DLL 均符合预期;无注入模块 |
**总体:** 内存转储确认,在四次分析运行中的任何一次中,都没有恶意软件活动达到注入或执行阶段。Themida 的保护在任何 payload 运行之前就干净地退出了该进程。
## 3.5 在线沙箱比较
与 CAPEv2 一起评估了两个外部平台:**ANY.RUN** 和 **Hybrid Analysis**(由 CrowdStrike Falcon Sandbox 提供支持)。
### ANY.RUN
ANY.RUN 是一个交互式沙箱 — 与自动化工具不同,分析师可以通过浏览器实时控制运行中虚拟机的鼠标和键盘。
主要功能:
- 分析期间的实时鼠标和键盘输入 — 这直接击败了 `mouse_movement_detect` 和 `antisandbox_foregroundwindows`
- 每个进程的 MITRE ATT&CK 技术映射
- 带有 DNS 和 TLS 检查的完整 PCAP
- 实时流量上的 Suricata IDS 规则和 YARA
- 可配置的 OS 区域设置、屏幕分辨率、已安装软件
- 限制:基于云 — 某些 APT 恶意软件会检查云 IP 范围并拒绝运行
免费层:仅限公开提交,60 秒超时。
### Hybrid Analysis (Falcon Sandbox)
完全自动化,由 CrowdStrike 的全球威胁情报提供支持。
主要功能:
- 将结果与 CrowdStrike 的全球 IOC 数据库进行交叉比对
- 完整的 ATT&CK 矩阵映射
- 执行前进行深度静态字符串扫描 — 如果 payload 与已知家族匹配,则无需运行即可返回结论
- 限制:无实时交互 — 对于 Themida 级别的样本,具有与 CAPEv2 相同的逃避弱点
### 比较
| 功能 | CAPEv2 (本地) | ANY.RUN | Hybrid Analysis |
|---|---|---|---|
| 样本 2 的行为数据 | 零 — Themida 逃避 | 可能部分 — 人类交互绕过了一些检查 | 可能为零 — 完全自动化 |
| 逃避对抗 | 手动虚拟机硬化 | 内置交互模拟 | 不可用 |
| 嵌套 PE 提取 | 是 — 自动提取了样本 2 | 否 | 否 |
| 网络捕获 | 宿主机上的完整 PCAP | 完整 PCAP + TLS 解码 | 完整 PCAP |
| 内存分析 | 通过 Volatility 手动进行 | 未暴露 | 未暴露 |
| 样本隐私 | 完全本地 | 样本上传到云端 | 样本上传到云端 |
| 虚拟机自定义 | 完全控制 — SMBIOS, CPUID, MAC | 供应商控制 | 最小 |
| 成本 | 免费(自托管) | 高级功能需付费 | 私密提交需付费 |
### 结论
- 当逃避是问题所在时,**ANY.RUN** 是最佳选择。真实的鼠标输入可以绕过击败所有自动化工具的检查。对于样本 2,在 ANY.RUN 上交互式运行它的分析师可能已经获得了行为数据。
- **Hybrid Analysis** 对于已知的恶意软件家族非常强大 — 威胁情报数据库可以仅从静态模式返回结论。
- **CAPEv2** 是唯一为我们提供嵌套 PE 提取、通过 Volatility 进行完整内存访问以及对虚拟机环境完全控制的平台。对于深度研究和敏感样本,本地是正确的选择。
这三种方法是互补的。ANY.RUN 用于对抗逃避样本。Hybrid Analysis 用于针对已知家族的快速分类。CAPEv2 用于深度、私密、可配置的分析。
# 任务 4 — 静态分析
由于动态分析在四次尝试中产生了零行为数据,静态分析是唯一剩下的选择。所有工具均在宿主机上运行。目标:`0ba17c89...`(样本 2,Themida 加壳的嵌套 PE)。
使用的工具:`file`、`pefile` (Python)、`strings`、`binwalk`、`rabin2`、`r2` (radare2)。
## 步骤 1 — 文件识别
```
file /home/nikita/Downloads/sample2.exe
```

*图 5.1 — `file` 输出:PE32 可执行文件,GUI,Mono/.NET assembly*
输出:`PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows`
- 32 位 Windows GUI 可执行文件
- 输出中的 `.Net assembly` 表示该二进制文件包含 .NET 元数据 — 即使它被加壳,PE 头仍然带有 .NET 标记
- GUI 子系统 — 无控制台窗口,设计为桌面应用程序运行
## 步骤 2 — PE 头和节区熵
```
python3 /home/nikita/Downloads/pe_analysis.py
```
该脚本读取 PE 头并计算每个节区的 Shannon 熵。

*图 5.2 — pe_analysis.py 输出,显示头、节区和熵值*
头字段:
| 字段 | 值 | 含义 |
|---|---|---|
| Entrypoint | `0x0010f93e` | 单跳转存根 — 无真实代码 |
| ImageBase | `0x00400000` | 标准 Windows 默认值 |
| Timestamp | `0x8c8a4ae1` = 2044 年 9 月 | 未来日期 — 故意的时间戳伪造 |
| Subsystem | `2` = Windows GUI | 桌面应用程序,无控制台 |
节区熵:
| 节区 | 大小 | 熵 | 结论 |
|---|---|---|---|
| `.text` | 1.05 MB | **7.87 / 8.0** | Themida 加密 — 接近最大值 |
| `.rsrc` | 2 KB | 3.60 | 正常资源数据 |
| `.reloc` | 12 字节 | 0.10 | 几乎为空 — 加壳二进制文件特征 |
正常编译代码的熵值约为 4.5–6.5。7.87 是加密或压缩的取证定义。整个代码节区都是一个密文块,无法以静态形式反汇编。
导入:
```
mscoree.dll → _CorExeMain (only import)
```
一个函数。Themida 在运行时动态解析其所有 API 调用 — 导入表中什么也没有出现,因为真实的导入逻辑位于加密节区内部。
## 步骤 3 — 字符串提取
```
strings -n 6 /home/nikita/Downloads/sample2.exe \
| grep -E "^[A-Za-z0-9 _.\-\\/\:]{6,}$" | sort -u
```
尽管代码节区的熵值高达 7.87,但偏移量 `0x1E000` 下方的 .NET 元数据区域并未加密,并泄露了可读字符串。

*图 5.3 — 过滤后的 strings 输出,显示来自 .NET 元数据的多个可读命名空间*
**这些字符串揭示了 payload 的真实身份。**

*图 5.4 — `MagnetosphereSimulator.Form*.resources` — 应用程序名称和 UI 表单命名空间*
应用程序身份:
| 字符串 | 含义 |
|---|---|
| `MagnetosphereSimulator` | 应用程序名称 |
| `Orbital Plasma Labs` | 作者/公司 |
| `1.0.5.1` | 应用程序版本 |
| `v4.0.30319` | .NET Framework 4.0 运行时 |
在 MSIL 元数据中可见的科学功能:
| 方法/命名空间 | 用途 |
|---|---|
| `ComputeDipoleField` | 地球磁偶极子模型 |
| `ComputeGyroFrequency` | 子回旋频率计算 |
| `ComputeLShell` | L-shell(磁纬度) |
| `ComputeDriftPeriod` | 范艾伦带漂移周期 |
| `ComputeBowShockRe` | 弓形激波 standoff 距离 |
| `ComputeMagnetopauseStandoffRe` | 磁层顶边界 |
| `DrawBowShock`, `DrawMagnetopause`, `DrawBelts` | 可视化引擎 |
| `DrawSolarWindArrows`, `DrawTrajectories` | 粒子轨迹渲染 |
| 粒子类型:`Proton`、`Electron`、`Helium`、`Oxygen` | 多物种模拟 |
这是一个功能完备的 GUI 物理应用程序。不是恶意软件。
其他关键字符串:

*图 5.5 — 在二进制文件中发现的 `PADPADP` — 已知的 Themida 内部填充标记*

*图 5.6 — `tWQZ.exe` — 随机生成的文件名,可能是外部释放器的原始名称*
| 字符串 | 意义 |
|---|---|
| `PADPADP` | Themida 内部填充标记 — 明确的 Themida 确认 |
| `tWQZ.exe` | 随机文件名 — 可能是外部释放器的原始名称 |
## 步骤 4 — 熵图
```
binwalk -E /home/nikita/Downloads/sample2.exe
```
生成可视化熵图,显示熵在整个文件中的变化情况。

*图 5.7 — 偏移量 0x1E000 处的急剧熵上升标志着 Themida 加密节区的开始*
| 偏移范围 | 熵 | 区域 |
|---|---|---|
| `0x0 → 0x1E000` | ~0.48 | PE 头和 .NET 元数据 — 可读 |
| `0x1E000 → 0x107400` | ~0.98 | Themida 加密的 `.text` — 955 KB 密文 |
| `0x107400 → EOF` | ~0.68 | `.rsrc` 资源 — 部分结构化 |
`0x1E000` 处的急剧上升正是 Themida 加密开始的精确字节位置。97.7% 的熵在统计上与随机数据难以区分。
## 步骤 5 — PE 元数据
```
rabin2 -I /home/nikita/Downloads/sample2.exe
```

*图 5.8 — rabin2 PE 元数据:编译日期、语言、签名状态、校验和字段*
关键字段:
| 字段 | 值 | 含义 |
|---|---|---|
| `compiled` | Mon Sep 19 04:49:37 2044 | 时间戳伪造 — 由 rabin2 独立确认 |
| `lang` | `cil` | .NET CIL 字节码 |
| `signed` | `false` | 无有效代码签名 — 已破解或修改的二进制文件 |
| `hdr.csum` | `0x00000000` | PE 校验和已清零 |
| `cmp.csum` | `0x0011e0c4` | 计算出的真实校验和 |
`hdr.csum` (0) 和 `cmp.csum` (0x0011e0c4) 之间的不匹配是被修补二进制文件的取证指纹。当软件被破解时,修补工具通常会将 PE 校验和清零,而不是正确地重新计算它。
`canary=true` 和 `nx=true` — 这些来自最初的合法构建,并在破解过程中被保留下来。
## 步骤 6 — 导入表
```
rabin2 -i /home/nikita/Downloads/sample2.exe
```

*图 5.9 — 单个导入:mscoree.dll → _CorExeMain*
输出:
```
1 0x00402000 mscoree.dll _CorExeMain
```
一个导入。Themida 的所有 API 调用都是通过其自身在运行时基于哈希的查找在内部解析的。真正重要的实际 IAT 被加密在 `.text` 内部。
## 步骤 7 — 节区映射
```
rabin2 -S /home/nikita/Downloads/sample2.exe
```

*图 5.10 — 三个节区:.text (1.05 MB)、.rsrc (2 KB)、.reloc (12 字节)*
```
.text 0x00402000 size=0x10da00 vsize=0x10e000 -r-x
.rsrc 0x00510000 size=0x800 vsize=0x2000 -r--
.reloc 0x00512000 size=0x200 vsize=0x2000 -r--
```
磁盘上的 `.text` 是 `-r-x`(不可写)。在运行时,Themida 调用 `VirtualProtect` 临时将其标记为可写,原地解密真实的 payload,然后恢复 `-r-x`。这是标准的原地解包技术。
## 步骤 8 — 入口点反汇编
```
r2 -q -c 'pd 30' /home/nikita/Downloads/sample2.exe 2>/dev/null
```

*图 5.11 — 入口点:跳转到 _CorExeMain 的单个 jmp,随后是被误读为操作码的加密空字节*
输出:
```
;-- entry0:
0x0050f93e ff2500204000 jmp dword [sym.imp.mscoree.dll__CorExeMain]
0x0050f944 0000 add byte [eax], al ; encrypted bytes
0x0050f946 0000 add byte [eax], al ; misread as instructions
...
```
一条指令:跳转到 .NET CLR 入口点。之后的所有内容都是 `0x00 0x00`,来自被误读为 x86 操作码的加密节区。Themida 的解密循环完全在运行时的加密节区内部运行 — 没有任何东西可以进行静态反汇编。
## 静态分析结论 — 真实样本身份
静态分析将 payload 识别为 **Orbital Plasma Labs 的 MagnetosphereSimulator v1.0.5.1** — 一个用于地球磁层和范艾伦带模拟的破解商业科学应用程序。它不是传统的恶意软件。
Themida 被用作 **DRM(数字版权管理)** 来保护软件许可证,而不是为了隐藏恶意行为。这解释了动态分析中的每一个异常:
| 观察 | 解释 |
|---|---|
| 13 种反沙箱技术 | Themida DRM 检查虚拟机以防止许可证绕过 |
| 没有 C2,没有破坏性行为 | 没有恶意 payload — Themida 在保护合法软件 |
| 时间戳伪造 | 被破解的软件混淆其来源 |
| `hdr.csum = 0x00000000` | 修补工具在破解过程中将校验和清零 |
| `signed = false` | 代码签名因修补而失效 |
| 在 4 次尝试中拒绝在 QEMU 中运行 | Themida DRM 专门设计用于检测虚拟机 |
## 动态与静态分析 — 哪个效果更好?
| | 动态 (CAPEv2) | 静态 (CLI 工具) |
|---|---|---|
| **发现** | 外部释放器结构,嵌套 PE 提取,13 个逃避签名 | 真实应用程序身份,Themida 确认,时间戳伪造,修补后的校验和,版本,作者 |
| **遗漏** | 关于内部 payload 的所有信息 | 运行时行为,解密密钥,实际执行流程 |
| **优势** | 真实行为 — 网络 IoC,进程链,注册表更改 | 无法逃避 — 文件存在于磁盘上,元数据始终可读 |
| **劣势** | Themida/DRM 击败了所有自动化分析 | 如果不脱壳,加密节区无法进行反汇编 |
对于这个特定样本,静态分析的效果要好得多。沙箱运行了该二进制文件 4 次却一无所获。一个 `strings` 命令在几秒钟内就识别出了应用程序名称、作者和版本。
话虽如此,这两种方法是互补的。对于实际执行的恶意软件 — 勒索软件、RAT、窃密木马 — 动态分析会产生静态分析永远无法找到的 IoC(网络地址、投放的文件、注册表键、进程链)。对于加壳或受 DRM 保护的软件,未加密元数据的静态分析能给出任何沙箱调整都无法产生的答案。
# 附录 — 命令参考
```
# CAPE 服务
sudo systemctl restart cape.service cape-processor.service
sudo systemctl status cape.service --no-pager
# VM 管理
virsh list --all
virsh domstate win10
virsh snapshot-list win10
virsh snapshot-info win10 snapshot1
virsh snapshot-create-as --domain win10 --name snapshot1 --atomic
# 验证 agent
nc -z -w2 192.168.100.10 8000 && echo "AGENT OK"
# 提交 sample
cd /opt/CAPEv2
sudo -u cape .cache/pypoetry/virtualenvs/capev2-t2x27zRb-py3.10/bin/python \
utils/submit.py /path/to/sample.exe --timeout 240 --enforce-timeout
# Memory dump
virsh dump win10 /home/nikita/Downloads/win10_memdump.raw --memory-only
# Volatility
vol -f /home/nikita/Downloads/win10_memdump.raw windows.info
vol -f /home/nikita/Downloads/win10_memdump.raw windows.pslist
vol -f /home/nikita/Downloads/win10_memdump.raw windows.pstree
vol -f /home/nikita/Downloads/win10_memdump.raw windows.cmdline
vol -f /home/nikita/Downloads/win10_memdump.raw windows.netscan
vol -f /home/nikita/Downloads/win10_memdump.raw windows.malfind
vol -f /home/nikita/Downloads/win10_memdump.raw windows.dlllist --pid 5048
# Static analysis
file /home/nikita/Downloads/sample2.exe
python3 /home/nikita/Downloads/pe_analysis.py
strings -n 6 /home/nikita/Downloads/sample2.exe | grep -E "^[A-Za-z0-9 _.\-\\/\:]{6,}$" | sort -u
binwalk -E /home/nikita/Downloads/sample2.exe
rabin2 -I /home/nikita/Downloads/sample2.exe
rabin2 -i /home/nikita/Downloads/sample2.exe
rabin2 -S /home/nikita/Downloads/sample2.exe
r2 -q -c 'pd 30' /home/nikita/Downloads/sample2.exe 2>/dev/null
```
标签:CAPEv2, Cloudflare, Cuckoo Sandbox, DAST, KVM, MITRE ATT&CK, .NET分析, PE脱壳, Python, QEMU, Themida, virt-manager, Windows 10, YARA, 主机专用网络, 云资产可视化, 云资产清单, 内联执行, 威胁情报, 安全实验, 安全报告, 实验报告, 开发者工具, 恶意样本分析, 恶意软件分析, 搜索语句(dork), 数字取证, 数据包嗅探, 无后门, 无线安全, 沙箱, 沙箱逃逸, 测试用例, 网络安全, 网络安全审计, 网络隔离, 自动化脚本, 虚拟化, 负载提取, 逆向工具, 逆向工程, 隐私保护