跳转到帖子

逆向木马远控实战:从可疑 Windows 样本中提取 C2 配置、还原持久化并完成日志闭环

精选回复

发布于

背景

本文记录一次授权内网演练中的木马远控样本分析过程。终端告警显示,一台 Windows 业务主机在用户登录后周期性访问外部 HTTPS 地址,但代理日志中的请求没有明显业务特征。现场需要回答三个问题:样本如何启动、远控配置藏在哪里、哪些主机可能已经受到影响。

分析对象来自隔离终端中的可疑文件副本,不在生产环境直接运行。所有动态行为均在无外网、可回滚的虚拟机中观察,并通过模拟服务接收流量,避免真实连接攻击者基础设施。

样本逆向的重点不是证明它“有毒”,而是形成可落地的 IOC、行为链和修复范围。文件哈希只能定位同一个样本,持久化位置、配置解密特征和网络行为通常更适合横向排查。

问题定位

EDR 原始告警只给出了父子进程关系:explorer.exe 启动一个位于用户目录的程序,随后该程序访问外部 443 端口。先保全样本和关联证据,再开展逆向,避免清理动作破坏时间线。

mkdir C:\IR\case-042
copy "C:\Users\Public\Libraries\winupd.exe" C:\IR\case-042\sample.bin
certutil -hashfile C:\IR\case-042\sample.bin SHA256
sigcheck64.exe -nobanner -a -h -i C:\IR\case-042\sample.bin

reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run"
schtasks /query /fo LIST /v > C:\IR\case-042\tasks.txt
wevtutil epl Microsoft-Windows-Sysmon/Operational C:\IR\case-042\sysmon.evtx
wevtutil epl Microsoft-Windows-PowerShell/Operational C:\IR\case-042\powershell.evtx

取证时同时记录文件创建、修改时间以及采集人员和工具版本。若条件允许,应额外采集内存、DNS 缓存、当前连接和 Prefetch。不要先双击样本,也不要用字符串结果直接下结论。

静态技术分析

样本为 64 位 PE 文件,无有效数字签名,导入表较小,但同时出现 VirtualAlloc、VirtualProtect、CreateThread、WinHttpOpen 和 RegSetValueExW。节区熵值较高,说明存在压缩或加密数据。导入表过小本身不能证明恶意,需要结合入口点和动态解析 API 的逻辑继续确认。

在 Ghidra 中从入口点跟踪,样本先计算 API 名称哈希,再通过 PEB 遍历已加载模块并解析导出表。初始化完成后,它读取资源节中的一段数据,执行单字节异或和 Base64 解码,得到 JSON 配置。伪代码可归纳为:

key = blob[0]
for i in range(1, blob_len):
    decoded[i - 1] = blob[i] ^ key
config = base64_decode(decoded)

# 实际配置字段:
# host、port、uri、sleep、jitter、campaign

这类配置提取适合写成离线脚本,避免反复运行样本。下面脚本只解析已导出的资源数据,不包含执行、注入或联网逻辑:

import base64
import json
from pathlib import Path

blob = Path("resource.bin").read_bytes()
if len(blob) < 2:
    raise ValueError("resource blob is too short")

key = blob[0]
plain = bytes(b ^ key for b in blob[1:])
config = json.loads(base64.b64decode(plain).decode("utf-8"))

allowed = {"host", "port", "uri", "sleep", "jitter", "campaign"}
print(json.dumps({k: config.get(k) for k in allowed}, indent=2))

提取结果显示样本以固定 URI 发起 HTTPS 请求,基础休眠时间为 90 秒,并设置约 20% 抖动。配置中的域名只能作为待验证 IOC:可能已经失效、被接管或与正常共享基础设施重叠,不能不经核验直接全网封禁。

动态行为验证

动态分析环境采用快照虚拟机、Host-only 网络和模拟 DNS/HTTP 服务。虚拟机不配置生产凭据,不挂载共享目录,宿主机防火墙禁止实验网段访问互联网。使用 Procmon、Process Explorer、Sysmon 和 Wireshark 记录行为。

执行后观察到以下链路:

  • 样本复制自身到 %LOCALAPPDATA%\Microsoft\Cache\winupd.exe。
  • 写入 HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Windows Update Cache,实现当前用户登录持久化。
  • 创建互斥体,防止同一用户会话重复运行。
  • 读取主机名、用户名、系统版本和进程列表,并组装首次上线数据。
  • 按配置中的休眠与抖动周期访问固定 URI;失败后采用递增退避。

没有发现驱动加载或系统服务创建行为,说明该版本主要停留在当前用户权限边界。处置时仍需确认它是否窃取过高权限令牌或凭据,不能因为持久化位于 HKCU 就认定影响较低。

日志关联与影响面排查

优先从稳定行为建立查询条件:异常用户目录可执行文件、Run 键写入、周期性网络连接和相同 URI。Sysmon 建议至少采集 Event ID 1、3、11、13、22,并确保命令行、目标注册表值和 DNS 查询字段未被裁剪。

证据数据源用途
进程路径与父进程Sysmon Event ID 1、EDR还原启动链
目标 IP、端口、进程Sysmon Event ID 3、代理日志确认网络访问主体
落地文件Sysmon Event ID 11定位副本及首次出现时间
Run 键修改Sysmon Event ID 13确认持久化
域名解析Sysmon Event ID 22、DNS 日志扩大受影响主机范围

PowerShell 可用于快速核查单机持久化和文件哈希:

$run = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'
Get-ItemProperty $run | Format-List

$target = "$env:LOCALAPPDATA\Microsoft\Cache\winupd.exe"
if (Test-Path $target) {
    Get-Item $target | Select-Object FullName, Length, CreationTimeUtc, LastWriteTimeUtc
    Get-FileHash $target -Algorithm SHA256
    Get-AuthenticodeSignature $target
}

可将行为特征转换为 Sigma 规则。以下规则关注用户目录程序写入当前用户 Run 键,实际部署时需要排除经过审批的自启动软件:

title: Suspicious User Profile Binary Added To Current User Run Key
logsource:
  category: registry_set
  product: windows
detection:
  selection_key:
    TargetObject|endswith: '\Software\Microsoft\Windows\CurrentVersion\Run\Windows Update Cache'
  selection_image:
    Image|contains:
      - '\AppData\Local\'
      - '\Users\Public\'
  condition: selection_key and selection_image
level: high

对文件样本可使用偏保守的 YARA 规则做初筛。规则应组合 PE 特征、配置字段和持久化字符串,避免只凭域名命中:

rule Win_Remote_Control_Config_Family_042
{
    meta:
        purpose = "defensive triage"
        family = "case-042"
    strings:
        $mz = { 4D 5A }
        $run = "Software\\Microsoft\\Windows\\CurrentVersion\\Run" wide ascii
        $cfg1 = "campaign" ascii
        $cfg2 = "jitter" ascii
        $cfg3 = "sleep" ascii
        $mutex = "Global\\WinUpdateCache_" wide ascii
    condition:
        uint16(0) == 0x5A4D and
        $run and $mutex and 2 of ($cfg*)
}

扫描前先在已知正常软件仓库中测试误报率。若配置字符串在运行时才解密,磁盘 YARA 可能无法命中,此时应在受控取证流程中扫描内存转储,并结合进程路径和网络日志判断。

权限边界与风险判断

样本自身以普通用户权限运行,但风险不应只按当前完整性级别评估。需要继续检查以下事项:

  • 受影响用户是否属于本地管理员组,是否使用过运维账号登录。
  • 样本存活期间是否出现 LSASS 访问、浏览器凭据库读取或异常令牌复制。
  • 同一账号是否在其他主机发生交互式登录、远程服务创建或计划任务创建。
  • 代理和 DNS 日志中是否存在相同周期、URI 或 TLS 指纹的历史连接。
  • 是否存在第二阶段载荷;仅删除首个落地文件不能证明处置完成。

如果发现凭据访问证据,应按“凭据可能泄露”处理:隔离终端、吊销会话、轮换相关密码和密钥,并检查横向登录记录。不要在仍可能受控的主机上直接修改高权限账号密码。

处置与修复建议

  • 先在 EDR 或交换网络侧隔离主机,再终止恶意进程、导出内存和删除持久化项。
  • 清除 Run 键和落地副本后重启复核,检查计划任务、服务、WMI 永久事件订阅和启动目录是否还有替代持久化。
  • 在 DNS、代理和 EDR 中部署经过验证的域名、URI、证书及行为 IOC;对共享云基础设施避免只按 IP 阻断。
  • 将 Sysmon 配置覆盖到进程创建、网络连接、文件创建、注册表修改和 DNS 查询,并集中保存日志,防止本地日志被清除。
  • 限制用户目录可执行文件运行,可结合 WDAC 或 AppLocker 先审计再阻断;对确有业务需求的路径建立签名与发布者白名单。
  • 复核本地管理员成员、浏览器保存凭据、远程管理入口及服务账号使用情况,按证据决定是否重装系统。

修复完成的判断标准应包含:持久化不再出现、相关文件和进程消失、至少跨越多个原通信周期未再产生同类流量、账号与横向活动排查无新增异常、检测规则已经覆盖同类变种。

总结

这类远控样本的有效分析路径是:先保全证据,再通过静态逆向提取配置,使用隔离环境验证行为,最后把结果转换为可查询的日志特征和检测规则。单一哈希适合确认已知文件,但对改名、重新打包和配置变化抵抗力较弱。持久化位置、配置解密逻辑、进程链和周期性通信组合起来,才能形成更稳定的检测与修复闭环。

逆向分析与样本观察示意图
逆向分析、样本行为与调试流程示意
服务器与云环境安全示意图
服务器、云资产与权限边界梳理示意

这类样本建议把“静态配置、运行时明文、主机侧证据”分开记录,否则很容易把解密中间值或备用域名误判为实际 C2。

1. C2 配置不要只靠 strings

先确认样本使用 WinHTTP、WinINet、原始 Winsock,还是自行封装 TLS。对相关 API 下断点,在参数生成后读取内存,通常比硬追解密算法省时间:

WinHttpOpenRequest
WinHttpConnect
WinHttpSendRequest
InternetConnectW
HttpOpenRequestW
connect
getaddrinfo
CryptDecrypt
BCryptDecrypt

x64dbg 中命中 WinHttpConnect 时,x64 调用约定下重点看 RDX 指向的主机名及 R8 的端口;命中 connect 时检查 RDX 指向的 sockaddr。同时对解密后缓冲区设置硬件写入断点,回溯配置来源。建议记录“原始偏移、解密算法、运行时地址、实际网络连接”四项,避免只给出孤立 IOC。

若怀疑配置藏在资源、overlay 或高熵节区,可先做基础定位:

diec sample.exe
pefile sample.exe
floss sample.exe
7z l sample.exe
capa sample.exe

2. 持久化要还原完整写入链

不仅看最终注册表项,还要确认由哪个进程、以什么权限、写入哪个落地文件。常见位置可以直接离线查询:

reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /s
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /s
schtasks /query /fo LIST /v
sc query type= service state= all
wmic /namespace:\\root\subscription PATH __EventFilter get /format:list
wmic /namespace:\\root\subscription PATH CommandLineEventConsumer get /format:list
wmic /namespace:\\root\subscription PATH __FilterToConsumerBinding get /format:list

计划任务还应导出 XML,重点核对触发器、执行用户和参数拼接:

schtasks /query /tn "\可疑任务名" /xml > task.xml

如果样本通过脚本或 LOLBin 间接启动,日志里应继续串起父子关系,例如:

sample.exe
  └─ powershell.exe -EncodedCommand ...
      └─ reg.exe add ...
          └─ rundll32.exe %APPDATA%\xxx.dll,Entry

3. 日志闭环需要统一时间线

建议至少覆盖进程创建、文件落地、注册表、DNS 和网络连接。Procmon 保存 PML 原始文件,Sysmon 可关注事件 ID 1、3、11、12/13、22;同时保留 PCAP。所有时间统一转成 UTC,并记录虚拟机时区和快照时间,避免把 DNS 查询、连接和持久化写入错序。

wevtutil epl Microsoft-Windows-Sysmon/Operational sysmon.evtx
wevtutil epl Microsoft-Windows-PowerShell/Operational powershell.evtx
pktmon start --capture --pkt-size 0 --file-name traffic.etl
rem 复现结束后
pktmon stop
pktmon etl2pcap traffic.etl --out traffic.pcapng

最终报告最好用一条可验证的事件链收口:样本哈希 → 初始进程与命令行 → 配置解密位置 → DNS/C2 连接 → 落地文件 → 持久化键或任务 → 重启后触发验证。清理阶段也应反向验证:删除持久化后重启,确认没有同名任务、残留服务、再次生成文件或网络连接。这样提取结果才能同时用于复现、检测和处置。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。