跳转到帖子

逆向木马远控实战:从持久化入口、进程注入到 C2 通信的闭环排查

精选回复

发布于

本文记录一个授权内网排查场景:终端出现周期性外连,EDR 仅提示 PowerShell 异常启动,但没有直接识别载荷。分析目标不是单纯提取 IOC,而是还原远控样本的启动入口、注入位置、通信协议和权限边界,并给出可验证的清理与加固方案。

以下步骤适用于已授权的应急响应、恶意样本分析和渗透测试复盘。样本应放在隔离虚拟机中处理,关闭共享剪贴板、共享目录和宿主机网络直通。

一、场景与初始现象

受影响主机为 Windows 10,普通域用户权限。网关日志显示该终端每隔约 60 秒访问同一公网地址,目标端口为 443,但 TLS 指纹和浏览器流量不一致。终端侧同时存在以下现象:

  • 用户登录后出现短暂的 PowerShell 进程,命令行不可见。
  • 计划任务中没有明显异常项,但注册表 Run 键存在名称近似系统组件的值。
  • 外连实际由 explorer.exe 发起,磁盘上没有与连接对应的常驻程序。
  • 重启后外连恢复,说明样本具备持久化能力。

这种“脚本拉起、合法进程外连、磁盘载荷不明显”的组合,通常需要同时检查持久化入口、进程树、内存映射和网络行为,不能只依赖静态查杀。

二、先保全证据,再进行清理

不要一开始就结束进程或删除文件。结束 explorer.exe 可能使注入区域消失,删除启动项也会破坏时间线。建议先记录系统时间、登录用户、网络连接、进程树、启动项和文件哈希。

mkdir C:\IR 2>nul
whoami /all > C:\IR\whoami.txt
systeminfo > C:\IR\systeminfo.txt
tasklist /v > C:\IR\tasklist.txt
netstat -ano > C:\IR\netstat.txt
sc query type= service state= all > C:\IR\services.txt
schtasks /query /fo LIST /v > C:\IR\tasks.txt
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /s > C:\IR\run_hkcu.txt
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /s > C:\IR\run_hklm.txt
wevtutil epl System C:\IR\System.evtx
wevtutil epl Security C:\IR\Security.evtx
wevtutil epl Microsoft-Windows-PowerShell/Operational C:\IR\PowerShell.evtx

如果工具条件允许,应优先制作内存镜像。全内存镜像能保留注入代码、解密后的配置、C2 地址和短生命周期进程痕迹。采集工具本身应提前校验哈希,并记录执行时间,避免把响应人员的操作误判为攻击行为。

三、定位持久化入口

本例在 HKCU Run 键中发现以下值:

HKCU\Software\Microsoft\Windows\CurrentVersion\Run
  WindowsUpdate    REG_SZ    powershell.exe -NoP -W Hidden -File "%APPDATA%\Microsoft\update.ps1"

这里有三个值得关注的点:使用当前用户注册表意味着不需要管理员权限;Hidden 只隐藏窗口,不代表进程不可审计;脚本放在用户可写目录中,符合低权限落地特征。

除 Run 键外,还应检查以下位置,避免只删除一个入口后样本再次恢复:

  • RunOnce、Startup 目录、计划任务和服务。
  • WMI 永久事件订阅,包括 EventFilter、CommandLineEventConsumer 和绑定关系。
  • IFEO Debugger、AppInit_DLLs、Winlogon Shell/Userinit。
  • 浏览器扩展、Office 加载项及用户目录中的快捷方式参数。
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce" /s
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" /s
wmic /namespace:\\root\subscription path __EventFilter get Name,Query /format:list
wmic /namespace:\\root\subscription path CommandLineEventConsumer get Name,CommandLineTemplate /format:list
wmic /namespace:\\root\subscription path __FilterToConsumerBinding get Filter,Consumer /format:list

四、脚本与载荷的静态拆解

update.ps1 并未直接包含 PE 文件,而是读取同目录下的 cache.dat,执行 Base64 解码和单字节异或,再通过反射加载。此时应先复制原始文件并计算哈希,不要直接双击或在联网主机上执行。

Get-FileHash "$env:APPDATA\Microsoft\update.ps1" -Algorithm SHA256
Get-FileHash "$env:APPDATA\Microsoft\cache.dat" -Algorithm SHA256
Get-Item "$env:APPDATA\Microsoft\update.ps1" | Format-List FullName,Length,CreationTimeUtc,LastWriteTimeUtc
Get-AuthenticodeSignature "$env:APPDATA\Microsoft\update.ps1" | Format-List

对脚本去混淆时,建议把“解码”和“执行”拆开。只保留字符串转换逻辑,将 Invoke-Expression、Add-Type、反射调用和委托执行替换为文件输出。以下示例仅恢复数据,不加载载荷:

$src = [IO.File]::ReadAllText('.\cache.dat')
$buf = [Convert]::FromBase64String($src)
for ($i = 0; $i -lt $buf.Length; $i++) {
    $buf[$i] = $buf[$i] -bxor 0x37
}
[IO.File]::WriteAllBytes('.\decoded.bin', $buf)
Get-FileHash '.\decoded.bin' -Algorithm SHA256

若 decoded.bin 以 MZ 开头,可使用 PE 工具检查编译时间、节区权限、导入表和资源。编译时间只能作为辅助信息,打包器经常会覆盖该字段。更有价值的异常包括 RWX 节区、极高熵节区、导入函数数量过少,以及 VirtualAlloc、VirtualProtect、WriteProcessMemory、CreateRemoteThread、NtUnmapViewOfSection 等组合。

五、动态调试:确认注入链路

在隔离虚拟机中运行时,父子进程关系表现为 powershell.exe 短暂启动,随后 explorer.exe 建立网络连接。对 PowerShell 设置进程创建监控后,可以看到脚本先申请可执行内存,再将解码后的 PE 映射到当前进程,最后向 explorer.exe 写入第二阶段代码。

调试时可围绕以下 API 设置断点:

阶段关键 API观察重点
内存申请VirtualAlloc、VirtualAllocEx、NtAllocateVirtualMemory是否申请 PAGE_EXECUTE_READWRITE,目标进程句柄指向何处
跨进程写入WriteProcessMemory、NtWriteVirtualMemory写入地址、缓冲区内容、PE 头或 shellcode 特征
权限变更VirtualProtect、NtProtectVirtualMemory内存是否从 RW 转为 RX
线程启动CreateRemoteThread、NtCreateThreadEx、QueueUserAPC线程入口是否落在无文件映射的私有内存
网络通信WinHttpSendRequest、InternetConnect、connect域名、URI、请求头、连接周期

如果 explorer.exe 中出现 Private、可执行且没有对应磁盘映像的内存区域,应进一步转储该区域。线程入口落在 MEM_PRIVATE 区域、调用栈无法回溯到正常模块,通常比“进程名是否正常”更有判断价值。

六、C2 通信特征分析

样本使用 443 端口,但并不等于正常 HTTPS。抓包结果显示它每 60 秒发送一次固定长度请求,URI 为随机八字符路径,请求头中的 User-Agent 长期不变。响应体先经过 Base64 解码,再使用内置密钥进行异或处理。

排查时应把网络 IOC 分为两类:

  • 易变化 IOC:IP、域名、URI、证书序列号。
  • 相对稳定行为:固定心跳周期、请求长度、异常 TLS 指纹、特定请求头顺序、解码流程。

只封禁单一 IP 很容易遗漏后续基础设施。网关侧可同时检索同一 JA3/JA4 指纹、相同 User-Agent、相近周期连接和低流量长时间会话。终端侧则将连接 PID 与进程创建事件、映像加载事件和线程入口关联。

七、日志留痕与检测配置

建议部署 Sysmon 并集中采集事件。最低限度应关注进程创建、网络连接、映像加载、进程访问、文件创建和注册表修改。配置规则不能只依赖 powershell.exe,因为样本可能改用 rundll32、regsvr32、mshta 或合法签名程序作为宿主。

<Sysmon schemaversion="4.90">
  <EventFiltering>
    <ProcessCreate onmatch="include">
      <CommandLine condition="contains any">-EncodedCommand;-enc;FromBase64String;Reflection.Assembly;VirtualAlloc</CommandLine>
    </ProcessCreate>
    <NetworkConnect onmatch="include">
      <Image condition="end with">\powershell.exe</Image>
      <Image condition="end with">\rundll32.exe</Image>
      <Image condition="end with">\regsvr32.exe</Image>
    </NetworkConnect>
    <RegistryEvent onmatch="include">
      <TargetObject condition="contains any">\CurrentVersion\Run;\CurrentVersion\RunOnce;\Image File Execution Options</TargetObject>
    </RegistryEvent>
  </EventFiltering>
</Sysmon>

上面的配置适合实验和定向排查,生产环境需要结合基线降噪。例如管理员脚本可能合法使用 Base64,单一命令行关键字不应直接作为阻断依据,应与父进程、签名、文件路径和网络行为组合判断。

八、权限边界与横向风险

该样本最初只获得普通用户权限,但仍可读取当前用户浏览器数据、访问已挂载共享目录,并继承用户现有网络权限。如果终端上存在高权限会话,注入到同完整性级别进程后还可能窃取会话令牌。排查范围不能局限于本机文件,应同步核查:

  • 感染时间段内该账号访问过的 SMB、RDP、VPN 和管理平台。
  • 是否出现异常 Kerberos 票据请求、远程服务创建或计划任务下发。
  • 浏览器、邮件客户端及脚本中保存的凭据是否需要轮换。
  • 同一哈希、启动项名称、C2 行为是否出现在其他终端。

如果发现远程执行或凭据访问迹象,应按账号和主机两个维度扩展调查,而不是仅重装当前终端。

九、清理与修复建议

清理前先隔离网络并完成证据保全。确认载荷和持久化链路后,再按以下顺序处理:

  • 阻断已确认的 C2 域名、IP、证书和行为特征。
  • 结束恶意线程或宿主进程,并保留相应内存转储。
  • 删除 Run 键、计划任务、WMI 订阅等全部持久化入口。
  • 隔离脚本、加密数据文件和释放后的载荷,记录 SHA256。
  • 重置受影响账号凭据,吊销活动令牌和 VPN 会话。
  • 检查同网段终端和服务器,确认没有横向移动残留。
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v WindowsUpdate /f
Remove-Item "$env:APPDATA\Microsoft\update.ps1" -Force
Remove-Item "$env:APPDATA\Microsoft\cache.dat" -Force

# 清理后复核
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run"
Get-NetTCPConnection | Sort-Object RemoteAddress
Get-ScheduledTask | Where-Object {$_.TaskPath -notlike '\Microsoft*'}
Get-CimInstance -Namespace root/subscription -ClassName __EventFilter

是否必须重装取决于可信恢复条件。如果样本获得管理员或 SYSTEM 权限、加载内核驱动、修改安全产品,或无法确认全部二阶段载荷,建议从可信镜像重装,而不是继续在原系统上做“清干净”的假设。

十、验证闭环

修复完成后至少观察一个完整业务周期。验证项包括:启动项不再恢复;原心跳周期内没有同类外连;PowerShell 日志中没有重复解码行为;宿主进程不存在异常可执行私有内存;账号侧没有新的异常认证事件。

逆向远控样本的重点不是得到一个病毒名称,而是形成可复核的行为链:持久化入口如何触发、载荷如何解码、代码注入到哪个进程、C2 如何通信、当前权限能够触达哪些资源。只有把这些环节与终端日志、网络日志和修复验证对应起来,处置才算真正闭环。

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

这类排查建议不要把“启动项、注入、C2”割裂分析,关键是统一时间线:先用持久化入口确定首次执行时间和落地路径,再围绕该进程补齐父子关系、跨进程操作及网络连接。否则很容易只清掉注入后的进程,遗漏负责重新拉起的 loader。

Windows 环境可以先收集下面几类证据,采集前尽量隔离网络,不要直接结束可疑进程,以免丢失内存与连接信息:

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 process get ProcessId,ParentProcessId,ExecutablePath,CommandLine,CreationDate
netstat -ano

持久化入口还应覆盖 WMI 永久事件订阅、启动目录和服务 DLL。WMI 木马经常不会出现在常规 Run 键里:

Get-CimInstance -Namespace root\subscription -ClassName __EventFilter
Get-CimInstance -Namespace root\subscription -ClassName CommandLineEventConsumer
Get-CimInstance -Namespace root\subscription -ClassName ActiveScriptEventConsumer
Get-CimInstance -Namespace root\subscription -ClassName __FilterToConsumerBinding

Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup" -Force
Get-ChildItem "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Startup" -Force

reg query HKLM\SYSTEM\CurrentControlSet\Services /s /f ServiceDll

判断进程注入时,不要只看进程名。重点检查“镜像路径与内存映射不一致”、无文件支持的可执行私有内存,以及异常线程起始地址。Sysmon 已部署的话,优先关联 Event ID 1、3、7、8、10、11、13、22;其中 8/10 对远程线程和进程访问比较关键,但需要结合源进程、目标进程和访问权限判断,避免把安全软件行为当成注入。

可用 Process Explorer/Process Hacker 查看线程起始地址和内存区域,再对目标进程做完整内存转储:

procdump64.exe -accepteula -ma <PID> suspicious.dmp

离线分析时,可用 Volatility 3 交叉验证进程、网络和可疑内存页:

python vol.py -f memory.raw windows.pslist
python vol.py -f memory.raw windows.pstree
python vol.py -f memory.raw windows.cmdline
python vol.py -f memory.raw windows.netscan
python vol.py -f memory.raw windows.malfind
python vol.py -f memory.raw windows.dlllist --pid <PID>

malfind 命中并不等于恶意,建议继续核对页面权限、PE 头、线程是否落在该区域,以及磁盘上是否存在对应映像。若出现 PAGE_EXECUTE_READWRITE 私有页、线程入口位于未映射模块区域,同时该进程发起外联,证据链会更完整。

C2 分析建议保留 DNS、SNI、目的 IP/端口、连接周期和单次流量大小。固定周期并带少量抖动的短连接,通常比单一恶意域名更适合作为行为特征。可先按 PID 对齐连接,再反查进程创建链:

Get-NetTCPConnection |
  Sort-Object OwningProcess |
  Format-Table LocalAddress,LocalPort,RemoteAddress,RemotePort,State,OwningProcess

Get-Process -Id <PID> |
  Select-Object Id,ProcessName,Path,StartTime

如果流量走 HTTPS,不建议只依赖域名封禁;同时提取证书指纹、JA3/JA4(采集条件允许时)、SNI 缺失情况及 beacon 间隔。DNS 型 C2 则重点看高熵子域、异常 TXT 查询、固定长度标签和单主机高频 NXDOMAIN。

最后处置顺序建议是:保存内存与日志 → 隔离主机 → 禁用持久化入口 → 阻断 C2 → 清理落地文件和注入载荷 → 重置该主机上使用过的凭据。确认存在 LSASS 访问、浏览器凭据窃取或令牌盗用时,仅重装主机不够,还要做凭据轮换,并检查同账号在其他终端上的横向活动。

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

最近浏览 0

  • 没有会员查看此页面。