跳转到帖子

逆向木马远控样本:从持久化、配置解密到 C2 留痕的授权分析方法

精选回复

发布于

本文面向授权安全测试、应急响应和隔离实验室中的样本分析,重点讨论 Windows 木马远控程序的逆向定位方法:如何确认样本是否具备远控能力,如何追踪持久化与权限边界,如何从静态配置和运行时行为中提取 C2 特征,以及如何利用日志验证攻击链路。示例均以不连接真实攻击基础设施为前提,分析环境应使用快照、隔离网络和测试账号。

一、典型场景与分析目标

某办公终端出现异常:用户登录后 CPU 占用间歇性升高,外联到一个不常见的公网地址;任务管理器中进程名伪装为 svchost.exe,但文件位于用户目录下。初步目标不是直接“清除文件”,而是回答以下问题:

  • 样本是否具备远程命令执行、文件管理、屏幕采集或凭据窃取能力。
  • 它通过注册表、计划任务、服务、WMI 还是 DLL 劫持实现持久化。
  • 进程以普通用户还是高完整性、SYSTEM 权限运行,是否存在权限边界突破。
  • C2 使用什么协议、域名、URI、信标周期和加密方式。
  • 主机日志、DNS、代理和流量设备上能够留下哪些可检索证据。

在没有完成证据固定前,不建议立即删除样本或重启主机,否则可能丢失内存中的解密配置、注入关系和网络连接信息。

二、隔离与证据固定

在虚拟机中建立快照,关闭共享剪贴板、共享目录和宿主机拖放功能。网络侧使用仅允许访问本地模拟服务的隔离网段,禁止样本触达真实公网 C2。对原始文件计算哈希并记录采集时间、来源主机、用户和文件路径。

mkdir C:\IR\case-20250308
Get-FileHash C:\Users\Public\svchost.exe -Algorithm SHA256 | Tee-Object C:\IR\case-20250308\hash.txt
Get-Item C:\Users\Public\svchost.exe | Select-Object FullName,Length,CreationTime,LastWriteTime,Attributes
Get-AuthenticodeSignature C:\Users\Public\svchost.exe | Format-List *
Get-CimInstance Win32_Process -Filter "Name='svchost.exe'" | Select-Object ProcessId,ParentProcessId,ExecutablePath,CommandLine
Get-NetTCPConnection -State Established | Sort-Object OwningProcess | Format-Table -AutoSize

如果主机仍处于在线状态,优先记录进程、父子关系、连接四元组和当前用户,再执行网络隔离。隔离应尽量采用交换机端口、EDR 网络隔离或防火墙阻断,而不是直接关机。

三、静态分析:从 PE 结构识别远控功能

首先检查 PE 文件的架构、时间戳、节区权限和导入表。远控样本常见特征包括:节区名称异常、代码节可写、资源段包含高熵数据、导入 WinInet、WinHTTP、WS2_32、Crypt32、Advapi32、Psapi 或 Wtsapi32 等 API。单个 API 不能证明恶意性,应结合调用路径和行为确认。

  • CreateProcess、ReadProcessMemory、WriteProcessMemory、VirtualAllocEx:可能涉及远程进程创建、注入或命令执行。
  • RegSetValueEx、CreateService、SchTasks 相关调用:关注持久化。
  • GetDC、BitBlt、GdiPlus:可能存在屏幕采集。
  • CryptDecrypt、自定义异或循环、AES 常量表:关注配置和 C2 数据解密。
  • WinHttpOpenRequest、InternetConnect、connect:沿调用链定位网络请求构造函数。

建议在 Ghidra、IDA 或 Binary Ninja 中先标记字符串引用、资源解压函数和网络 API 调用点,再回溯参数来源。若字符串很少,不要仅凭此判断样本没有配置,常见情况是配置位于资源、覆盖数据、附加数据或运行时解密缓冲区中。

四、定位 C2 配置与运行时解密

对 PE 文件执行字符串提取时,应分别处理 ASCII、UTF-16LE 和资源内容。重点搜索域名、IPv4、URI 路径、User-Agent、互斥体名称、睡眠时间和命令标识。对于高熵资源,可以记录资源大小、熵值和引用函数,但不要在生产主机上直接运行解包器。

strings -n 6 sample.exe > strings-ascii.txt
strings -el -n 6 sample.exe > strings-unicode.txt
7z l sample.exe
rabin2 -I sample.exe
rabin2 -zz sample.exe | grep -Ei "http|/api|cmd|mutex|user-agent|\.onion|[0-9]{1,3}(\.[0-9]{1,3}){3}"
floss.exe sample.exe > floss.txt

动态分析时,在网络 API 的返回点和自定义解密函数的末尾设置断点。常见流程是:读取资源或覆盖数据 → 分配堆内存 → 循环异或/AES 解密 → 将明文复制到请求结构 → 发起 DNS 或 HTTP 请求。应在“明文已经生成、尚未被释放”的时间窗口中导出内存,而不是只在文件中搜索。

对采用 HTTPS 的样本,不建议通过破解或绕过真实服务端证书校验来连接外部基础设施。授权实验中可以将域名解析到本地模拟服务,并通过代理记录请求元数据;如果样本启用证书固定,应优先在调试器中观察请求构造和加密前数据,避免改写样本后影响行为判断。

五、持久化与权限边界检查

远控样本的持久化方式通常决定其权限边界。以普通用户权限写入 HKCU\Software\Microsoft\Windows\CurrentVersion\Run,与创建 SYSTEM 服务不是同一等级的事件,排查时必须记录创建者、目标路径和权限。

reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run /s
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run /s
schtasks /query /fo LIST /v
sc.exe query type= service state= all
Get-CimInstance Win32_StartupCommand | Select-Object Name,Command,Location,User
Get-WmiObject -Namespace root\subscription -Class __EventFilter
Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding

检查服务时重点关注二进制路径是否位于用户可写目录、服务配置的 ACL 是否允许低权限用户修改,以及服务启动账号是否为 LocalSystem。可以使用 Sysinternals Autoruns 做交叉验证,并将结果导出后与基线比较:

autorunsc64.exe -accepteula -a * -c -h -s -v -vt > autoruns.csv
accesschk64.exe -uwcqv "Users" *
sc.exe qc SuspiciousService

如果发现普通用户可写目录中的服务二进制或服务配置,需先确认是否为真实权限提升路径:检查目录和文件 ACL、服务重启权限、父进程身份以及实际令牌完整性级别。不要把“文件位于 Temp 目录”直接等同于高危提权。

六、运行时行为与日志关联

建议启用 Sysmon 的进程创建、网络连接、DNS 查询、映像加载、注册表修改和计划任务事件。下面是排查时常用的关联字段:

行为重点日志关联字段
伪装进程启动Sysmon 1、安全日志 4688Image、ParentImage、CommandLine、User、Hashes
首次外联Sysmon 3、代理日志、防火墙日志ProcessId、DestinationIp、DestinationPort、时间
域名解析Sysmon 22、DNS 服务器日志QueryName、进程路径、主机名
持久化修改Sysmon 12/13/14、任务计划日志TargetObject、Details、创建者

例如,进程创建事件显示 C:\Users\Public\svchost.exe,随后同一 PID 在 30 秒内连接外部地址,且父进程为 explorer.exe,这比单独观察进程名更有判断价值。若进程随后退出而连接仍存在,应检查是否发生 DLL 注入、进程迁移或子进程接管。

wevtutil qe Microsoft-Windows-Sysmon/Operational /q:"*[System[(EventID=1 or EventID=3 or EventID=22)]]" /f:text /c:100
Get-WinEvent -FilterHashtable @{LogName='Security';Id=4688;StartTime=(Get-Date).AddHours(-4)} | Select-Object TimeCreated,Message
Get-NetTCPConnection | ForEach-Object { $p=$_.OwningProcess; Get-Process -Id $p -ErrorAction SilentlyContinue | Select-Object Id,Path,@{N='Remote';E={"$($_.Name):$($_.Id) $($_.Path)"}} }

七、检测规则与误报控制

可将已确认的路径、互斥体、URI、文件哈希和网络模式沉淀为检测规则。YARA 不应只匹配单一通用字符串,否则容易误报;建议至少组合一个网络特征、一个持久化或远控能力特征,并排除已知合法软件。

rule Suspicious_Remote_Control_Sample_Example
{
    meta:
        description = "示例:检测授权分析中确认的远控样本特征"
        author = "IR"
        reference = "case-20250308"
    strings:
        $ua = "Mozilla/5.0" ascii wide
        $path = "/api/gate" ascii wide
        $mutex = "Global\\UpdateCheck_" ascii wide
        $inject1 = "VirtualAllocEx" ascii
        $inject2 = "WriteProcessMemory" ascii
    condition:
        uint16(0) == 0x5A4D and
        2 of ($ua,$path,$mutex) and
        1 of ($inject*)
}

规则上线前应在企业软件、远程运维工具和历史样本库中进行回扫。对高风险特征优先采用“哈希 + 路径 + 行为”的组合告警,避免仅凭 VirtualAllocEx 或 WriteProcessMemory 告警,因为调试器、安装程序和安全软件同样可能调用这些 API。

八、处置与修复建议

  • 保留原始样本、内存镜像、事件日志、DNS 和代理日志,计算哈希并记录证据链。
  • 在确认影响范围后,对 C2 域名、IP、URI 和证书指纹实施出口阻断,但不要只依赖 IP 黑名单。
  • 删除持久化前先记录注册表键、任务 XML、服务配置和文件 ACL,便于后续复盘。
  • 若样本曾以高权限运行,应轮换本机管理员、域账号、令牌和可能暴露的应用凭据。
  • 修复服务目录和计划任务的写权限,禁止普通用户修改高权限服务加载路径。
  • 启用 Sysmon、PowerShell 日志、命令行审计和网络 DNS 日志,并将进程哈希与父子关系纳入集中检索。
  • 完成清理后从可信介质重建主机;对仅删除文件但未确认凭据和权限边界的处置,不应视为彻底修复。

总结

逆向木马远控样本的关键不是“找到一个可疑文件”,而是把静态结构、运行时调用、持久化位置、权限令牌和网络日志串成一条可验证链路。优先固定证据,再在隔离环境中定位配置解密和 C2 构造逻辑,最后用 Sysmon、YARA 和出口策略形成持续检测。对于授权渗透测试,还应明确样本触发范围、网络隔离边界和清理回滚步骤,避免分析动作本身扩大影响面。

逆向分析与样本观察示意图
逆向分析、样本行为与调试流程示意
网络流量与边界分析示意图
网络请求、日志与边界流量分析示意

这个方向里最值得强调的是证据链:要区分“样本包含某段持久化代码”和“持久化在当前权限下实际创建成功”,C2 也不要只记录域名、IP,否则后续很难复核。

1. 持久化建议做执行前后差分

在隔离虚拟机中分别保存 before/after,至少覆盖启动项、服务、计划任务和 WMI 永久订阅:

# 分析前、执行后各运行一次,修改输出目录
$Out = "C:\triage\before"
New-Item -ItemType Directory -Force $Out | Out-Null

Get-CimInstance Win32_StartupCommand |
    Select-Object Name, Command, Location, User |
    Export-Csv "$Out\startup.csv" -NoTypeInformation

Get-CimInstance Win32_Service |
    Select-Object Name, State, StartMode, PathName |
    Export-Csv "$Out\services.csv" -NoTypeInformation

Get-ScheduledTask | ForEach-Object {
    $Task = $_
    [pscustomobject]@{
        TaskPath = $Task.TaskPath
        TaskName = $Task.TaskName
        State    = $Task.State
        Actions  = ($Task.Actions | ForEach-Object {
            "$($_.Execute) $($_.Arguments)"
        }) -join "; "
    }
} | Export-Csv "$Out\tasks.csv" -NoTypeInformation

Get-CimInstance -Namespace root/subscription -ClassName __EventFilter |
    Export-Clixml "$Out\wmi_filters.xml"
Get-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer |
    Export-Clixml "$Out\wmi_consumers.xml"
Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding |
    Export-Clixml "$Out\wmi_bindings.xml"

reg.exe query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /s > "$Out\hkcu_run.txt"
reg.exe query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /s /reg:64 > "$Out\hklm_run.txt"

动态侧可结合 Sysmon 的 1、3、11、12-14、19-22 号事件,同时检查 Security 4698 和 System 7045。记录写入进程、目标路径、权限、返回值和时间,不要仅凭注册表字符串判断持久化成功。释放文件还应保存 SHA-256、签名状态及完整路径。

2. 配置解密从“消费点”反推更稳

静态分析时先定位网络 API、URL 解析、JSON 解析或配置结构初始化,再向上追踪交叉引用,通常比直接搜索高熵数据有效。动态调试可关注 CryptDecrypt、BCryptDecrypt、WinHttpConnect、WinHttpOpenRequest、InternetConnectW 等位置,在解密函数返回后直接转储缓冲区。自定义算法则在明文首次被消费的位置回溯。

复写解密逻辑时建议同时固定样本哈希、配置偏移、长度和函数地址,避免“脚本能跑但无法复现”。例如重复密钥 XOR 可以用下面的最小脚本验证,实际轮转、加减和字节序应严格按反编译结果实现:

from pathlib import Path
from hashlib import sha256

def xor_repeat(data: bytes, key: bytes) -> bytes:
    return bytes(b ^ key[i % len(key)] for i, b in enumerate(data))

sample = Path("sample.bin").read_bytes()
offset = 0x00000000   # 替换为实际配置偏移
size = 0x0000         # 替换为实际长度
key = bytes.fromhex("00")  # 替换为分析得到的密钥

enc = sample[offset:offset + size]
plain = xor_repeat(enc, key)

Path("config.dec").write_bytes(plain)
print("sample_sha256 =", sha256(sample).hexdigest())
print("config_sha256 =", sha256(plain).hexdigest())
print(plain[:128])

如果解密后仍不可读,应按调用顺序检查 Base64、压缩、字符串编码和完整性校验,不要看到高熵就直接认定为 AES。

3. C2 留痕要关联到具体进程

样本不应直接连接公网,建议在关闭桥接、共享目录和剪贴板的快照环境中使用 FakeNet-NG 或 INetSim 提供伪造 DNS/HTTP 服务,并同时保存 PCAP、Sysmon EVTX 和内存。PCAP 可先做一轮快速归并:

tshark -r sample.pcapng \
  -Y "dns || http || tls.handshake.type == 1" \
  -T fields \
  -e frame.time_epoch \
  -e ip.src -e ip.dst \
  -e dns.qry.name \
  -e http.host -e http.request.uri \
  -e tls.handshake.extensions_server_name

zeek -Cr sample.pcapng
# 重点查看 conn.log、dns.log、http.log、ssl.log、x509.log

最终 IOC 除域名和 IP 外,最好保留 URI 模板、Host/SNI、User-Agent、证书指纹、请求体编码、心跳周期及抖动范围。再按时间戳将这些流量与 Sysmon 3/22 事件、PID 和进程树关联;单独的 PCAP 无法证明连接由哪个进程发起。

报告中把“静态推断”“动态观察”“已成功落地”分栏记录,并给 PCAP、EVTX、内存镜像和解密后配置计算哈希。这样后续做 YARA/Sigma 时可以优先使用解密例程、配置结构和行为链,而不是依赖很快失效的 C2 地址。

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

最近浏览 0

  • 没有会员查看此页面。