跳转到帖子

内网横向移动痕迹排查:基于 Windows 事件日志的实战思路

精选回复

发布于

背景

内网安全排查里,横向移动是比较常见也最容易漏掉的一类行为。很多时候攻击者并不会使用特别“高级”的手法,而是借助已经获取的账号,通过 SMB、远程服务、计划任务、WMI、WinRM、RDP 等方式在主机之间移动。

如果现场没有完整的 EDR,Windows 事件日志依然是最基础、最可靠的数据源之一。本文主要围绕蓝队排查视角,整理一套基于 Windows 日志识别横向移动的分析方法,重点关注可落地的事件 ID、字段和检索思路。

技术分析

横向移动本质上会留下几类痕迹:

  • 认证行为:谁从哪里登录到了哪台机器。
  • 远程执行行为:是否创建服务、计划任务、远程进程。
  • 共享访问行为:是否访问 ADMIN$、C$、IPC$ 等管理共享。
  • 权限使用行为:是否出现特殊权限登录、凭据使用、票据异常。
  • 进程链异常:系统服务进程是否拉起了可疑命令。

常用事件日志主要包括:

  • Security:登录、权限、共享访问、进程创建等。
  • System:服务创建、服务启动失败、系统组件异常。
  • Microsoft-Windows-PowerShell/Operational:PowerShell 执行日志。
  • Microsoft-Windows-WMI-Activity/Operational:WMI 调用痕迹。
  • Microsoft-Windows-TaskScheduler/Operational:计划任务创建与执行。
  • Microsoft-Windows-WinRM/Operational:WinRM 远程管理行为。

关键事件 ID

以下事件在横向移动排查中比较实用。

1. 登录认证相关

事件 ID日志说明
4624Security登录成功,重点看 LogonType、IpAddress、TargetUserName
4625Security登录失败,常用于发现爆破、密码喷洒
4648Security使用显式凭据登录,常见于 runas、远程管理、工具调用
4672Security特权登录,管理员账号登录时常出现
4768DC SecurityKerberos TGT 请求
4769DC SecurityKerberos 服务票据请求,可用于分析访问目标服务
4776DC SecurityNTLM 认证,老环境和横向移动场景较常见

重点关注 4624 的 LogonType:

  • 2:交互式登录,本地控制台。
  • 3:网络登录,SMB、远程服务、IPC$ 常见。
  • 7:解锁。
  • 9:NewCredentials,常见于 runas /netonly。
  • 10:远程交互式登录,RDP。
  • 11:缓存交互式登录。

2. 远程服务与管理共享

事件 ID日志说明
7045System创建新服务,PsExec、远程服务执行常见
4697Security安装服务,需启用相应审计
5140Security访问网络共享
5145Security详细文件共享访问,可看到访问路径和权限

典型 PsExec 或类 PsExec 行为通常有以下组合:

  • 源主机到目标主机产生 4624,LogonType=3。
  • 访问 ADMIN$ 或 IPC$,出现 5140 / 5145。
  • 目标主机 System 日志出现 7045,新建服务。
  • 服务镜像路径可能包含临时 EXE、cmd.exe、powershell.exe。

3. 进程创建与脚本执行

如果开启了进程创建审计,事件 4688 非常关键,建议同时启用命令行记录:

  • 组策略路径:计算机配置 - 管理模板 - 系统 - 审核进程创建 - 在进程创建事件中加入命令行。
  • 注册表项:HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit\ProcessCreationIncludeCmdLine_Enabled

重点关注以下父子进程关系:

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

操作步骤

步骤一:确定时间窗口

先从告警时间、异常账号登录时间、异常流量时间反推排查窗口。通常建议至少向前回溯 24 小时,严重事件建议回溯 7 天以上。

如果只看单机日志,很容易漏掉路径。横向移动排查建议按“账号”和“源 IP”两个维度扩展:

  • 同一账号在多台主机上的登录轨迹。
  • 同一源 IP 对多台主机的认证行为。
  • 同一目标主机上是否出现服务创建、计划任务、WMI、PowerShell 记录。

步骤二:检查目标主机登录事件

在疑似受害主机上筛选 4624、4625、4648、4672。重点字段:

  • TargetUserName:登录账号。
  • IpAddress:来源地址。
  • WorkstationName:来源主机名,有时为空或不可靠。
  • LogonType:判断登录方式。
  • AuthenticationPackageName:Kerberos、NTLM。

步骤三:检查服务创建和共享访问

如果发现可疑 LogonType=3 登录,继续查目标主机同一时间附近是否有 7045、5140、5145。重点字段:

  • 7045:ServiceName、ImagePath、ServiceType、StartType。
  • 5140:ShareName,关注 \\*\ADMIN$、\\*\C$、\\*\IPC$。
  • 5145:RelativeTargetName,可看到具体访问文件。

步骤四:检查远程执行方式

不同横向方式的日志特征略有区别:

  • PsExec / 远程服务:4624 Type 3 + 5140/5145 + 7045。
  • WMI:4624 Type 3 + WMI-Activity 5857/5858/5861 + 4688 中 wmiprvse.exe 拉起进程。
  • WinRM:4624 Type 3 + WinRM Operational 日志 + wsmprovhost.exe 相关进程。
  • RDP:4624 Type 10 + 4778/4779 会话重连断开。
  • 计划任务:4698 或 TaskScheduler Operational 106/140/200/201。

代码示例

下面是一个简单的 PowerShell 排查脚本,用于在本机导出近 24 小时内比较关键的横向移动相关事件。实际使用时可以通过远程收集或日志平台批量执行。

$StartTime = (Get-Date).AddHours(-24)
$OutFile = "C:\Temp\lateral_movement_events.csv"

$EventMap = @{
    "Security" = @(4624,4625,4648,4672,4688,4697,4698,5140,5145)
    "System"   = @(7045)
    "Microsoft-Windows-WMI-Activity/Operational" = @(5857,5858,5861)
    "Microsoft-Windows-TaskScheduler/Operational" = @(106,140,200,201)
    "Microsoft-Windows-WinRM/Operational" = @(6,16,91,169)
    "Microsoft-Windows-PowerShell/Operational" = @(4103,4104)
}

$Results = foreach ($LogName in $EventMap.Keys) {
    foreach ($EventId in $EventMap[$LogName]) {
        try {
            Get-WinEvent -FilterHashtable @{
                LogName   = $LogName
                Id        = $EventId
                StartTime = $StartTime
            } -ErrorAction Stop | ForEach-Object {
                $xml = [xml]$_.ToXml()
                $data = @{}
                foreach ($d in $xml.Event.EventData.Data) {
                    if ($d.Name) {
                        $data[$d.Name] = $d.'#text'
                    }
                }

                [PSCustomObject]@{
                    TimeCreated = $_.TimeCreated
                    Computer    = $_.MachineName
                    LogName     = $LogName
                    EventId     = $_.Id
                    User        = $data["TargetUserName"]
                    SourceIp    = $data["IpAddress"]
                    LogonType   = $data["LogonType"]
                    ShareName   = $data["ShareName"]
                    ServiceName = $data["ServiceName"]
                    ImagePath   = $data["ImagePath"]
                    ProcessName = $data["NewProcessName"]
                    CommandLine = $data["CommandLine"]
                    ParentProc  = $data["ParentProcessName"]
                    Message     = ($_.Message -replace "`r|`n", " ")
                }
            }
        } catch {
            Write-Warning "Failed to query $LogName EventId=$EventId : $_"
        }
    }
}

$Results |
    Sort-Object TimeCreated |
    Export-Csv -NoTypeInformation -Encoding UTF8 $OutFile

Write-Host "Export finished: $OutFile"

如果有日志平台,可以把上述思路转成查询语句。一个比较实用的筛选逻辑是:

  • 先查 4624 且 LogonType in 3,9,10。
  • 按 SourceIp、TargetUserName 聚合,找短时间访问多台主机的组合。
  • 再关联同一目标主机 5 分钟内的 7045、4688、5140、5145。

典型判断规则

1. 管理员账号短时间登录多台主机

如果某个域管或本地管理员账号在短时间内从同一源 IP 登录大量服务器,需要重点确认是否为正常运维。尤其是非运维时间段出现时,风险较高。

2. 4624 Type 3 后紧跟 7045

这是远程服务执行的典型组合。注意不要只看服务名,一些工具会随机生成服务名,也可能伪装成正常服务。更关键的是 ImagePath,例如:

  • C:\Windows\Temp\*.exe
  • cmd.exe /c ...
  • powershell.exe -enc ...
  • \\127.0.0.1\ADMIN$\...

3. WMI 拉起命令解释器

正常业务里 wmiprvse.exe 很少直接拉起 cmd.exe、powershell.exe 执行复杂命令。若同时看到远程登录和 WMI-Activity 5858 异常,基本需要深入分析。

4. 共享访问 ADMIN$ 后出现异常文件

5145 可以看到具体文件访问路径。如果在 ADMIN$、C$ 下出现可执行文件写入,然后又出现服务创建或进程执行,基本可以串成完整链路。

注意事项

  • 日志策略要提前开启。 4688 命令行、5145 详细共享访问、PowerShell 4104 默认不一定完整开启,事后再开只能覆盖后续行为。
  • 不要孤立看单个事件。 4624 Type 3 在 Windows 环境很常见,必须结合源 IP、账号、时间、后续行为判断。
  • 注意 NAT 和跳板机。 来源 IP 可能是堡垒机、运维平台或代理节点,需要结合运维审计确认。
  • 域控日志很关键。 如果怀疑域账号被滥用,必须看域控上的 4768、4769、4776,而不是只看终端本地日志。
  • 攻击者可能清日志。 重点关注 1102 安全日志清除事件,以及日志服务异常、日志时间断层。
  • 时间同步很重要。 主机时间偏差会导致关联分析失败,内网建议统一 NTP。

加固建议

  • 限制本地管理员密码复用,优先部署 LAPS 或等价方案。
  • 普通办公账号和管理账号分离,域管账号禁止登录普通终端。
  • 关闭不必要的 ADMIN$ 访问面,至少通过防火墙限制管理端来源。
  • WinRM、WMI、远程服务管理只允许堡垒机或固定运维网段访问。
  • 开启 PowerShell Script Block Logging 和 Module Logging。
  • 对 7045、4698、4624 Type 10、异常 4648 建立基础告警。
  • 对“同一账号短时间登录多台主机”建立行为基线。

总结

横向移动排查不建议只依赖某一个事件 ID。比较可靠的方式是把认证、共享访问、远程执行、进程创建几类日志串起来看。

实战中最常用的入口通常是 4624、4648、7045、5140、5145、4688,再根据行为扩展到 WMI、WinRM、PowerShell 和计划任务日志。只要日志策略提前配置到位,即使没有高级安全产品,也能还原出相当一部分横向移动路径。

最后建议把这些规则固化到日志平台里,形成基础检测能力。靠人工临时翻日志可以救急,但长期来看还是要做自动化聚合和关联分析。

网络流量与边界分析示意图
网络请求、日志与边界流量分析示意
可以补一条排查思路:横向移动不要只看登录成功事件,建议把“登录类型 + 进程创建 + 服务安装 + 远程计划任务 + 认证源”串起来看,误报会少很多。 比较实用的 Windows 事件组合:
  • 4624:登录成功,重点看 LogonType
  • 4625:登录失败,爆破或口令喷洒
  • 4672:特权账号登录
  • 4688:进程创建,需要开启命令行审计
  • 7045:新服务安装,PsExec / Impacket 常见
  • 4698:计划任务创建
  • 5140 / 5145:共享访问,特别是 ADMIN$、C$、IPC$
  • 4768 / 4769 / 4771 / 4776:域控上的 Kerberos / NTLM 认证痕迹
横向移动场景里,比较值得优先盯这几类:
  1. PsExec / SMB 横向
    目标机常见痕迹是 4624 LogonType=3,随后出现 7045 服务安装,服务名可能是随机名,也可能是 PSEXESVC。同时文件共享日志里可能看到 ADMIN$ 写入。
  2. RDP 横向
    看 4624 LogonType=10,配合 4778/4779 会话重连/断开。很多时候攻击者会先用 SMB 验证账号,再 RDP 登录,所以源 IP 时间线也要串起来。
  3. WinRM / PowerShell Remoting
    一般是 4624 LogonType=3,进程侧可能有 wsmprovhost.exe、powershell.exe。如果开了 PowerShell 日志,重点看 4104 脚本块。
  4. WMI 横向
    目标机常见进程链是 wmiprvse.exe 拉起 cmd.exe、powershell.exe 或其他可疑程序。仅靠 4624 不容易判断,需要结合 4688。
可以先在目标机器上快速拉一段时间内的关键事件,例如最近 24 小时:
wevtutil qe Security /q:"*[System[(EventID=4624 or EventID=4625 or EventID=4672 or EventID=4688 or EventID=4698) and TimeCreated[timediff(@SystemTime) <= 86400000]]]" /f:text > C:\Temp\security_recent.txt

wevtutil qe System /q:"*[System[(EventID=7045) and TimeCreated[timediff(@SystemTime) <= 86400000]]]" /f:text > C:\Temp\service_install_recent.txt
如果环境里能用 PowerShell,筛选会更方便,比如查最近一天可疑登录类型:
$start = (Get-Date).AddDays(-1)

Get-WinEvent -FilterHashtable @{
    LogName='Security'
    Id=4624
    StartTime=$start
} | ForEach-Object {
    $xml = [xml]$_.ToXml()
    $data = @{}
    foreach ($d in $xml.Event.EventData.Data) {
        $data[$d.Name] = $d.'#text'
    }

    [PSCustomObject]@{
        Time        = $_.TimeCreated
        User        = "$($data.TargetDomainName)\$($data.TargetUserName)"
        LogonType   = $data.LogonType
        SourceIP    = $data.IpAddress
        Workstation = $data.WorkstationName
        Process     = $data.ProcessName
        AuthPackage = $data.AuthenticationPackageName
    }
} | Where-Object {
    $_.LogonType -in 3,10
} | Sort-Object Time | Format-Table -AutoSize
排查时我一般会按这个顺序做:
  • 先在域控上查异常账号认证来源:同一账号短时间访问多台主机、非常用源 IP、非办公时间登录。
  • 再到被访问主机上看 4624 的 LogonType 和 SourceIP。
  • 然后查同时间段是否有 7045、4698、4688。
  • 最后看进程链,比如 services.exe、wmiprvse.exe、wsmprovhost.exe 是否启动了命令解释器或落地程序。
另外建议提前确认这些审计项是否打开,否则事后很容易缺关键日志:
auditpol /get /category:*

auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Logoff" /success:enable
auditpol /set /subcategory:"Account Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable
auditpol /set /subcategory:"File Share" /success:enable /failure:enable
auditpol /set /subcategory:"Detailed File Share" /success:enable /failure:enable
auditpol /set /subcategory:"Security Group Management" /success:enable /failure:enable
进程命令行也建议打开,不然 4688 价值会低很多:
reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f
如果有 Sysmon,可以重点补充看这些事件:
  • Sysmon 1:进程创建
  • Sysmon 3:网络连接
  • Sysmon 7:镜像加载,辅助看注入
  • Sysmon 10:进程访问,比如凭据抓取
  • Sysmon 11:文件创建
  • Sysmon 13:注册表修改
一个小经验:不要只用单个事件定性,比如单独看到 4624 LogonType=3 不一定就是横向,正常访问共享也会触发。更可靠的是同一时间窗口内出现:
4624 LogonType=3/10
+ 4672 特权登录
+ 5140/5145 访问 ADMIN$/C$
+ 7045 服务安装 或 4698 计划任务
+ 4688 可疑进程链
这种链路基本就值得重点调查了。

补充一点,单看事件编号很容易把正常运维和横向移动混在一起,实际排查时我一般先围绕几个“关联键”做串联:TargetUserName、IpAddress、LogonId、ProcessId,再结合事件时间线。

RDP 不建议只盯 4624 Type=10,TerminalServices 相关日志通常更容易确认连接是否真正建立:

  • Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational:1149,远程身份验证成功;
  • Microsoft-Windows-TerminalServices-LocalSessionManager/Operational:21,建立会话;22,Shell 启动;24,断开会话;25,重连会话;
  • 安全日志 4624 Type=10:补充账号、来源地址、LogonId 等字段。

例如看到某源地址先触发 1149,随后出现 4624 Type=10 和 21,再在 4688 中出现 mstsc.exe、cmd.exe 或异常 PowerShell,可信度就明显高于单独一个 4624。

另外两类经常被漏掉:

  • WMI/DCOM:目标机可能只有 4624 Type=3,随后由 WmiPrvSE.exe 派生命令进程。可以重点看 4688 的父进程、命令行以及来源账号,常见可疑参数包括 process call create、Win32_Process、wmic /node。
  • WinRM/远程 PowerShell:除 4624 Type=3 外,检查 Microsoft-Windows-WinRM/Operational 和 Microsoft-Windows-PowerShell/Operational,关注 4103/4104 中的远程命令、Invoke-Command、Enter-PSSession、New-PSSession 等。

一个比较实用的关联方式是:以目标机上的 4624 为起点,记录其 LogonId,在同一时间窗口内查找 4688 的 SubjectLogonId。如果该登录会话随后创建了服务、计划任务、脚本解释器或凭据导出工具,优先级要高很多。示例查询可以先这样做:

$start = (Get-Date).AddHours(-2)

Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4624,4688,4698,7045
    StartTime = $start
} | ForEach-Object {
    [xml]$x = $_.ToXml()
    $d = @{}
    $x.Event.EventData.Data | ForEach-Object {
        if ($_.Name) { $d[$_.Name] = $_.'#text' }
    }

    [pscustomobject]@{
        Time       = $_.TimeCreated
        EventId    = $_.Id
        User       = $d.TargetUserName
        SourceIp   = $d.IpAddress
        LogonType  = $d.LogonType
        LogonId    = $d.TargetLogonId
        SubjectId  = $d.SubjectLogonId
        NewProcess = $d.NewProcessName
        CommandLine= $d.CommandLine
        Service    = $d.ServiceName
    }
} | Sort-Object Time

这里要注意 7045 在部分系统上属于 System 日志,不一定能和 Security 日志一次查全;建议单独查询 System 日志,并把服务创建时间与 4624/4688 做 ±2 分钟关联。服务名本身不可靠,随机服务名、合法服务名被复用都可能出现,最好再看服务二进制路径、签名、首次出现时间以及创建者账号。

审计配置方面,至少确认进程创建命令行和 PowerShell 日志已经打开:

auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable
auditpol /set /subcategory:"Other Object Access Events" /success:enable

reg add "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit" ^
 /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f

最后建议把“首次出现的源 IP + 非常用账号 + 非交互式登录 + 随后的远程执行”作为高优先级组合,而不是简单按 4624 或 4672 告警。域控、跳板机和运维账号的基线单独维护,否则日常批量运维会产生大量看似横向的事件。

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

最近浏览 0

  • 没有会员查看此页面。