当 Windows 服务器或终端出现异常行为时——CPU 飙升、不明外联、文件被篡改——安全人员需要在最短时间内判断系统是否已被入侵,并定位攻击者的活动痕迹。本文将系统讲解 Windows 环境下的应急排查方法,覆盖进程、网络、日志、注册表、计划任务和文件系统六大维度,提供大量可直接执行的排查命令。
Windows 安全事件类型
在开展排查之前,首先需要了解 Windows 环境中常见的安全事件类型:
- 恶意软件感染:勒索软件加密文件、挖矿木马占用资源、远控木马(RAT)建立持久化
- 账户安全事件:暴力破解、凭据窃取(Mimikatz)、横向移动(Pass-the-Hash)
- 权限提升:利用系统漏洞或配置缺陷从普通用户提权至管理员或 SYSTEM
- 持久化后门:通过注册表、计划任务、服务、WMI 等机制维持访问权限
- 数据外泄:敏感文件被压缩外传、数据库被非授权访问导出
进程排查
进程排查是应急响应的第一步。攻击者执行的恶意程序、反弹 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 进程排查的利器:
- 验证签名:Options → Verify Image Signatures,未签名的进程用红色高亮
- 查看 VirusTotal 检测:Options → Check VirusTotal.com,直接查询进程文件的恶意检测率
- 父子进程关系:树形视图直观展示进程层级,识别异常的父子关系(如 Word 启动了 cmd.exe)
- 查看 TCP/IP 连接:双击进程 → TCP/IP 标签页,查看进程的网络活动
- DLL 注入检测:查看进程加载的 DLL 列表,识别异常注入的模块
网络连接排查
恶意程序通常需要与 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 | 日志通道 | 含义 |
|---|---|---|
| 4624 | Security | 账户成功登录 |
| 4625 | Security | 账户登录失败 |
| 4648 | Security | 使用显式凭据登录(RunAs) |
| 4672 | Security | 分配了特权(管理员登录) |
| 4688 | Security | 新进程创建 |
| 4720 | Security | 新建用户账户 |
| 4732 | Security | 成员被添加到本地安全组 |
| 7045 | System | 新服务被安装 |
| 1102 | Security | 审计日志被清除 |
使用 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 系统中几乎所有的自启动位置。
关键功能:
- Hide Microsoft Entries:过滤微软签名的条目,快速定位第三方和可疑项
- Verify Code Signatures:验证所有条目的数字签名
- Check VirusTotal:提交文件哈希到 VirusTotal 进行多引擎检测
- Compare:与之前保存的基线快照对比,发现新增条目
命令行版本 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
安全建议与防御措施
- 启用完整的审计策略:确保进程创建(4688)、登录事件(4624/4625)、特权使用(4672)等关键事件均已开启审计
- 开启 PowerShell 日志:启用 Script Block Logging 和 Module Logging,记录所有 PowerShell 执行内容
- 配置 Sysmon:部署 Sysinternals Sysmon 并使用 SwiftOnSecurity 等开源配置模板,获取更细粒度的进程、网络和文件监控
- 建立系统基线:在系统正常运行时记录进程、服务、计划任务、自启动项的基线,便于对比发现异常
- 集中日志管理:将 Windows 事件日志转发至 SIEM 平台,防止攻击者清除本地日志后丢失证据
- 应用白名单策略:使用 AppLocker 或 WDAC(Windows Defender Application Control)限制非授权程序执行
总结
Windows 应急响应排查是一项系统性工作,需要从进程、网络、日志、注册表、计划任务和文件系统多个维度综合分析。掌握本文介绍的命令和工具,能够帮助安全人员在事件发生时快速定位异常、收集证据并判断攻击范围。建议将常用排查命令整理为脚本,并定期在测试环境中演练,确保在真实事件中能够高效执行。