Windows 安全审核策略与事件日志排查实务——成为看得懂 4625 的信息系统负责人

· 更新日期: · · Windows, 安全, 事件日志, 审核策略, 日志设计, PowerShell, 信息系统

更新记录(仅首版,2026年08月01日 发布)
首次发布
引用本文(DOI(已登记存档): 10.5281/zenodo.22175699)

以下 DOI 指向先前登记的存档,内容可能与当前正文不同。引用当前正文时,请使用本页网址。

Go Komura(2026)。《Windows 安全审核策略与事件日志排查实务——成为看得懂 4625 的信息系统负责人》。小村软件有限公司。 https://comcomponent.com/zh-CN/blog/windows-security-audit-policy-guide/

DOI(已登记存档)
10.5281/zenodo.22175699
DOI(上次登记版本)
10.5281/zenodo.22175700

“从昨晚开始,某个账户一直在反复锁定,帮忙查一下原因。”“想确认有没有人在用离职员工的账户尝试登录。”“这台服务器,能查出什么时候谁执行了什么吗?”——这些都是中小企业的信息系统负责人,或者向客户交付系统的开发者,某天突然会接到的请求。而此时唯一能指望的救命稻草,就是 Windows 的 Security 事件日志。

然而真正打开事件查看器后,等待你的是两种现实:想看的事件根本没有被记录(审核策略没有启用),或者被淹没在海量事件里读不出来(噪声太多、日志臃肿)。安全审核确实是“启用了就能记下来”的东西,但如果不设计录什么、录到什么程度,关键时刻就派不上用场。

打开事件查看器后等待你的两种现实打开事件查看器后,要么审核策略没有启用、想看的事件根本没有被记录,要么噪声太多、日志臃肿而使大量事件把想看的内容淹没,两者都需要设计录什么、录到什么程度没有记录下来被淹没打开事件查看器等待你的现实是?想看的事件未被记录事件太多读不出来审核策略未启用噪声太多、日志臃肿设计录什么、录到什么程度

图1:要么“没录下来”,要么“被淹没读不出来”。两者的原因都是没有设计记录范围。

本文把“为排查留下必要日志的配置”和“从留下的日志中查原因的步骤”分开梳理。 涵盖审核策略的机制(基本与高级两套体系)、中小规模环境下至少应启用的子类别、4624/4625/4740/4688 的读法、Security 日志的容量设计,以及用 PowerShell 排查的方法。技术说明基于 2026 年 8 月时点的一手资料。

如果说本站此前的 NTLM 审核SMB 签名BitLocker防火墙几篇文章讲的是“把防守做扎实”,那么本文讲的就是“让事后能够确认发生过什么”,是把它们串联起来的续篇。

1. 先说结论

要让日志真正能用于排查,需要凑齐三件事:“记录必要的内容”“在正确的机器上读正确的字段”“在消失之前固定下来”。 关键是不要只做到“启用审核”就收工。

准备做配置的人:统一到高级一侧,只记录必要的内容

  • 审核策略分为“基本”和“高级(Advanced Audit Policy)”两套体系,绝不能混用。微软明确写明,两者同时使用会让审核结果处于无法预期的状态。请统一到高级一侧(40 多个子类别)。1
  • 确认现状用 auditpol /get /category:*无论来自组策略还是本地设置,都能列出当前实际生效的审核配置。2
  • “全部启用”是绝对不能做的。启用会产生海量事件的子类别,关键事件就会被噪声淹没,还会影响性能。请以微软的基线建议为起点,只补上真正需要的部分。34

正在做排查的人:不要只看事件 ID,还要确认记录位置和字段

  • 登录成功是 4624,失败是 4625。4624 要靠登录类型(2=交互式、3=网络、10=远程桌面等)来区分“这是哪一种登录”。5
  • 4625 的失败原因由 Status/Sub Status 代码确定。常见的有 0xC0000064=用户名不存在、0xC000006A=密码错误、0xC0000072=账户已被禁用、0xC0000234=处于锁定状态。6
  • 每个事件“记录在哪台机器上”都是固定的。4624/4625 记录在被访问的一侧,凭据验证(4776)记录在对该凭据具有权威的机器上(域账户即域控制器),Kerberos 预身份验证失败(4771)记录在域控制器上。看错机器就会误判为“没有日志”。678

两边都需要:设计日志保留与机密信息的处理方式

  • Security 日志有一半的功夫在容器设计(最大大小与保留方式)上。如果保留方式是覆盖模式,旧事件就会被逐条挤掉。用 Get-WinEvent -ListLog Security 确认最大大小和记录数,再从需要的保留天数反推扩容。910
  • 进程创建(4688)的命令行记录很有力,但代价是机密会以明文留在日志里。启用前先检查各类脚本。1112

按目的和症状选择该读的地方

现在想知道的事 先要掌握的 该读的地方
想把审核配置理顺 先确认实际生效的设置和日志容量,再挑选需要的子类别 第 2 章:确认设置第 5 章:容量与保留第 3 章:判断表
想读懂登录的成功与失败 成功看登录类型,失败看 Status/Sub Status 4.1:46244.2:4625
想知道反复锁定的原因 用 4740 找来源,失败的痕迹还要到访问目标和域控制器上确认 4.3:4740
想查谁执行了什么 读 4688 的父进程,以及 4698 的任务定义。追加命令行记录前需要事前检查 4.5:46884.6:4698第 7 章:注意事项
想看的日志没有,或者很快消失 确认记录位置、审核设置和实际还留着的时间范围 第 2 章第 5 章第 7 章
想成批地查日志 先用 evtx 固定下来,再按 ID 和时间范围筛选提取 6.3:固定6.2:PowerShell

如果已经接到排查请求,请先按 6.3 把日志固定下来,确认第 7 章关于记录位置和时钟同步的注意事项,再去读第 4 章对应的事件。 如果是做配置,请先用第 2 章和第 5 章确认现状,然后进入第 3 章。

图中实线表示始终成立的关系,虚线表示带条件的关系(成立条件写在详情页各关系的说明中)。关系的完整列表(共 34 条,附依据与确信度)以及主要概念的定义,汇总在知识地图详情页(日文)。数据:JSON-LD / Turtle

2. 审核策略的基础——不要把“基本”和“高级”混在一起

2.1. 弄清配置位置与粒度的差别

Windows 的审核策略有两套体系。1

  • 基本审核策略:位于“本地策略 > 审核策略”下的 9 个类别设置。这是 Windows Vista 之前就存在的旧体系。
  • 高级审核策略(Advanced Audit Policy Configuration):位于“安全设置 > 高级审核策略配置”下的 40 多个子类别设置。它把基本的一个类别拆成了多个子类别,例如基本的“审核账户登录事件”这一个类别,在高级一侧对应 4 个子类别。在基本一侧启用一个类别,等同于把对应的子类别全部启用,连不关心的事件也会被大量记录。1

2.2. 统一到高级一侧,防止基本一侧覆盖

要点在于,这两套体系并不兼容。微软明确写道:不要同时使用基本和高级,否则审核结果会处于无法预期的状态。

用组策略下发高级审核策略时,这台计算机上已有的审核设置会先被清除,然后才应用高级一侧的设置;此后只有在高级一侧才能可靠地控制。

在使用高级一侧的环境里,要启用安全选项“审核:强制审核策略子类别设置”,让基本一侧的设置无法覆盖过来(独立计算机上默认已启用)。14

基本审核策略与高级审核策略的关系基本审核策略与高级审核策略并不兼容,两者同时使用会让审核结果处于无法预期的状态,因此要统一到高级一侧并启用强制子类别设置,防止基本一侧覆盖基本审核策略(9 个类别)两者同时使用?高级审核策略(40 多个子类别)审核结果无法预期统一到高级一侧启用强制子类别设置防止基本一侧的设置覆盖

图2:两套体系并不兼容。统一到高级一侧,用“强制”设置防止基本一侧覆盖。

2.3. 用 auditpol 确认“最终生效的设置”

确认现状只需要一条命令,在管理员命令提示符下执行。2

下面这个例子里是显示现状、变更前备份、还原这三个彼此独立的操作。先确认显示结果,变更之前先做备份。/restore 那一行是需要还原时才执行的,并不是为了确认现状而接着执行的步骤。

rem 按子类别列出当前生效的审核设置
auditpol /get /category:*

rem 变更前的备份(CSV)与还原
auditpol /backup /file:C:\logs\auditpol-backup.csv
auditpol /restore /file:C:\logs\auditpol-backup.csv

auditpol 的输出是“最终生效的策略”,与来自组策略还是本地设置无关。本应由组策略下发的设置没有生效时,也可以用它来做比对。

另外,审核设置本身被更改时会记录事件 4719,因此“不知不觉间审核被关掉了”这类情况也能事后追查。12

auditpol 显示的是最终生效的策略auditpol 的输出是最终生效的审核策略,与设置来自组策略还是本地无关,可用于组策略未生效时的比对,而审核设置本身的更改会记录为事件 4719 供事后追查组策略下发的设置最终生效的策略本地的设置用 auditpol /get 列出可用于组策略未生效时的比对审核设置本身的更改记录 4719 可事后追查

图3:auditpol 不问来源,返回“正在生效的设置”。审核设置的更改本身留在 4719 里。

3. 至少应启用的子类别判断表

3.1. 不做“全部启用”的理由

“先全部启用再说”之所以是坏招,理由很明确。例如把特权使用类的子类别连成功也一起审核,事件量会变得极其庞大,在安全日志中找别的条目会变得困难,而且微软警告说还会影响性能。4 日志的容器(第 5 章)是有限的,录进去的噪声越多,真正需要的事件的保留天数就被削得越短。所谓审核设计,就是决定“不录什么”。

全部启用之所以是坏招启用所有子类别会产生大量事件,关键事件被噪声淹没并影响性能,而且在有限的日志容器中还会削减必要事件的保留天数启用所有子类别产生大量事件关键事件被淹没影响性能保留天数被削减决定不录什么才是审核设计

图4:“全部启用”会把关键事件淹没。决定不录什么,才是审核设计。

3.2. 以基线为起点,挑选需要的记录

微软按工作站和服务器分别公开了基线建议和强化建议,这是起点。3 在此基础上,下表是从中小规模环境“出事时至少想读到这些”的角度整理出来的。这是本文以微软建议为起点做出的判断表,并不是可以一律套用到所有环境的设置清单。

子类别(类别) 主要事件 ID 能看出什么 中小规模环境的建议
登录(登录/注销) 4624 / 4625 登录的成功与失败、登录类型、来源 成功+失败。Windows 10 1809 以后默认也已启用成功与失败3
特殊登录(同上) 4672 / 4964 带管理员特权的登录的发生 成功
账户锁定(同上) 4625 针对锁定中账户的登录失败 失败(4625 是失败事件,这个子类别不存在成功事件)13
用户账户管理(账户管理) 4720 / 4726 / 4738 / 4740 账户的创建、删除、修改、锁定 成功+失败
安全组管理(同上) 4728 / 4732 / 4756(添加)、4729 / 4733 / 4757(删除) 向管理员组等添加或删除成员(全局/本地/通用) 成功(这个子类别不存在失败事件)14
凭据验证(账户登录) 4776 NTLM 身份验证的成败。域账户记录在域控制器一侧7 成功+失败
Kerberos 身份验证服务(同上,仅域控制器) 4768 / 4771 TGT 颁发与预身份验证失败(密码错误等)8 在域控制器上成功+失败
进程创建(详细跟踪) 4688 谁、从哪个父进程、启动了什么 成功。命令行记录请先读第 7 章的注意事项
其他对象访问事件(对象访问) 4698 计划任务的创建(攻击持久化的常见手法)15 可考虑启用成功
审核策略更改(策略更改) 4719 审核设置本身的更改 成功+失败

3.3. 会大量记录的,要缩小对象和时间范围

反过来,文件系统和注册表的对象访问审核、特权使用、数据包筛选类(如 5152)默认不要去碰比较稳妥。这些东西只有在缩小了对象的 SACL 配置下、或在排查期间限时开启时才有用,长期全开会把日志吃光。4

大量事件类子类别的处理方式文件系统和注册表的对象访问审核、特权使用以及数据包筛选类子类别长期全开会把日志吃光,只有在缩小对象的 SACL 配置下或排查期间限时开启时才有用长期全开缩小对象的 SACL排查期间限时开启大量事件类子类别怎样启用?对象访问审核特权使用、数据包筛选类把日志吃光有用有用

图5:对象访问和特权使用不要长期全开。缩小对象和时间范围才有用。

4. 常见事件 ID 的读法

要把“是哪个事件”“留在哪台机器上”“看哪个字段”作为一组来确认。 登录看 4.1 和 4.2,锁定看 4.3,账户变更看 4.4,被执行的操作看 4.5 和 4.6。实际排查时,请先按 6.3 的方法固定日志

4.1. 4624——登录成功要按登录类型分开读

4624 是“已成功登录账户”,记录在创建了登录会话的机器(被访问的一侧)上5 它是会被大量记录的事件,所以读的时候先按登录类型分类。5

登录类型 名称 实务中的含义
2 Interactive 在那台电脑的控制台上登录
3 Network 经由网络的访问(共享文件夹、管理工具等)。有多少台就出多少条,数量最多
4 Batch 批处理执行(计划任务等)
5 Service 服务的启动(服务控制管理器)
7 Unlock 解除屏幕锁定
8 NetworkCleartext 密码以明文形式传给身份验证包的网络登录
9 NewCredentials 复制另一份凭据(相当于 runas /netonly)
10 RemoteInteractive 远程桌面
11 CachedInteractive 使用缓存凭据的登录(连不上域控制器的状态)

按类型分类之后,再看账户、来源和权限

要一并查看的字段是:“新登录”中的账户名、“网络信息”中的源地址、“身份验证包”(是 NTLM 还是 Kerberos),以及“提升的令牌”(是不是管理员特权会话)。如果只想追踪管理员特权的登录,还可以用以相同登录 ID 记录的 4672(分配了特殊特权)。5

分开读 4624 的步骤会被大量记录的 4624 先按登录类型分类,再确认账户名与来源、身份验证包和提升的令牌,管理员特权的登录则与相同登录 ID 的 4672 做关联4624 登录成功按登录类型分类确认主要字段账户名与来源身份验证包提升的令牌追踪管理员特权相同登录 ID 的 4672

图6:4624 先按登录类型分类,再读字段。特权登录与 4672 做关联。

4.2. 4625——失败原因由 Status/Sub Status 代码确定

4625 是“账户登录失败”,记录在发起登录尝试的那台机器上6 比起“失败原因”栏里的文字,用 Status/Sub Status 的十六进制代码来读更可靠。常见的如下。6

先用 Status/Sub Status 读出失败原因

  • 0xC0000064:用户名不存在。如果短时间内连续出现,就是账户枚举攻击的迹象
  • 0xC000006A:密码错误。如果针对特定账户连续出现,就是密码猜测攻击的迹象
  • 0xC000006D:用户名或身份验证信息不正确
  • 0xC000006F:不在允许的时间段内
  • 0xC0000070:来自未被允许的工作站
  • 0xC0000072:被管理员禁用的账户(针对离职员工账户的尝试会出现在这里)
  • 0xC000015B:这台机器不允许所请求的登录类型
  • 0xC0000193:已过期的账户
  • 0xC0000234:处于锁定状态

把目标账户、来源和失败原因组合起来

“谁、从哪里、为什么失败”,要靠目标账户+来源(工作站名/IP 地址)+这个代码这三件套来确定。6.2 给出了一次性提取这三项的 PowerShell 代码。

确定 4625 失败原因的流程4625 的失败原因由 Status/Sub Status 的十六进制代码确定,先从代码的趋势读出攻击迹象,再结合目标账户和来源以三件套锁定0xC0000064 连续出现0xC000006A 连续出现0xC00000724625 登录失败确认 Sub Status 代码代码的趋势如何?账户枚举的迹象密码猜测的迹象针对离职员工账户的尝试用三件套确定目标账户+来源+代码

图7:失败原因由代码确定,再与目标账户、来源组成三件套来读。

4.3. 4740——锁定的来源就是“调用方计算机名”

找来源:4740 的调用方计算机名

4740 是“用户账户已被锁定”(子类别是用户账户管理)。这个事件的主角是“调用方计算机名(Caller Computer Name)”字段,那里记录着触发锁定的登录尝试来自哪台计算机16 先在这里锁定来源终端,再排查那台终端上残留的旧凭据,这是标准套路。

原因大多是某个在密码更改后仍继续使用旧凭据的东西(已保存的凭据、一直处于断开状态的远程桌面会话、用旧密码配置的服务或任务)。

账户锁定排查的标准套路用 4740 的调用方计算机名锁定来源终端,再排查该终端上残留的已保存凭据、一直处于断开状态的远程桌面会话以及用旧密码配置的服务或任务4740 发生锁定确认调用方计算机名锁定来源终端排查旧凭据已保存的凭据一直断开的远程桌面会话用旧密码配置的服务或任务

图8:从 4740 的“调用方计算机名”锁定来源,再排查那台终端上的旧凭据。

找失败的痕迹:不看来源,也要看接受请求的一侧

有一点需要注意。4625 记录在接受登录尝试的一侧计算机上。如果原因是来源终端对文件服务器等发起的网络登录,来源终端自己的 Security 日志里不会留下 4625,痕迹留在访问目标服务器的 4625 上;如果是域账户,则留在域控制器一侧的 4776(NTLM)/4771(Kerberos 预身份验证失败)上。78 “来源终端的日志里什么都没有”时,请去看接受请求的一侧。

排查流程可以整理成:用 4740 的调用方找来源 → 按时间顺序比对访问目标的 4625 和域控制器的 4776/4771 → 确认来源终端上的已保存凭据、服务、任务等。找来源和找失败事件的记录位置是两件事。

失败痕迹留在哪台机器上网络登录的失败不会留在来源终端自身上,而是记录在接受登录尝试的访问目标服务器的 4625 里,如果是域账户,域控制器一侧的 4776 和 4771 也会留下痕迹网络登录域账户的身份验证来源终端(自身不留 4625)访问目标服务器记录 4625域控制器4776(NTLM)/4771(Kerberos)

图9:4625 留在接受请求的一侧。来源终端上什么都没有时,就去看访问目标服务器和域控制器一侧。

4.4. 4720 系列——账户的创建、修改与组成员添加

把账户的变更和组成员的变更分开

账户管理类的编号是连着的:4720(创建用户账户)17、4726(删除)、4738(修改),以及组一侧的成员添加/删除。

组成员的变更要注意事件 ID 会按组的类型分开。本地组是 4732/4733,全局组是 4728/4729,通用组是 4756/4757。14 Domain Admins 是全局组,所以向它添加成员记录在 4728 里——如果只把 4732 设为告警条件,最想看到的事件恰恰会被漏掉。

对管理员组的意外添加,哪怕只有一次也要查

日常情况下这些只是服务台工作的记录,但“标准用户突然被加进了管理员组”“出现了谁都不认识的账户”,哪怕只发生一次也要立即调查。微软也把向特权组意外添加成员列为单次即告警的例子。3

组的类型与成员添加事件向组添加成员的事件 ID 会按组的类型分开,本地组记录为 4732,全局组记录为 4728,通用组记录为 4756,因此向全局组 Domain Admins 添加成员要看 4728本地全局通用向组添加成员组的类型是?记录为 4732记录为 4728记录为 4756向 Domain Admins 添加在这里只盯 4732 会漏掉

图10:成员添加的事件 ID 按组的类型分开。向 Domain Admins 添加是 4728。

4.5. 4688——进程创建。命令行记录是另一个开关

进程创建审核能看出什么

4688 是“已创建新进程”,每次创建进程都会记录创建它的账户、新进程的可执行文件路径、父进程和令牌提升类型。11 它能回答“这台服务器上谁执行了什么”,排查价值很高。

要留下命令行,需要另一项设置和事前检查

不过默认情况下不会记录命令行参数。只有另外启用“在进程创建事件中包含命令行”这项组策略(管理模板 > 系统 > 审核进程创建),4688 的“进程命令行”字段里才会有参数。1112 要追踪 powershell -EncodedCommand ... 这类可疑启动,它实际上是必需的设置,但请先理解第 7 章讲的机密混入风险再启用。先读第 7 章,把用参数传递机密的地方改掉,然后再做配置。

4688 与命令行记录的关系启用进程创建审核后 4688 会记录账户、可执行文件路径和父进程,但命令行参数只有另外启用一项组策略才会被记录,并且存在机密以明文写入的风险保持默认额外启用组策略启用进程创建审核记录 4688账户、路径、父进程也想看参数?命令行为空记录参数机密以明文写入的风险

图11:4688 的命令行记录是另一个开关。启用之前先检查机密混入风险。

4.6. 4698——计划任务的创建

4698 是“已创建计划任务”,会记录任务名和任务定义的 XML 全文(含执行命令)。恶意软件为了在重启后继续存活,惯用手法就是注册任务,因此微软建议监视任务创建事件。15 即便在业务上大量使用任务的环境里,创建也不是天天发生的事,所以噪声较小。

通过注册任务实现持久化与 4698恶意软件为了在重启后继续存活惯用注册计划任务的手法,因此监视任务创建时记录的 4698,就能追到含执行命令的任务定义恶意软件的持久化注册任务以继续存活记录 4698含执行命令的 XML 全文监视任务创建以检测创建并不频繁,噪声小

图12:持久化的惯用手法注册任务会留在 4698 里。从定义 XML 全文能追到执行命令。

日志本身是否被清除,还要确认 1102

另一个值得记住的是 1102“审核日志已被清除”。清除 Security 日志必定会留下这个事件,因此“日志变空了”时,可以据此区分是出问题还是有人操作。18

用 1102 区分日志清除清除 Security 日志必定会留下 1102,因此日志变空时只要确认有没有 1102,就能区分是有人执行了清除操作还是出了问题没有日志变空了清除必定留下 1102有没有 1102?发生过清除操作怀疑是出了问题

图13:清除 Security 日志必定留下 1102。空日志靠有没有 1102 来区分是出问题还是操作。

5. 日志容器的设计——最大大小与保留

5.1. 满了之后,丢的是“旧记录”还是“新记录”

在增加审核策略之前,先确认承接它的容器。Security 日志有最大大小和保留方式,在覆盖模式(接近默认的配置)下,达到最大大小后新事件会覆盖最旧的事件。反过来,在保留模式(不覆盖)下,日志满了之后被丢弃的是新事件10 两种行为都会造成“回头一看日志没了”,所以要先掌握现状。

5.2. 从实际还留着的天数来考虑需要的容量

# 确认 Security 日志的容器: 保留方式、最大大小、当前记录数
Get-WinEvent -ListLog Security |
    Select-Object LogName, LogMode, MaximumSizeInBytes, RecordCount

# 现在实际还留着多少天(最旧事件的时间)
Get-WinEvent -LogName Security -Oldest -MaxEvents 1 |
    Select-Object TimeCreated

Get-WinEvent -ListLog 会一并返回日志的配置和记录数。9“最旧事件的时间”与当前时间之差就是实际的保留天数,如果它不满足自家的要求(事件排查时想回溯的天数),就扩大最大大小。设置可以用 wevtutil sl Security /ms:<字节数> 或通过组策略下发。10

容量要从“想留多少天”来考虑。 增加审核子类别会让事件量一起增加,所以改完设置之后要重新确认实际还留着的天数。还需要有在被覆盖之前定期导出、或汇总到另一台机器的运维做法。

从保留天数反推的容量设计用 Get-WinEvent 的 ListLog 确认配置和记录数,从最旧事件的时间算出实际的保留天数,若不满足事件排查想回溯的天数就扩大最大大小满足不满足用 ListLog 确认配置和记录数确认最旧事件的时间算出实际的保留天数满足要求吗?维持现有大小扩大最大大小用 wevtutil sl 或组策略配置

图14:确认实际还留着的天数,从想回溯的天数反推最大大小。

5.3. CrashOnAuditFail 不是解决容量不足的设置

另外,安全选项里还有“审核:如果无法记录安全审核则立即关闭系统”(也就是常说的 CrashOnAuditFail)。启用后一旦无法记录审核,系统会以 STOP 错误 C0000244 停止。它是为绝对不能丢失审核痕迹的合规要求准备的设置,默认是禁用。

微软自己也提醒,它可能被转化为攻击者刻意产生大量事件来停掉服务器的 DoS,因此在一般的中小规模环境里不应轻易启用。19

日志满了之后的行为保留的配置有覆盖模式和不覆盖模式两种,在不覆盖模式下无法记录审核时,如果另一项独立设置 CrashOnAuditFail 已启用,系统会以 STOP 错误 C0000244 停止覆盖模式不覆盖Security 日志达到最大大小保留的配置是?最旧的事件被覆盖新事件被丢弃两者都会造成回头一看日志没了CrashOnAuditFail 也启用了?以 STOP 错误 C0000244 停止

图15:保留的配置有覆盖和丢弃两种。CrashOnAuditFail 是另一项独立设置,在无法记录时让系统停止。

6. 排查的实务——筛选、Get-WinEvent 与导出

实际动手的顺序是“6.3 固定 → 6.1 或 6.2 分析”。 这里按排查手段分别说明。一次性的用事件查看器,数量大或者要反复做的排查用 PowerShell。

6.1. 在事件查看器里筛选

一次性的排查用事件查看器就够了。打开 Security 日志,用“筛选当前日志”指定事件 ID(例如 4625)和时间范围。要反复查看的条件可以用“创建自定义视图”保存下来,下次一键就能用。如果不只想按事件 ID、还想按特定账户等筛选,可以在筛选对话框的 XML 选项卡里直接编辑 XPath 查询。

6.2. 用 Get-WinEvent 提取

数量大的排查、多条件、定期执行,就切换到 PowerShell 的 Get-WinEvent。要点是使用让筛选在服务端生效的 -FilterHashtable9

排查手段的区分使用一次性的排查用事件查看器的筛选就够了,要反复查看的条件保存为自定义视图,数量大的排查、多条件和定期执行则切换到 Get-WinEvent一次性要反复查看的条件大量、多条件、定期是什么样的排查?用事件查看器筛选保存为自定义视图切换到 Get-WinEvent用 FilterHashtable 筛选

图16:一次性用事件查看器,要反复做就用自定义视图,数量大就用 Get-WinEvent。

按 ID 和时间范围筛选,取出目标账户、来源和失败原因

下面前半段取出最近 24 小时的 4625。后半段取出 XML 的各个字段,是按账户、Status、SubStatus、来源的组合分别统计条数的例子。最后那张表不是单条事件按时间排序的列表,而是按相同组合出现了多少次、从多到少显示。

# 取得最近 24 小时的登录失败(4625)
Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4625
    StartTime = (Get-Date).AddDays(-1)
}

# 把“谁、从哪里、为什么”整理成表
Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4625
    StartTime = (Get-Date).AddDays(-1)
} | ForEach-Object {
    $x = [xml]$_.ToXml()
    $d = @{}
    $x.Event.EventData.Data | ForEach-Object { $d[$_.Name] = $_.'#text' }
    [pscustomobject]@{
        Time      = $_.TimeCreated
        Account   = "$($d.TargetDomainName)\$($d.TargetUserName)"
        LogonType = $d.LogonType
        Source    = "$($d.WorkstationName) $($d.IpAddress)"
        Status    = $d.Status
        SubStatus = $d.SubStatus
    }
} | Group-Object Account, Status, SubStatus, Source |
    Sort-Object Count -Descending |
    Format-Table Count, Name -AutoSize

从 XML 读取必要字段的套路,也可以用到其他事件上

把这种从事件的 XML 表示中抽出 EventData 的套路留一份在手边,4624 也好 4688 也好,都能照同样的要领复用。Get-WinEvent 的筛选设计(FilterHashtable 与 XPath 的区分使用、慢查询的改法)在“用 Get-WinEvent 实务地排查事件日志”里有详细讨论。

抽出 EventData 的整形套路把 Get-WinEvent 取得的事件转换成 XML 表示,抽出 EventData 的各个字段并整理成表,这个套路不限于 4625,在 4624 和 4688 上也能照同样的要领复用用 Get-WinEvent 取得把事件转换成 XML 表示抽出 EventData整理成表并统计4624 和 4688 也是同样要领

图17:从 XML 表示抽出 EventData 再整理成表的套路,换了事件 ID 也能复用。

6.3. 用 wevtutil 导出

被排查机器上的日志,原则上要先导出保全下来,赶在被覆盖消失之前。10

rem 把 Security 日志整体以 evtx 保全
wevtutil epl Security C:\logs\security-20260801.evtx

rem 只把 4625 用 XPath 筛选后导出
wevtutil epl Security C:\logs\security-4625.evtx /q:"*[System[(EventID=4625)]]"

把保存下来的 evtx 拿到另一台机器上分析

导出的 .evtx 可以在另一台机器上用 Get-WinEvent -Path C:\logs\security-20260801.evtx 照同样的方式分析。9 先保全再分析这个习惯,和崩溃排查中“先把转储拿到手”是同一个思路(参见“Windows 崩溃转储收集入门”)。

先保全再分析的流程用 wevtutil epl 把被排查机器的 Security 日志导出成 evtx 文件保全下来,再在另一台机器上通过 Get-WinEvent 的 Path 参数照同样的方式分析被排查的机器用 wevtutil epl 保全成 evtx带到另一台机器用 Get-WinEvent -Path 分析赶在被覆盖消失之前拿到手

图18:先保全,再分析。保全成 evtx 就能在另一台机器上照样排查。

7. 陷阱——现场最容易踩的四个

7.1. 机密混进 4688 的命令行

启用命令行记录后,所有进程的参数都会以明文进入 Security 日志。微软明确写道:“任何具有安全事件读取权限的用户,都能读到任何进程的命令行参数。参数中可能含有密码等机密。”12 只要有一个业务应用或脚本用 myapp.exe /user:admin /password:P@ssw0rd 这样的方式启动,那就是把机密公开给了所有能看日志的人。

启用之前,要把用参数传递机密的地方找出来并改掉。日志的保全位置和转发目的地也需要同等级别的保护。

启用命令行记录的顺序4688 的命令行记录在启用之前要先找出用参数传递机密的业务应用和脚本,把相关位置改掉之后再启用,并对日志的保全位置和转发目的地要求同等级别的保护没有找出用参数传递机密的地方有没有符合的?改掉传递机密的地方启用命令行记录保全位置和转发目的地同等级别保护

图19:命令行记录要“先找出来改掉,再启用”。顺序反了就是公开机密。

7.2. 不了解日志满了之后的行为就上线运行

覆盖模式下旧的痕迹会悄悄消失,设为不覆盖时新事件会被丢弃,启用了 CrashOnAuditFail 则整个系统会停(第 5 章)。1019 正道是先掌握自己选的是哪种行为,再准备好“在消失之前收集起来”的机制(定期导出或日志采集平台)。

7.3. 域控制器和终端上该看的日志不一样

4624/4625 记录在被访问的机器上。56 而域账户的凭据验证(NTLM 的 4776)记录在对该凭据具有权威的机器上,也就是域账户对应域控制器7,Kerberos 的预身份验证失败(4771)则记录在域控制器上。8 不能认为“文件服务器上没有 4625=没有发生攻击”,只有把域控制器一侧的 4776/4771 也比对上,才能得到全貌。各种身份验证协议具体怎么流转,请参见“图解 NTLM 与 Kerberos”。

7.4. 时钟不同步就无法比对

把多台机器的日志并排起来,追查“这条 4740 之前哪台终端出现了 4625”,前提是各台机器的时钟是对齐的。在域环境里,Kerberos 本身就对时钟偏差设了上限(默认 5 分钟),超过之后身份验证本身就会开始失败。20 从排查的角度看,别说 5 分钟,几秒的偏差都会让先后关系被误读,所以要把确认 w32time 的同步状态放进排查步骤的第一步。

另外,事件的记录时间以 UTC 保存,显示时按查看机器的时区,因此读取从海外站点或设为 UTC 的服务器上拿来的 evtx 时,别忘了做时区换算。

时钟同步与比对排查的前提把多台机器的日志按时间顺序比对的排查以各台机器时钟对齐为前提,几秒的偏差就会让先后关系被误读,超过默认 5 分钟的偏差还会让 Kerberos 身份验证本身失败,因此要把 w32time 的确认放进排查步骤的第一步对齐几秒的偏差超过默认的 5 分钟比对多台机器的日志以时钟对齐为前提时钟偏差有多大?能按时间顺序追踪误读先后关系Kerberos 身份验证失败把 w32time 的确认放在步骤第一步

图20:多台机器的比对以对时为前提。几秒的偏差也会导致先后关系被误读。

8. 总结

要把 Windows 的 Security 日志用于排查,需要把记录的范围、读的位置和字段、保全的机制放在一起设计。

做配置的时候

审核策略不要把“基本”和“高级”混在一起,统一用高级一侧。用 auditpol /get /category:* 确认现状,以微软的基线建议为起点,从第 3 章中以登录、账户管理、进程创建为轴的判断表开始。设成“全部启用”会因为噪声和臃肿让排查变难。

日志的容器(最大大小、保留方式)占了审核设计的一半。确认实际还留着的天数,从要求反推决定大小,并在消失之前导出或汇总。4688 的命令行记录要先检查机密混入的风险再启用。

做排查的时候

先保全,再分析。用 wevtutil epl 拿到手,确认每台机器的记录位置和时钟同步之后再开始读。一次性的用事件查看器的筛选,要反复做的排查用 Get-WinEvent -FilterHashtable

读的时候的要害是:4624 看登录类型,4625 看 Status/Sub Status,4740 看调用方计算机名,4688 看父进程和命令行。不要只凭事件 ID 下判断,要确认那是记录在哪里的什么信息,并把需要的日志比对起来。

相关文章

相关的咨询领域

小村软件有限责任公司承接 Windows 环境的审核策略与日志设计咨询、基于事件日志的“何时、谁、做了什么”的排查,以及业务应用在身份验证和审核方面引发的故障的原因分析。哪怕还处在“被要求看一下日志,但不知道该从哪里下手”的阶段也没关系。

参考链接

  1. Microsoft Learn, Advanced security auditing FAQ. 关于基本审核策略(本地策略下的 9 项设置)与高级审核策略的区别、在基本一侧启用一个类别等同于把对应的子类别全部启用、两者互不兼容且同时使用会让审核结果处于无法预期的状态因而不能混用、用组策略应用高级一侧时已有的审核设置会被清除、应当启用“审核:强制审核策略子类别设置”、以及要把事件量降到最低就要锁定重要的资源、活动和用户并加以收窄。  2 3 4

  2. Microsoft Learn, auditpol. 关于 auditpol 命令可以对系统审核策略执行显示(/get)、设置(/set)、备份为 CSV(/backup)、还原(/restore)和清除(/clear)。  2

  3. Microsoft Learn, System Audit Policy recommendations. 关于按工作站和服务器分列的 Windows 默认值、基线建议和强化建议的一览表,建议只是起点、各组织应结合自身的威胁和风险容忍度来评估和测试,登录子类别在 Windows 10 1809 以后成功与失败均默认启用,不只是服务器、工作站的监视同样重要,向特权组意外添加成员等应当单次即告警的事件示例,以及用基线对比来发现失败登录激增的思路。  2 3 4

  4. Microsoft Learn, Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings. 关于可以用 40 多个审核子类别做精细管理、把这项设置保持为启用是最佳实践且客户端、成员服务器和域控制器的有效默认值都是 Enabled,以及把特权使用子类别全部启用这类会产生大量事件的设置会让人更难在安全日志中找到其他条目并可能对性能造成很大影响的警告。  2 3 4

  5. Microsoft Learn, 4624(S): An account was successfully logged on. 关于 4624 在创建登录会话时记录在被访问的一侧计算机上、登录类型一览(2=Interactive、3=Network、4=Batch、5=Service、7=Unlock、8=NetworkCleartext、9=NewCredentials、10=RemoteInteractive、11=CachedInteractive)、提升的令牌(Elevated Token)标志、身份验证包(NTLM/Kerberos/Negotiate)与 NTLM 的 Package Name(NTLM V1/V2/LM),以及通过登录 ID 与 4672 等事件做关联。  2 3 4 5

  6. Microsoft Learn, 4625(F): An account failed to log on. 关于 4625 记录在发起登录尝试的那台计算机上(在用户终端上尝试就记录在终端上)、子类别是账户锁定和登录、Status/Sub Status 代码的含义(0xC0000064=用户名不正确、0xC000006A=密码错误、0xC000006D=用户名或身份验证信息不正确、0xC000006F=不在允许的时间段、0xC0000070=未被允许的工作站、0xC0000072=被禁用的账户、0xC000015B=登录类型未被允许、0xC0000193=已过期的账户、0xC0000234=锁定),以及连续出现的 0xC0000064 可能是账户枚举攻击的迹象。  2 3 4 5

  7. Microsoft Learn, 4776(S, F): The computer attempted to validate the credentials for an account. 关于 4776 在每次通过 NTLM 身份验证做凭据验证时记录、只记录在对该凭据具有权威的计算机上(域账户是域控制器,本地账户是本地计算机),以及成功和失败都会被记录。  2 3 4

  8. Microsoft Learn, 4771(F): Kerberos pre-authentication failed. 关于 4771 在每次 KDC 颁发 Kerberos TGT 失败(密码错误、已过期等)时记录,以及这个事件只在域控制器上生成。  2 3 4

  9. Microsoft Learn, Get-WinEvent (Microsoft.PowerShell.Diagnostics). 关于用 -ListLog 取得日志配置(LogMode、MaximumSizeInBytes、RecordCount)、用 -FilterHashtable 以 LogName、Id、StartTime 等哈希表指定做高效筛选、用 -Path 读取已保存的 .evtx 文件,以及用 -Oldest / -MaxEvents 按从旧到新和指定条数取得。  2 3 4

  10. Microsoft Learn, wevtutil. 关于用 set-log(sl)设置最大大小(/ms)和保留方式(/rt)、保留方式为 true 时日志满了会保留已有事件并丢弃新事件、为 false 时新事件会覆盖最旧的事件,用 export-log(epl)把事件日志导出到文件并用 /q 选项以 XPath 查询筛选,以及用 query-events(qe)执行查询。  2 3 4 5

  11. Microsoft Learn, 4688(S): A new process has been created. 关于 4688 在每次启动新进程时记录、其中包含创建者账户、新进程的可执行文件路径、创建方(父)进程名和令牌提升类型,以及 Process Command Line 字段默认为空、只有启用“在进程创建事件中包含命令行”这项组策略之后才会记录。  2 3

  12. Microsoft Learn, Command line process auditing. 关于命令行记录需要同时具备高级审核策略中的进程创建审核和“在进程创建事件中包含命令行”(管理模板 > 系统 > 审核进程创建,默认为未配置)这两项,启用后所有进程的命令行信息都会以明文记录到安全事件日志中、任何具有读取权限的用户都能读到可能含有密码等机密的参数这一注意事项,以及高级审核策略被基本设置覆盖时会记录事件 4719、可以用“强制”设置来防止。  2 3 4

  13. Microsoft Learn, Audit Account Lockout. 关于账户锁定子类别审核的是针对锁定中账户的登录失败、它生成的事件是 4625(F)、这个子类别不存在成功事件因而启用成功审核没有意义,以及在所有计算机类型上都建议审核失败。 

  14. Microsoft Learn, Audit Security Group Management. 关于这个子类别审核安全组的创建、修改、删除以及成员的添加和删除,成员添加/删除的事件 ID 按组的类型分开为本地组 4732/4733、全局组 4728/4729、通用组 4756/4757,存在 4728 等域组专用事件,以及这个子类别不存在失败事件、在所有计算机类型上都建议审核成功。  2

  15. Microsoft Learn, 4698(S): A scheduled task was created. 关于 4698 在每次创建计划任务时记录、子类别是其他对象访问事件、会记录包含任务名和执行命令在内的任务定义 XML 全文,以及恶意软件常用任务来实现重启后的持久化因而特别建议在重要机器上监视任务创建事件。  2

  16. Microsoft Learn, 4740(S): A user account was locked out. 关于 4740 在每次用户账户被锁定时记录、子类别是用户账户管理,以及 Caller Computer Name 字段记录着引发锁定的登录尝试来自哪台计算机。 

  17. Microsoft Learn, 4720(S): A user account was created. 关于 4720 在每次创建新的用户对象时记录于域控制器、成员服务器和工作站上,以及子类别是用户账户管理。 

  18. Microsoft Learn, 1102(S): The audit log was cleared. 关于事件 1102 在每次清除 Windows 安全审核日志时记录。 

  19. Microsoft Learn, Audit: Shut down system immediately if unable to log security audits. 关于这项设置启用时一旦无法记录安全审核,系统就会以 STOP 消息 C0000244 {Audit Failed} 停止、默认值是 Disabled、可能被转化为通过产生大量安全事件来刻意强制关机的 DoS,以及突然停机可能导致应用程序数据变得不可用。  2

  20. Microsoft Learn, Maximum tolerance for computer clock synchronization. 关于 Kerberos v5 为防范重放攻击而使用时间戳,因此对客户端与域控制器的时钟偏差设有最大容差(默认和建议均为 5 分钟),超过之后时间戳就不再被视为真实。 

共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。

与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。

本文与以下服务页面相关联,欢迎从最接近的入口查看。

常见问题

汇总了咨询这一主题时常见的问题。

什么审核策略都没有配置,为什么 Security 日志里已经记录了 4624 和 4625?
因为 Windows 有一部分审核子类别默认就是启用的。例如“登录”子类别,在 Windows 10 版本 1809 及以后,成功和失败都默认启用,所以什么都不配置,4624(成功)和 4625(失败)也会被记录。但保持默认时,凭据验证(4776)、进程创建(4688)等排查中经常需要的事件大多不会被记录。自己的环境里启用了哪些,可以用 auditpol /get /category:* 确认。在此基础上,把缺少的子类别在高级审核策略一侧显式启用,这是实务中的标准做法。
想查登录失败,可目标服务器的 Security 日志里找不到 4625,该看哪里?
首先请确认一条原则:4625 记录在“尝试登录的那台计算机”上。用户终端上的登录失败就看终端一侧,访问文件服务器失败就看文件服务器一侧。接着用 auditpol /get /category:* 确认“登录”子类别的失败审核是否已启用。如果是域账户,域控制器一侧的凭据验证(4776)和 Kerberos 预身份验证失败(4771)往往留有记录,在无法锁定终端时,从域控制器一侧查反而更快。如果还是找不到,请确认是不是日志覆盖导致过去的部分已经消失(查看日志的最大大小和最旧事件的时间)。
进程创建(4688)的命令行记录该不该启用?
它的排查价值非常高,但属于要先理解风险再启用的设置。启用后,所有进程的命令行参数都会以明文记录到 Security 日志里。只要有一个脚本或业务应用通过命令行传递密码或 API 密钥,这些机密就会变成所有能读 Security 日志的人都看得到的状态。微软自己也明确写出了这个注意事项。建议的顺序是:先检查自家的脚本有没有用命令行参数传递机密,把传递机密的地方改掉,然后再启用。
Security 日志的最大大小该设成多少?
正统做法是从“希望在手边留多少天”反推,不存在万能的数值。当前的设置和实际情况可以用 Get-WinEvent -ListLog Security 确认,最旧事件的时间与当前时间之差,就是“现在实际还留着的天数”。增加审核子类别会让事件量一起增加,所以每次改完设置都必须重新确认这个实际保留天数。事件响应中需要几周到几个月前的日志并不罕见,因此在被覆盖消失之前定期导出,或者用日志采集机制汇总到另一台机器上,会更稳妥。
账户锁定(4740)的原因该怎么查?
4740 事件的“调用方计算机名(Caller Computer Name)”字段是第一条线索,那里记录着触发锁定的失败登录来自哪台计算机。但要注意,失败记录本身(4625)不会留在来源一侧,而是留在接受登录尝试的一侧。如果源于网络登录,就按时间顺序追访问目标服务器上的 4625;如果是域账户,就追域控制器上的 4776/4771。在此基础上,对已确定为来源的终端,排查那些在密码更改后仍持有旧凭据的东西,也就是已保存的凭据、一直处于断开状态的远程桌面会话,以及仍用旧密码配置的服务和计划任务。如果锁定反复发生,请一并确认时钟同步有没有偏差。

作者简介

本文作者的个人简介页面。

Go Komura

小村软件有限公司 代表

以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。

返回博客列表