可疑进程树与父子进程异常取证分析

可疑进程树与父子进程异常取证分析

很多现场最容易看漏的,不是恶意文件,而是“看起来合法”的进程。攻击者越来越少直接跑一个明显叫 trojan.exe 的程序,而是:

  • WINWORD.EXE 拉起 powershell.exe
  • wscript.exe 拉起 cmd.exe
  • rundll32.exeregsvr32.exe 执行载荷
  • 让一个被重命名的 cdb.exe 伪装成系统进程
  • 让合法父进程之下挂出一条恶意执行链

因此,真正高价值的并不是“这台机器有一个 PowerShell”,而是这个 PowerShell 是谁拉起来的,它之前发生了什么,它之后又触发了什么。


0x01 进程树分析要回答什么

建议优先回答四个问题:

  1. 谁是最初的触发点? 是 Office、浏览器、压缩软件、邮件客户端、服务还是脚本宿主。
  2. 父子关系是否合理? 合法进程是否拉起了不符合业务逻辑的子进程。
  3. 进程链是否跨越了多个执行层级? 例如 浏览器 -> PowerShell -> 下载器 -> 隧道工具 -> 横向工具
  4. 进程树是否与日志、文件、网络证据闭环? 只有进程树和文件、连接、任务、注册表能对上,这条链才可信。

0x02 公开案例一:PIKABOT 的 ZIP 到 PowerShell 到伪装程序执行链

Elastic Security Labs 在 2024 年公开的 PIKABOT 分析里,给出了一条非常适合蓝队落地的进程链:

  1. 邮件中的超链接指向 ZIP
  2. ZIP 内是混淆 JavaScript
  3. JavaScript 调用 PowerShell 下载二阶段样本
  4. 样本伪装成正常程序继续执行
  5. 后续利用异常调用栈和无后备内存中的 syscall 规避 EDR

这个案例的关键价值不是“PIKABOT 很复杂”,而是它明确说明了蓝队现场应该怎么从 ZIP -> JS -> PowerShell -> 伪装 PE 这条链回查。

公开来源:


0x03 公开案例二:Squidoor 使用被重命名的 cdb.exe 伪装加载

Unit 42 在 2025 年公开的 Squidoor 分析中提到,攻击者投放了微软 Console Debugger cdb.exe,并将其重命名为:

  • C:\ProgramData\fontdrvhost.exe

随后利用它加载和执行 shellcode。

这个案例对蓝队非常有价值,因为它提醒我们:

  • 不能只看进程名是否“像系统程序”
  • 还要看进程原始文件名、路径、签名、父进程和命令行

公开来源:


0x04 哪些父子进程关系最值得怀疑

1. Office 拉起脚本宿主

重点关注:

  • WINWORD.EXE -> powershell.exe
  • EXCEL.EXE -> cmd.exe
  • OUTLOOK.EXE -> wscript.exe
  • POWERPNT.EXE -> mshta.exe

2. 浏览器拉起系统命令解释器

重点关注:

  • chrome.exe -> powershell.exe
  • msedge.exe -> cmd.exe
  • firefox.exe -> wscript.exe

3. 脚本宿主拉起下载器或 LOLBin

重点关注:

  • wscript.exe -> powershell.exe
  • mshta.exe -> rundll32.exe
  • powershell.exe -> regsvr32.exe
  • cmd.exe -> certutil.exe

4. 服务进程后出现用户态工具

重点关注:

  • services.exe -> cmd.exe
  • svchost.exe -> powershell.exe
  • wmiprvse.exe -> cmd.exe

5. 安全产品或系统组件被异常替身利用

重点关注:

  • 原始文件名与进程名不一致
  • 系统组件运行在用户目录或 ProgramData
  • 合法签名文件被重命名后出现在异常位置

0x05 Windows 现场排查命令

1. Security 4688 按父子进程回查

$start=(Get-Date).AddDays(-2)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688; StartTime=$start} |
  Where-Object {
    $_.Message -match 'powershell\.exe|cmd\.exe|wscript\.exe|cscript\.exe|mshta\.exe|rundll32\.exe|regsvr32\.exe|certutil\.exe'
  } |
  Select-Object TimeCreated, Message

2. Sysmon Event ID 1 按进程树看父进程

Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1; StartTime=$start} |
  Where-Object {
    $_.Message -match 'powershell\.exe|cmd\.exe|wscript\.exe|mshta\.exe|rundll32\.exe'
  } |
  Select-Object TimeCreated, Message

3. 直接查最近异常父子组合

Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=1; StartTime=$start} |
  Where-Object {
    $_.Message -match 'ParentImage:.*(WINWORD\.EXE|EXCEL\.EXE|OUTLOOK\.EXE|chrome\.exe|msedge\.exe|wmiprvse\.exe|services\.exe)'
  } |
  Select-Object TimeCreated, Message

4. 反查进程路径、签名和原始文件名

Get-Process | Select-Object Id, ProcessName, Path

Get-ChildItem C:\ProgramData,C:\Users\Public,$env:TEMP -Recurse -Force -ErrorAction SilentlyContinue |
  Where-Object {$_.Name -match 'fontdrvhost|svchost|dllhost|taskhost|conhost'} |
  Select-Object FullName, LastWriteTime, Length

5. 结合 Prefetch 和下载目录补链

Get-ChildItem C:\Windows\Prefetch -Force -ErrorAction SilentlyContinue |
  Where-Object {$_.Name -match 'POWERSHELL|WSCRIPT|MSHTA|CMD|RUNDLL32|REGSVR32'} |
  Sort-Object LastWriteTime -Descending |
  Select-Object -First 50 FullName, LastWriteTime

Get-ChildItem "$env:USERPROFILE\Downloads" -Force -ErrorAction SilentlyContinue |
  Sort-Object LastWriteTime -Descending |
  Select-Object -First 30 FullName, LastWriteTime, Length

0x06 Linux 现场排查命令

Linux 进程树更适合围绕 bash/sh/python/perl/curl/wget/ssh/socat 展开。

# 看当前进程树
ps -ef --forest

# 看近期被拉起的高风险工具
ps -ef | egrep 'bash|sh|python|perl|curl|wget|ssh|scp|socat|nc|ncat' | grep -v grep

# 如果启用了 auditd,可按执行文件查
ausearch -m EXECVE -ts recent | egrep 'curl|wget|python|perl|bash|ssh|scp|socat'

# 看 systemd 或 cron 是否拉起了异常脚本
systemctl list-units --type=service
grep -RInE 'curl|wget|bash -c|python -c|ssh -R|ssh -D|socat' /etc/systemd /etc/cron* /var/spool/cron 2>/dev/null

0x07 一条现场可直接执行的分析流程

如果你刚拿到一台疑似中毒的 Windows 主机,建议按下面顺序执行:

  1. 先查 4688 / Sysmon Event ID 1,过滤 powershell/cmd/wscript/mshta/rundll32
  2. 再看它们的父进程是不是 Office/浏览器/services/wmiprvse
  3. 再看子进程是否继续下载、解压、注入或外联
  4. 再看相同时间窗里是否落地了 ZIP、DLL、EXE、任务、服务或隧道配置
  5. 最后补上文件路径、签名、原始文件名和网络连接

这一步做完,很多“只有一个 PowerShell”的模糊告警就能收敛成完整攻击链。


0x08 进程树分析中最常见的误区

1. 只看进程名,不看父进程

powershell.exe 本身不是结论,WINWORD.EXE -> powershell.exe 才接近结论。

2. 只看父进程,不看路径和签名

被重命名的合法文件、伪装系统文件、目录错位,是现场非常常见的绕过方式。

3. 只看单个时间点,不看整条链

真正有价值的不是某一个进程,而是:

  • 谁拉起它
  • 它又拉起了谁
  • 它之后落了什么文件
  • 它之后连了谁

0x09 建议的交付结构

进程树事件建议整理为如下表格:

时间父进程子进程路径/命令行关联结果结论
09:13:02WINWORD.EXEpowershell.exe-enc ...下载二阶段样本Office 触发执行
09:13:18powershell.execmd.execertutil/curl落地 EXE下载执行成立
09:13:41cmd.exefontdrvhost.exeC:\ProgramData\fontdrvhost.exe异常外联伪装后门运行
09:14:02fontdrvhost.exe持续连接公网出网链建立后门活跃

0x0A 总结

进程树分析的价值,在于它能把“分散的行为点”变成“连续的执行链”。很多时候,你并不需要一上来就拿到样本或内存转储,只要先把父子进程关系理顺,就能迅速回答:

  • 攻击从哪里开始
  • 中间经过了哪些解释器和 LOLBin
  • 最终落到了哪个后门、隧道或外传动作上

这也是为什么 系统进程检查0x02 升级到 0x03 后,不应该停留在“看当前有哪些进程”,而应该升级成“看进程树是否讲得通”。