Skip to content

Windows 应急响应实战 — 进程、日志、注册表排查

Published:
13 min read

当 Windows 服务器或终端出现异常行为时——CPU 飙升、不明外联、文件被篡改——安全人员需要在最短时间内判断系统是否已被入侵,并定位攻击者的活动痕迹。本文将系统讲解 Windows 环境下的应急排查方法,覆盖进程、网络、日志、注册表、计划任务和文件系统六大维度,提供大量可直接执行的排查命令。

Windows 安全事件类型

在开展排查之前,首先需要了解 Windows 环境中常见的安全事件类型:

进程排查

进程排查是应急响应的第一步。攻击者执行的恶意程序、反弹 Shell、挖矿进程都会以进程形式存在于系统中。

使用 tasklist 排查

:: 查看所有进程及其 PID
tasklist

:: 查看进程及其对应服务
tasklist /svc

:: 查看进程的详细信息(模块列表)
tasklist /m

:: 查看指定进程的模块
tasklist /m /fi "PID eq 1234"

:: 查找可疑进程名
tasklist /fi "IMAGENAME eq svchost.exe"

:: 查看远程会话中的进程
tasklist /fi "SESSION ne 0"

使用 WMIC 深入排查

:: 获取进程完整命令行(关键!恶意进程常通过命令行参数暴露)
wmic process get Name,ProcessId,ParentProcessId,CommandLine /format:list

:: 查看进程的可执行文件路径
wmic process get Name,ExecutablePath,ProcessId /format:csv

:: 查看进程的创建时间
wmic process get Name,ProcessId,CreationDate /format:list

:: 查找非标准路径下的可执行文件(可疑)
wmic process where "ExecutablePath is not null" get Name,ExecutablePath,ProcessId

使用 PowerShell 高级排查

# 获取进程详细信息,包含路径和命令行
Get-Process | Select-Object Id, ProcessName, Path, StartTime |
    Format-Table -AutoSize

# 查找没有签名的可执行文件进程(高度可疑)
Get-Process | Where-Object {$_.Path} | ForEach-Object {
    $sig = Get-AuthenticodeSignature $_.Path
    if ($sig.Status -ne 'Valid') {
        [PSCustomObject]@{
            PID = $_.Id
            Name = $_.ProcessName
            Path = $_.Path
            SignatureStatus = $sig.Status
        }
    }
} | Format-Table -AutoSize

# 查找从临时目录或用户目录运行的进程(可疑)
Get-Process | Where-Object {
    $_.Path -match '\\Temp\\|\\AppData\\|\\Downloads\\|\\Desktop\\'
} | Select-Object Id, ProcessName, Path | Format-Table -AutoSize

# 获取进程的完整命令行(Windows 10/Server 2016+)
Get-CimInstance Win32_Process |
    Select-Object ProcessId, Name, CommandLine, ParentProcessId |
    Format-List

# 查找与 svchost.exe 伪装的可疑进程
Get-CimInstance Win32_Process |
    Where-Object {$_.Name -eq 'svchost.exe' -and $_.ExecutablePath -ne 'C:\Windows\System32\svchost.exe'} |
    Select-Object ProcessId, Name, ExecutablePath, CommandLine

Process Explorer 使用要点

Sysinternals Process Explorer 是 Windows 进程排查的利器:

网络连接排查

恶意程序通常需要与 C2(Command & Control)服务器通信,因此网络连接排查是发现入侵的重要手段。

使用 netstat 排查

:: 查看所有活动连接及对应 PID
netstat -ano

:: 只看已建立的连接(ESTABLISHED)
netstat -ano | findstr "ESTABLISHED"

:: 只看监听端口
netstat -ano | findstr "LISTENING"

:: 查看连接对应的程序名
netstat -anob

:: 持续监控网络连接变化(每5秒刷新)
netstat -ano 5

使用 PowerShell 网络排查

# 查看所有 TCP 连接及关联进程
Get-NetTCPConnection |
    Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State,
    @{Name='Process';Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
    Format-Table -AutoSize

# 查找连接到外部 IP 的进程(排除本地和私有地址)
Get-NetTCPConnection -State Established |
    Where-Object {
        $_.RemoteAddress -notmatch '^(127\.|10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.|0\.0\.0\.0|::)'
    } |
    Select-Object RemoteAddress, RemotePort,
    @{Name='Process';Expression={(Get-Process -Id $_.OwningProcess).ProcessName}},
    OwningProcess |
    Format-Table -AutoSize

# 查看 DNS 缓存(可发现恶意域名解析记录)
Get-DnsClientCache | Select-Object Entry, Data |
    Format-Table -AutoSize

# 查看防火墙规则(排查攻击者添加的放行规则)
Get-NetFirewallRule | Where-Object {$_.Enabled -eq 'True' -and $_.Direction -eq 'Inbound'} |
    Select-Object Name, DisplayName, Action |
    Format-Table -AutoSize

系统日志分析

Windows 事件日志是安全调查最重要的证据来源之一。关键日志通道和事件ID如下:

事件ID日志通道含义
4624Security账户成功登录
4625Security账户登录失败
4648Security使用显式凭据登录(RunAs)
4672Security分配了特权(管理员登录)
4688Security新进程创建
4720Security新建用户账户
4732Security成员被添加到本地安全组
7045System新服务被安装
1102Security审计日志被清除

使用 wevtutil 命令行分析

:: 查询最近的登录失败事件(暴力破解检测)
wevtutil qe Security /q:"*[System[(EventID=4625)]]" /c:50 /f:text /rd:true

:: 查询新建用户事件
wevtutil qe Security /q:"*[System[(EventID=4720)]]" /c:20 /f:text /rd:true

:: 查询新安装的服务
wevtutil qe System /q:"*[System[(EventID=7045)]]" /c:20 /f:text /rd:true

:: 查询审计日志被清除的事件(高度可疑)
wevtutil qe Security /q:"*[System[(EventID=1102)]]" /c:10 /f:text /rd:true

:: 导出安全日志用于离线分析
wevtutil epl Security C:\IR\security.evtx
wevtutil epl System C:\IR\system.evtx
wevtutil epl Application C:\IR\application.evtx

使用 PowerShell 日志分析

# 查询最近24小时的登录失败事件
Get-WinEvent -FilterHashtable @{
    LogName='Security'
    Id=4625
    StartTime=(Get-Date).AddDays(-1)
} | Select-Object TimeCreated,
    @{Name='TargetUser';Expression={$_.Properties[5].Value}},
    @{Name='SourceIP';Expression={$_.Properties[19].Value}},
    @{Name='LogonType';Expression={$_.Properties[10].Value}} |
    Format-Table -AutoSize

# 查询 RDP 远程登录事件(LogonType=10)
Get-WinEvent -FilterHashtable @{
    LogName='Security'
    Id=4624
} -MaxEvents 200 | Where-Object {
    $_.Properties[8].Value -eq 10
} | Select-Object TimeCreated,
    @{Name='User';Expression={$_.Properties[5].Value}},
    @{Name='SourceIP';Expression={$_.Properties[18].Value}} |
    Format-Table -AutoSize

# 查询新创建的进程(需开启进程审计策略)
Get-WinEvent -FilterHashtable @{
    LogName='Security'
    Id=4688
    StartTime=(Get-Date).AddHours(-6)
} | Select-Object TimeCreated,
    @{Name='NewProcess';Expression={$_.Properties[5].Value}},
    @{Name='CommandLine';Expression={$_.Properties[8].Value}},
    @{Name='ParentProcess';Expression={$_.Properties[13].Value}} |
    Format-Table -AutoSize

# 统计登录失败的来源 IP(暴力破解检测)
Get-WinEvent -FilterHashtable @{
    LogName='Security'
    Id=4625
    StartTime=(Get-Date).AddDays(-7)
} | ForEach-Object {$_.Properties[19].Value} |
    Group-Object | Sort-Object Count -Descending |
    Select-Object -First 20 Name, Count

注册表自启动项排查

攻击者常利用注册表实现持久化。以下是需要重点检查的注册表位置:

常见自启动注册表键

# 用户级别自启动
$userRun = @(
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunServices",
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders",
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
)

# 系统级别自启动
$systemRun = @(
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run",
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce",
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run",
    "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon",
    "HKLM:\SYSTEM\CurrentControlSet\Services"
)

# 批量检查所有自启动项
foreach ($path in ($userRun + $systemRun)) {
    if (Test-Path $path) {
        Write-Host "=== $path ===" -ForegroundColor Yellow
        Get-ItemProperty $path | Format-List
    }
}

# 检查 Winlogon 的 Shell 和 Userinit(常被篡改)
Get-ItemProperty "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" |
    Select-Object Shell, Userinit

# 检查 Image File Execution Options(映像劫持)
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" |
    Where-Object {$_.GetValue('Debugger')} |
    ForEach-Object {
        [PSCustomObject]@{
            Name = $_.PSChildName
            Debugger = $_.GetValue('Debugger')
        }
    }

计划任务排查

:: 列出所有计划任务(详细格式)
schtasks /query /fo LIST /v

:: 查看指定路径的计划任务
schtasks /query /fo LIST /v /tn "\Microsoft\Windows\*"
# 查看所有非微软的计划任务(重点排查)
Get-ScheduledTask | Where-Object {
    $_.TaskPath -notmatch '\\Microsoft\\' -and $_.State -ne 'Disabled'
} | Select-Object TaskName, TaskPath, State,
    @{Name='Action';Expression={$_.Actions.Execute}} |
    Format-Table -AutoSize

# 查看最近创建的计划任务
Get-ScheduledTask | ForEach-Object {
    $info = Get-ScheduledTaskInfo $_.TaskName -ErrorAction SilentlyContinue
    [PSCustomObject]@{
        TaskName = $_.TaskName
        TaskPath = $_.TaskPath
        State = $_.State
        LastRun = $info.LastRunTime
        NextRun = $info.NextRunTime
        Action = ($_.Actions | ForEach-Object {$_.Execute}) -join '; '
    }
} | Sort-Object LastRun -Descending | Select-Object -First 30 |
    Format-Table -AutoSize

文件系统排查

# 查找最近3天内修改的可执行文件
Get-ChildItem -Path C:\Users, C:\Windows\Temp, C:\ProgramData -Recurse -ErrorAction SilentlyContinue |
    Where-Object {
        $_.LastWriteTime -gt (Get-Date).AddDays(-3) -and
        $_.Extension -match '\.(exe|dll|bat|ps1|vbs|js|cmd|scr|com)$'
    } | Select-Object FullName, LastWriteTime, Length |
    Sort-Object LastWriteTime -Descending |
    Format-Table -AutoSize

# 检查 ADS(Alternate Data Streams,备用数据流)
Get-ChildItem -Path C:\Users -Recurse -ErrorAction SilentlyContinue |
    ForEach-Object {Get-Item $_.FullName -Stream * -ErrorAction SilentlyContinue} |
    Where-Object {$_.Stream -ne ':$DATA' -and $_.Stream -ne 'Zone.Identifier'} |
    Select-Object FileName, Stream, Length

# 查找隐藏文件
Get-ChildItem -Path C:\ -Recurse -Hidden -ErrorAction SilentlyContinue |
    Where-Object {$_.Extension -match '\.(exe|dll|bat|ps1)$'} |
    Select-Object FullName, LastWriteTime, Attributes |
    Format-Table -AutoSize

# 查找大于100MB的可疑文件(可能是数据打包外传)
Get-ChildItem -Path C:\Users -Recurse -ErrorAction SilentlyContinue |
    Where-Object {$_.Length -gt 100MB -and $_.Extension -match '\.(zip|rar|7z|tar|gz)$'} |
    Select-Object FullName, @{Name='SizeMB';Expression={[math]::Round($_.Length/1MB,2)}}, LastWriteTime

Autoruns 工具使用

Sysinternals Autoruns 是排查持久化机制的终极工具,它覆盖了 Windows 系统中几乎所有的自启动位置。

关键功能:

命令行版本 autorunsc 使用:

:: 导出所有自启动项为 CSV 格式
autorunsc.exe -a * -c -h -s -v > C:\IR\autoruns.csv

:: 只显示非微软签名的条目
autorunsc.exe -a * -m -c -h -s > C:\IR\autoruns_nonms.csv

:: 对比两次扫描结果
autorunsc.exe -a * -c -h -s > C:\IR\autoruns_after.csv
:: 使用 diff 工具对比 autoruns_before.csv 和 autoruns_after.csv

安全建议与防御措施

  1. 启用完整的审计策略:确保进程创建(4688)、登录事件(4624/4625)、特权使用(4672)等关键事件均已开启审计
  2. 开启 PowerShell 日志:启用 Script Block Logging 和 Module Logging,记录所有 PowerShell 执行内容
  3. 配置 Sysmon:部署 Sysinternals Sysmon 并使用 SwiftOnSecurity 等开源配置模板,获取更细粒度的进程、网络和文件监控
  4. 建立系统基线:在系统正常运行时记录进程、服务、计划任务、自启动项的基线,便于对比发现异常
  5. 集中日志管理:将 Windows 事件日志转发至 SIEM 平台,防止攻击者清除本地日志后丢失证据
  6. 应用白名单策略:使用 AppLocker 或 WDAC(Windows Defender Application Control)限制非授权程序执行

总结

Windows 应急响应排查是一项系统性工作,需要从进程、网络、日志、注册表、计划任务和文件系统多个维度综合分析。掌握本文介绍的命令和工具,能够帮助安全人员在事件发生时快速定位异常、收集证据并判断攻击范围。建议将常用排查命令整理为脚本,并定期在测试环境中演练,确保在真实事件中能够高效执行。