图解 NTLM 与 Kerberos ── 为什么认证会「回退」到 NTLM

· · NTLM, Kerberos, Windows, Active Directory, 安全, 认证, 信息系统

即便是被称为「我们是 Kerberos 环境」的企业内网,只要提取审核日志,就一定会发现 NTLM。而且出现的往往是本应支持 Kerberos 的应用

把两种协议「究竟想要证明什么」并排放在一起看,就能一目了然地明白为什么会这样。本文将用图解梳理 NTLM 与 Kerberos 的运作方式,在什么条件下会回退到 NTLM,以及为什么微软要淘汰 NTLM,并附上官方文档的依据加以整理。

关于自家环境的盘点步骤(审核策略的设置、事件的追踪方法、修复顺序),已整理在与本文成对的文章《NTLM 停用会导致业务应用停止运行吗》中。

1. 先说结论

  • NTLM 只证明「持有密码的哈希」这一件事。凭据由域名、用户名、密码的单向哈希构成,1 当前 Windows 使用的 NTLMv2 会用从该哈希导出的密钥,对「服务器的挑战 + 时间 + 客户端一侧的挑战 + 目标信息」计算 HMAC 后返回(2.2 节)。2
  • Kerberos 证明的是「谁、对哪个服务」。它以连接目标的服务名(SPN)为钥匙签发票据,因此发给不同目的地的票据无法使用。3
  • 决定性的差异有三个:是否具备相互认证、(在域账户的认证中)服务器是否需要询问域控制器、能否进行委派。这些都由微软明确写明(第 5 章)。4
  • 回退到 NTLM 的最大原因是「名称」。Kerberos 如果无法从连接目标的名称解析出 SPN 就无法开始。直接使用 IP 地址、SPN 未注册、工作组、无法到达 DC,是四大主因(第 6 章)。56
  • 「Kerberos 失败」与「回退到 NTLM」是两种不同的现象。前者是在选择了 Kerberos 之后发生错误(例如时间偏差)的状态,认证本身会中止。后者是无法开始 Kerberos、于是悄悄切换到 NTLM 的状态,业务仍然照常运转。排查故障时请从这两种可能性入手区分(6.5 节)。7
  • 中继攻击之所以成立,是因为 NTLM 没有把「在向谁认证」绑定住的机制。Pass-the-Hash 之所以成立,是因为认证所需要的正是哈希本身(第 7 章)。81
  • NTLMv1 已经被移除。对象是 Windows 11 版本 24H2 和 Windows Server 2025。NTLMv2 已弃用,但仍可使用(第 8 章)。9
  • 应用程序应该编写的是 Negotiate。Negotiate 会在 Kerberos 与 NTLM 之间做出选择,除非认证相关的某个系统无法使用 Kerberos,否则都会选择 Kerberos。1

2. NTLM 在做什么

NTLM(Windows Challenge/Response)正如其名,是一种挑战/响应方式的认证协议。概括微软的说明:凭据由交互式登录时获取的域名、用户名、密码的单向哈希构成,为了不把密码本身发送到线路上就完成认证,发起认证请求的一方要进行计算,以证明自己「能够访问安全保存的 NTLM 凭据」。1

这里重要的是,认证所使用的材料不是密码本身,而是密码的哈希。正是这一点,构成了后面要讲的 Pass-the-Hash 得以成立的条件。

2.1. 域账户认证时会出现三方

在已经登录的用户以域账户访问服务器上的资源的场景(非交互式认证)中,会涉及客户端、服务器、域控制器三方。此时的特点是,服务器自己不做认证计算,而是交给域控制器代为计算1

域控制器服务器客户端域控制器服务器客户端登录时计算密码的哈希,随后丢弃密码本身用密码哈希加密挑战从 SAM 中取出哈希进行相同的计算用户名(明文)18 字节随机数(挑战)2响应3用户名 / 挑战 / 响应4一致则认证成功5允许访问6

图1:NTLM 的非交互式认证(域账户情形)

微软作为概念展示的步骤如下(实际的计算如后文所述会因 NTLMv2 而有所不同,但出场角色和分工都和这张图一致)。1

  1. (仅交互式认证)用户输入域名、用户名、密码。客户端计算密码的加密哈希,丢弃真正的密码
  2. 客户端把用户名以明文发送给服务器。
  3. 服务器生成 8 字节的随机数(挑战、nonce)发给客户端。
  4. 客户端用用户密码的哈希加密这个挑战,把结果(响应)返回。
  5. 服务器把用户名、发给客户端的挑战、收到的响应这三项发送给域控制器。
  6. 域控制器根据用户名从 SAM 数据库中取出密码哈希,用它加密挑战。
  7. 将自己计算出的结果与客户端的响应比较,一致则认证成功。

2.2. 实际的计算 ── NTLMv2 更复杂一些

上面的 7 个步骤,是微软在概述页面中说明的基本形式。当前 Windows 实际使用的 NTLMv2,比「用密码哈希加密挑战」要复杂一层。在规范([MS-NLMP])中定义如下。2

  • 响应密钥为 NTOWFv2 = HMAC_MD5( MD4(UNICODE(密码)), 大写化的用户名 + 域名 )
  • 客户端会把响应版本、时间客户端一侧生成的 8 字节挑战目标信息(AV 对)连接起来,构成 temp
  • 响应的核心 NTProofStr = HMAC_MD5( 响应密钥, 服务器的挑战 + temp )

只抽取材料与处理流程,就是下面这一张图。

以此为密钥以此为密钥密码对 UNICODE 密码取 MD4= NT 哈希大写化的用户名+ 域名HMAC_MD5响应密钥 NTOWFv2响应版本 / 时间 /客户端侧 8 字节挑战 /目标信息-AV 对temp服务器的挑战HMAC_MD5NTProofStrNtChallengeResponse= NTProofStr + temp

图2:NTLMv2 响应的生成过程(密码 → NT 哈希 → 响应密钥 → HMAC)

也就是说实际上,不仅是服务器的挑战,还混入了客户端一侧的随机数、时间、目标信息,一并计算 HMAC。验证方也要重现相同的计算。如果账户在 Active Directory 中,就把挑战与响应这一组发送给域控制器进行验证;如果是服务器本地的账户,则由服务器用自己保存的 OWF 计算期望值2

对本文的讨论而言重要的是,即使变复杂了,以下两点也没有改变

  1. 密钥的材料,现在仍然是密码的哈希。NTOWFv2 的出发点是 MD4(UNICODE(密码)),也就是 NT 哈希本身。2 所以 Pass-the-Hash 能够成立(7.2 节)。
  2. 客户端并没有验证服务器是否是真的。NTLM 没有相互认证这一微软的说明,在 NTLMv2 中也没有改变。4

后续的说明都建立在这两点之上。

2.3. 本地账户认证只需两方即可完成

如果是本地账户,这张图右侧的部分就会消失。如果账户是域账户,资源服务器会查询该域的域控制器上的认证服务;但如果是本地账户,则会参照本地的账户数据库10 也就是说,工作组机器,或是用文件服务器本地账户连接共享的情形,域控制器不会出场,而是变成服务器查阅自己的 SAM、自行判定的两方往来。

这一差异,直接关系到 6.3 节要讨论的「因为是本地账户所以用不了 Kerberos」这一依赖的盘点。即使查看域控制器的审核日志,也不会出现这条路径上的 NTLM。

2.4. 这种设计带来的三个结论

看图1,可以直接读出后面会成为问题的性质。

  • 服务器没有向客户端证明任何东西。整个往来是单向的,服务器没有任何环节能证明「自己是真的」。
  • 服务器只有在自己持有哈希时才能判定。资源服务器每当需要新的访问令牌时,如果是域账户就要向域控制器的认证服务查询,如果是本地账户就要参照本地账户数据库。10域账户的认证之所以依赖域控制器,原因就在这里。
  • 响应「仅对该次挑战有效」,但不绑定目的地。由于挑战每次都不同,同一个响应无法重复使用。但由于没有能证明「这个响应是发给哪台服务器的」的要素,即使被转发到别的服务器也无法察觉。

3. 为什么服务器要询问域控制器

在域账户的认证中,持有密码哈希的只有域控制器一侧的账户数据库。资源服务器并不知道该用户的哈希,因此无法自行验证。所以每次认证都需要向域控制器查询(直通认证)101(如果是本地账户,服务器会查阅自己的 SAM 自行判定。以下关于依赖域控制器的讨论,针对的是域账户的情形。)

这在安全性和运维两方面都是有代价的。微软说明,在 Kerberos 之前的 NTLM 认证中,应用服务器每次认证客户端或服务时都需要连接域控制器,而在 Kerberos 中,可更新的会话票据取代了直通认证,服务器除非需要验证 PAC(特权属性证明),否则不需要访问域控制器4

也就是说,迁移到 Kerberos 既是安全性的问题,同时也是减少对域控制器的依赖的问题。

4. Kerberos 在做什么

Kerberos 的思路与 NTLM 明显不同。它采取的方式是不在每次认证时都重新确认身份,而是最初只做一次身份确认、领取一张「票据」,之后每次出示这张票据

KDC(密钥分发中心)运行在域控制器上,使用 Active Directory Domain Services 的数据库作为安全账户数据库。4

服务 (以 SPN 标识)KDC (域控制器)客户端服务 (以 SPN 标识)KDC (域控制器)客户端AS 交换 ── 身份确认与获取 TGT能用长期密钥解密即为本人TGS 交换 ── 获取服务票据根据 SPN 找到服务账户用其长期密钥加密票据AP 交换 ── 向服务出示票据能用自己的长期密钥解密= 是发给自己的票据KRB_AS_REQ(用户名 + 用长期密钥加密的时间)1KRB_AS_REPTGT(用 krbtgt 的密钥加密) + 会话密钥2KRB_TGS_REQ(TGT + 目标服务的 SPN + 认证器)3KRB_TGS_REP服务票据 + 会话密钥4KRB_AP_REQ(服务票据 + 认证器)5KRB_AP_REP(如果要求了相互认证)6

图3:Kerberos 的三次交换(AS / TGS / AP)

图例 ── AS = Authentication Service(认证服务)、TGS = Ticket Granting Service(票据授予服务)、AP = Application(应用程序)。消息名称中的 _REQ 表示请求,_REP 表示响应。例如 KRB_TGS_REQ 意为「向票据授予服务发出的请求」。

4.1. AS 交换 ── 一次性的身份确认

客户端会向 KDC 发送用户名、域名,以及用自己的长期密钥(由密码导出的密钥)加密的时间戳。这就是预身份验证(pre-authentication)。如果 KDC 能用该长期密钥解密,且时间戳合理,就判断「是本人」。3

KDC 会返回TGT(票据授予票据)。由于 TGT 是用 KDC 自身的长期密钥(krbtgt 账户的密钥)加密的,客户端无法读取其内容。同时,客户端与 KDC 之间使用的会话密钥,也会用客户端的长期密钥加密后一并传递。3

这里要记住的是,时间戳是认证的一部分。Kerberos 之所以对时间同步要求严格,原因就在这里,默认允许的时间差为 5 分钟。7 一旦超出这个范围,预身份验证就无法通过,Kerberos 认证本身会因错误而失败(Windows 的时间同步已整理在《Windows 时间同步(w32time)指南》中)。这种「Kerberos 失败」与「回退到 NTLM」是两回事。区别将在 6.4 节讨论。

4.2. TGS 交换 ── 申报「要连接哪个服务」

这里是与 NTLM 的决定性分歧点。客户端会把想要连接的服务的名称(SPN)告知 KDC,附上 TGT 与认证器,申请服务票据。3

KDC 会查找与该 SPN 对应的服务账户,用该账户的长期密钥加密服务票据后返回。3 因此,

  • 如果解析不出 SPN,就不会签发票据。如果服务账户没有注册 SPN,KDC 就无法确定对方是谁。即使把连接目标指定为 IP 地址,默认情况下也不会尝试 Kerberos(6.1 节)。
  • 票据是「专属该目的地」的。由于无法用别的服务的长期密钥解密,所以不能改变目的地重复使用。

4.3. AP 交换 ── 向服务出示票据与相互认证

客户端把服务票据与认证器出示给服务。服务用自己的长期密钥解密票据,取出其中的会话密钥与授权信息。能够解密这件事本身就证明了「这张票据是发给自己的」。3

如果客户端要求了相互认证,服务会用会话密钥加密收到的时间戳后返回。客户端通过验证这一点,可以确认对方确实是真正的服务3 这是 NTLM 中不存在的步骤。

5. 决定性的差异

观点 NTLM Kerberos
对方的验证 客户端无法验证服务器,服务器也无法验证另一台服务器,设计上假定服务器就是真的4 连接两端都能够验证对方确实是所声称的对方4
每次认证时对 DC 的查询 域账户时需要。资源服务器每次需要新的访问令牌都要查询 DC(本地账户则查阅自己的账户数据库)10 不需要(除非需要验证 PAC)。由可更新的会话票据取代4
目的地绑定 无。响应不能证明「是发给谁的」 有。服务票据用目标服务的长期密钥加密3
委派 只提供本地冒充所需的授权信息4 支持服务代表客户端连接到其他服务的委派4
时间同步 不依赖 依赖(默认允许差 5 分钟)7
名称解析 不问对方的名称(即使是 IP 地址也能成立) 前提是能解析出 SPN3
域外使用 工作组构成或本地登录时仍然需要10 以 Active Directory 为前提4

「委派」这一行,在实务中还会进一步细分。委派有无约束委派、约束委派(constrained delegation)基于资源的约束委派(RBCD)等种类,在从前端 Web 应用以用户的凭据连接后端 SQL Server 这类架构中,选哪一种会成为设计上的争论点。本文不深入展开,但请把它记作日后调查 Kerberos 委派时的检索关键词。

这张表下面两行,正是「回退到 NTLM」的原因所在。因为Kerberos 的强项(绑定目的地、验证对方),是建立在名称能够被正确解析这一前提之上的

6. 为什么会「回退」到 NTLM

即使应用程序没有直接指定 NTLM,也会使用到 NTLM。这是因为Negotiate会这样行事。按照微软的说明,Negotiate 会在 Kerberos 与 NTLM 之间做出选择,除非认证相关的某个系统无法使用 Kerberos,否则都会选择 Kerberos1

也就是说,「变成了 NTLM」在大多数情况下,是「Kerberos用不了」的另一种说法。

-工作组 / 本地账户--直接使用 IP 地址--SPN 未注册 / 用别名访问--据点 / VPN / 防火墙-用 Negotiate 开始认证是域账户吗?能从连接目标名称生成 SPN 吗?该 SPN是否已注册?能连接到KDC 吗?用 Kerberos 认证回退到 NTLM

图4:Negotiate 回退到 NTLM 的分支判断

先把四大主因按条件、原因、解决方法排成三列表格。详情将在 6.1 节之后讨论。

条件(出现这种情况就会回退) 为什么会回退 解决方法
连接目标以 IP 地址指定(6.1 节) 默认情况下,当主机名是 IP 地址时,Windows 不会尝试 Kerberos 认证11 把连接目标的设置改为 FQDN。只对确实无法改动的对象,把客户端的 TryIPSPN 设为 1,手动注册 IP 地址的 SPN(最后手段)11
SPN 未注册 / 用 DNS 别名访问(6.2 节) KDC 无法从 SPN 找到服务账户,也就无法用该账户的长期密钥加密票据3 用实际访问所使用的名称,注册所需服务类别的 SPN。如果使用 CNAME,也需要该名称的 SPN5
工作组机器 / 本地账户的访问(6.3 节) 在 Active Directory 之外,本来就没有 KDC10 加入域,或改为用域账户访问。阶段2 的本地 KDC 只能填补对应版本 Windows 之间的场景6
无法到达域控制器(6.4 节) 无法与 KDC 通信,也就无法获取票据6 检查路由与防火墙,确保 Kerberos 所需的通信能够到达 KDC

6.1. 使用 IP 地址连接

这是最常见的原因。微软明确指出,默认情况下,当主机名是 IP 地址时,Windows 不会对该主机尝试 Kerberos 认证,而是回退到 NTLM 等其他有效的认证协议11 审核指南方面也写明,如果事件 8001 的「目标服务器」既不是 NetBIOS 格式也不是 FQDN 格式,就不会使用 Kerberos。5

至于为什么会变成这样,官方也给出了理由:因为配置失误,或者厂商文档的原因,使用 IP 地址而非 DNS 名称的应用程序5「因为名称解析不稳定」而在过去改成 IP 地址的设置,就这样一直留到现在,这种情况在实务中也非常常见。

不过,这只是默认行为,并非绝对的限制。Windows 10 版本 1507 及 Windows Server 2016 以后,具备可以把 IP 地址用作 SPN 主机名的机制。把客户端一侧的注册表值 TryIPSPN 设为 1,再以 Setspn -s <服务类别>/<IP 地址> <账户> 的形式手动注册 IP 地址的 SPN,即使目的地是 IP 地址,Kerberos 也能够成立。要注册的是客户端实际请求的服务类别,像共享文件夹这类会映射到 HOST 的服务,注册 host/192.168.1.1 就够了;但如果是 Web,就需要 HTTP/192.168.1.1,如果是 SQL Server,则需要包含端口在内的 MSSQLSvc/192.168.1.1:1433 这样另一个 SPN。只注册 host/ 的话,如果与所请求的 SPN 不一致,Kerberos 依然无法成立。微软把这项功能定位为专门用来减少禁用 NTLM 带来的影响的手段。11

尽管如此,这并不是首选方案。微软自己也表示,由于 IP 地址是临时性的,租约到期与更新可能引发冲突或认证失败,通常不应把它用来代替主机名,基于 IP 地址注册 SPN 属于手动操作,只应在无法切换为基于 DNS 的主机名时才使用11 审核中发现的直接使用 IP 地址的情况,请首先考虑改成 FQDN。TryIPSPN 只是对那些无论如何都做不到这一点的对象的最后手段。

6.2. SPN 未注册

这是第二常见的原因。微软列举了明明支持 Kerberos 却使用了 NTLM 的应用类型,其中之一就是SPN 配置不正确的应用程序5

正如图3 的 TGS 交换中所看到的,KDC 是根据 SPN 找到服务账户,再用它加密票据的。如果没有 SPN,KDC 就无法确定「该服务的密钥」。用 DNS 别名(CNAME)或自定义主机名访问时,如果没有注册该名称对应的 SPN,也会发生同样的情况。明明应用本身工作正常,却只是名称没有登记在册。

6.3. 本来就在 Active Directory 之外

工作组构成的终端,或用本地账户访问共享,本来就不在 Kerberos 的势力范围内。微软也说明,作为工作组成员配置的系统的 Windows 认证,以及在非域控制器上进行的本地登录认证,都要使用、也必须使用 NTLM。10

这正是无法「一刀切地禁止」NTLM 的原因所在。阶段2 计划推出的本地 KDC,正是为了填补这个空缺而设计的功能。6 不过请注意,能填补的仅限于对应版本 Windows 之间的场景。如果对方是旧版 Windows,或是 NAS、复合机等其他厂商的设备,本地账户认证不会因为本地 KDC 的到来而自动变成 Kerberos。这方面的划分已在实务篇的第5章、第6章中讨论。

6.4. 无法到达 KDC

在据点或经由 VPN 无法到达域控制器、Kerberos 所需的端口被防火墙阻挡等路由方面的问题,也会引发回退。6 由于无法与 KDC 通信,也就无从获取票据,Negotiate 只能选择剩下的选项 NTLM。

6.5. 不要混淆「Kerberos 失败」与「回退到 NTLM」

最后,把容易混淆但实为两回事的问题区分清楚。到目前为止的 6.1~6.4,都是「无法开始 Kerberos」的情形。因为无法开始,Negotiate 才会选择 NTLM。

另一方面,Kerberos 被选中,但在此之后失败,则是另外一回事。典型例子就是时间偏差。如果能解析出 SPN,也能连接到 KDC,Negotiate 会首先选择 Kerberos。之后如果时间超出容许差(默认 5 分钟),预身份验证就无法通过,会作为 Kerberos 的错误而失败7 已选定的协议失败了,并不意味着 Negotiate 会自动切换到 NTLM 重试(除非应用程序自己明确地用别的方式重试)。

实务上的含义很简单。时间偏差引起的故障,即使去搜索事件 8001 也找不到。症状也不同。

症状 应怀疑的原因 查看位置
能正常工作,但认证变成了 NTLM 6.1~6.4(无法开始 Kerberos) NTLM/Operational 中的事件 8001
认证本身因错误而失败 时间偏差、SPN 重复注册、加密类型不一致等 系统日志中的 Kerberos 事件、klistw32tm /query /status

请先分清楚「是回退到了 NTLM,还是 Kerberos 本身出了故障」,再着手排查。

7. 从攻击角度看差异 ── 中继攻击与 Pass-the-Hash

微软在策略设置文档中明确写明,NTLM 及 NTLMv2 认证容易受到包括 SMB 中继、中间人攻击、暴力破解在内的各种恶意攻击的影响8 为什么会这样,看图1 就能说明。

7.1. 中继攻击 ── 不绑定目的地带来的后果

真正的服务器攻击者的服务器受害者的电脑真正的服务器攻击者的服务器受害者的电脑把受害者引导至攻击者的服务器无法辨别是否来自真正的服务器未要求签名也未要求 channel binding 的情况下开始认证(用户名)1用同一用户开始认证2挑战3原样转发该挑战4响应(用哈希导出的密钥计算)5原样转发该响应6认证成功 → 以受害者身份建立连接7

图5:NTLM 中继攻击的成立条件(对方未启用签名与通道绑定的情形)

攻击者不需要知道密码,也不需要知道哈希。只需要把挑战与响应从一侧转发到另一侧即可。之所以能够成立,是因为客户端一侧没有手段确认这个响应是否真的传到了自己意图连接的对象那里。

不过,中继并不是对任何对象都能成立的。中继来的往来能否变成可用的会话,取决于连接目标的防御措施。

  • 对要求 SMB 签名的对象不成立。微软明确说明,SMB 所有消息附带的签名不仅包含整条消息的哈希,还包含发送方与接收方的身份,因此能够防止中继攻击12 另外,域控制器默认会要求连接方进行 SMB 签名。12
  • 对强制要求 Extended Protection for Authentication(通道绑定)的服务也不成立。由于它把认证绑定在了下层的 TLS 通道上,中继到别的通道的认证就无法通过。

也就是说,图5 描绘的,是在既没有签名也没有通道绑定、且接受 NTLM 的对象这一条件下才能成立的路径。反过来说,这也意味着在实务中有立即可行的对策。在盘点 NTLM 的同时,一并确认 SMB 签名的要求情况是有价值的。

在 Kerberos 中,本来就无法进行同样形式的中继。因为服务票据是用目标服务的长期密钥加密的,即使拿到别的服务那里也无法解密。3 而且客户端可以通过相互认证确认对方是否是真的。4

微软准备 SMB 客户端侧 NTLM 拦截的理由,正是这一点。据说其目的正是防止把 NTLM 请求发送给恶意服务器这种手法13 另外,在 SMB 签名相关的建议中,微软还提到应使用 Kerberos 而非 NTLMv2,以确保会话密钥从一开始就足够强,以及不要用 IP 地址或 CNAME 记录连接共享(因为这样会使用 NTLM 而非 Kerberos)12 这与 6.1 节、6.2 节讲的是同一件事。

7.2. Pass-the-Hash ── 哈希与密码等价

单向哈希导出响应密钥并计算 HMAC密码密码的哈希响应认证成功从终端窃取哈希无需明文密码

图6:认证所需的是哈希,而不是明文密码

NTLM 的凭据是密码的单向哈希1 在 NTLMv2 中,会以 MD4(UNICODE(密码)) 为密钥导出响应密钥,再用该密钥计算 HMAC 生成响应。2 即使计算的形式发生了变化,出发点是哈希这一点也没有改变。也就是说,认证所需要的是哈希,而不是明文密码。

这一结论在运维上有着相当重的分量。即使把密码设得更长更复杂,也堵不住哈希被窃取的路径。微软也把 Pass-the-Hash 与暴力破解、破解并列,作为 SMB 的 NTLM 拦截所要对抗的攻击之一。13

Kerberos 中虽然也存在长期密钥,但日常认证中传递的是有有效期的票据与会话密钥。3 一旦被窃取,波及的范围完全不同。

8. NTLMv1、NTLMv2 与「移除」

NTLM 并不是单一的协议,而是包含 LAN Manager 版本1、2 与 NTLM 版本1、2 在内的一组认证协议10

目前的处理状态划分如下。

版本 状态 含义
LANMAN / NTLMv1 / NTLMv2 全部已弃用(2024年6月)9 不再是积极开发的对象。但在下一版 Windows Server 及下一个年度发布的 Windows 中仍可工作
NTLMv1 已移除(Windows 11 24H2 / Windows Server 2025)9 在这些版本中无法使用

也就是说,「因为是 NTLMv2 所以可以暂时放着不管」是不成立的。不过优先级是明确的,只能使用 NTLMv1 的设备或主机最优先处理。审核中记录到 NTLM V1 的主机,如果直接升级到新版 Windows,认证会失败。版本的辨别方法(查看安全日志中的「包名称(仅限 NTLM)」)已在实务篇文章的4.4节中讨论。5

另外,限制 NTLM 的审核与拦截策略,对 NTLMv1 和 NTLMv2 两者具有相同的效果。5 施加限制时,版本不同并不会导致行为不同。

9. 今后会怎样

微软展示的方向有三个。

第一是在应用程序一侧使用 Negotiate。把 NTLM 的调用替换为 Negotiate 的调用,这正是弃用公告本身所包含的指示。9 官方也明确说明,应用程序不应直接访问 NTLM 安全包。1

第二是减少需要用到 NTLM 的场景本身。阶段2(2026年下半年)计划推出的 IAKerb 与本地 KDC,正属于此类。6 这是通过协议层面来填补 6.3 节所讲的「因为是本地账户所以用不了 Kerberos」「因为到不了域控制器所以用不了 Kerberos」这两个漏洞的尝试。不过能填补的范围是有限的。IAKerb 解决的是到域控制器的可达性问题,而不是对方是否支持的问题。本地 KDC 也是一样,只有在对应版本的 Windows 之间才有效。如果对方是其他厂商的 NAS 或复合机,即使等到阶段2,情况也不会改变,需要自行选择设备更新、加入域、切换到其他协议、例外管理中的某一种方案。

第三是改变默认设置。在阶段3,计划在下一个主要版本中默认禁用网络 NTLM 认证。6 不过官方也表示,可以通过策略重新启用。

这个顺序是有意义的。正因为是「先消除使用的理由,再改变默认设置」这样的顺序,把现在自家公司残留的 NTLM 依赖,划分为可以期待在阶段2 得到解决的部分(对应版本 Windows 之间的本地账户认证、DC 可达性),与需要自己动手解决的部分(直接使用 IP 地址、SPN 未注册,以及对方是旧版 Windows 或其他厂商设备的本地账户认证),就能省去无谓的工程。如果把最后这一类归入「等待阶段2」,一旦默认禁用到来,就会以故障的形式表面化。具体的划分步骤已整理在实务篇中。

10. 总结

  • NTLM 是一种通过挑战/响应来证明「持有密码的哈希」的协议。判定工作由域控制器代为完成(域账户),或由服务器自己查阅自己的 SAM 完成(本地账户)。110
  • Kerberos 证明的是「谁、对哪个服务」。服务票据用目标服务的长期密钥加密,因此不能改变目的地重复使用。3
  • 决定性的差异在于是否具备相互认证、每次认证是否需要询问 DC、能否委派。4
  • 回退到 NTLM,几乎都发生在「无法开始」Kerberos 的时候。直接使用 IP 地址、SPN 未注册、位于 Active Directory 之外、无法到达 KDC,是四大主因。5611
  • 另一方面,像时间偏差这样在 Kerberos 被选中之后才失败的问题,表现为认证错误,而不是回退到 NTLM。即使搜索事件 8001 也找不到。7
  • 中继攻击之所以成立,是因为 NTLM 的响应不绑定目的地。Pass-the-Hash 之所以成立,是因为认证所需要的正是哈希本身。8113
  • NTLMv1 已经被移除(Windows 11 24H2 / Windows Server 2025),包括 NTLMv2 在内的所有版本均已弃用。9
  • 应用程序应该编写的是 Negotiate。在此基础上,把连接目标的名称统一为 FQDN、注册 SPN,就是让 Kerberos 得以成立的实务核心。15

相关文章

相关咨询领域

合同会社小村软件承接因认证方式调整而产生的 Windows 业务应用改造,以及 Kerberos/NTLM 相关认证故障的原因排查。

参考链接

  1. Microsoft Learn, Microsoft NTLM。关于 NTLM 是一种被称为 Windows Challenge/Response 的认证协议,是一个为应用程序提供认证、完整性与机密性的安全包;NTLM 凭据由交互式登录时获取的域名、用户名、密码的单向哈希构成;通过加密的挑战/响应,在不把密码发送到线路上的情况下完成认证,发起认证请求的一方要进行计算,证明自己能够访问安全保存的 NTLM 凭据;非交互式认证由客户端、服务器、域控制器三方完成,其具体步骤(客户端计算密码的哈希并丢弃明文密码、把用户名以明文发送、服务器生成8字节随机数即挑战并发送、客户端用哈希加密挑战返回响应、服务器把用户名/挑战/响应发给域控制器、域控制器用 SAM 数据库中的哈希进行相同计算并核对);以及应用程序不应直接访问 NTLM 安全包,而应使用 Negotiate 安全包,Negotiate 会在 Kerberos 与 NTLM 之间做出选择,除非认证相关的某个系统无法使用 Kerberos,否则都会选择 Kerberos。  2 3 4 5 6 7 8 9 10 11 12 13

  2. Microsoft Learn, [MS-NLMP]: NTLM v2 Authentication。关于 NTLM 的认证版本不在协议中协商,需要在认证之前由客户端与服务器双方预先配置;NTLM v2 的响应密钥定义为 NTOWFv2(Passwd, User, UserDom) = HMAC_MD5( MD4(UNICODE(Passwd)), UNICODE(大写化的 User + UserDom) );客户端生成 8 字节挑战;temp 是响应版本、8 字节 GMT 时间、客户端挑战、ServerName(AUTHENTICATE_MESSAGE 中 NTLMv2_CLIENT_CHALLENGE 所含的 AvPairs 结构体)等的连接;NTProofStr = HMAC_MD5( ResponseKeyNT, 服务器的挑战 + temp ) 的计算方式,以及 NtChallengeResponseNTProofStrtemp 的连接;SessionBaseKey = HMAC_MD5(ResponseKeyNT, NTProofStr);以及验证方面,若要认证的用户账户托管在 Active Directory 中,会把挑战/响应这一组发送给域控制器进行验证,DC 用 NTOWF v2 / LMOWF v2 计算期望值并核对,DC 返回 STATUS_NTLM_BLOCKED 时服务器返回 STATUS_NOT_SUPPORTED;若账户托管在服务器本地,则由服务器根据本地保存的 OWF 计算期望值并核对。  2 3 4 5

  3. Microsoft Learn, How the Kerberos Version 5 Authentication Protocol Works。关于 AS 交换中,客户端把用户主体名称、账户的域名,以及用用户的长期密钥(由密码导出的密钥)加密的预身份验证数据(含时间戳)发送给 KDC,KDC 用长期密钥解密并验证后,返回用 KDC 自身的长期密钥(krbtgt 账户的密钥)加密的 TGT,以及用用户的长期密钥加密的会话密钥;TGT 包含会话密钥、授权数据(用户 SID 与组 SID)、有效期与标志。关于 TGS 交换中,客户端把目标服务器名(SPN)、TGT,以及用会话密钥加密的认证器(含时间戳与校验和)发送给 KDC,KDC 用自身的长期密钥解密 TGT 取出会话密钥,验证认证器的时间戳在策略规定的范围内后,返回用目标服务的长期密钥加密的服务票据,以及用 TGS 会话密钥加密的新会话密钥。关于客户端/服务器交换(AP 交换)中,客户端把服务票据与认证器出示给服务,服务用自己的长期密钥解密票据取出会话密钥与授权数据,如果要求了相互认证,就用会话密钥加密客户端的时间戳返回,以此证明服务自身的身份。以及长期密钥与会话密钥的区别(长期密钥由密码或服务账户导出,跨会话持续存在;会话密钥是短命的,随票据到期而销毁)。  2 3 4 5 6 7 8 9 10 11 12 13

  4. Microsoft Learn, Kerberos authentication overview in Windows Server。关于 Windows Server 实现了 Kerberos version 5 认证协议,以及用于公钥认证、授权数据传递、委派的扩展;Kerberos 客户端以 SSP(安全支持提供程序)的形式实现,通过 SSPI 访问;KDC 与域控制器上的其他安全服务集成,使用 Active Directory Domain Services 的数据库作为安全账户数据库;Kerberos 支持服务的委派(前端服务以客户端身份连接到其他计算机上的后端服务的机制),而 NTLM 与 Kerberos 提供的都是服务在本地冒充客户端所需的授权信息;在 Kerberos 之前的 NTLM 认证中,应用服务器每次认证客户端或服务时都需要连接域控制器,而在 Kerberos 中,可更新的会话票据取代了直通认证,除非需要验证 PAC,否则服务器不需要访问域控制器;以及关于相互认证,Kerberos 中网络连接的两端都能够验证对方确实是所声称的对方,而 NTLM 既不允许客户端验证服务器的身份,也不允许一台服务器验证另一台服务器的身份,它是为可以假定服务器是真的这种网络环境设计的,Kerberos 不做这样的假定。  2 3 4 5 6 7 8 9 10 11 12

  5. Microsoft Learn, Viewing events for assessing NTLM usage。关于可以判断事件日志中的 NTLM 审核信息属于 NTLM v1 还是 v2,方法是在安全日志的登录事件中检索「认证包」,查看「详细认证信息」中的「包名称(仅限 NTLM)」;限制 NTLM 的审核与拦截策略对 NTLM 的两个版本具有相同的效果;理论上明明支持 Kerberos 却使用了 NTLM 的应用的四种类型(可以选择各种安全配置或提供程序的应用、SPN 配置不正确的应用、因配置失误或厂商文档而使用 IP 地址而非 DNS 名称的应用、在旧版代码库中含有 NTLM 专用部分的应用);从域控制器的事件 8004,到成员服务器的事件 8003,再到客户端事件 8001 的排查步骤及各事件的项目;事件 8001 的「目标服务器」如果既不是 NetBIOS 格式也不是 FQDN 格式,就不会使用 Kerberos;以及经由 SMB 的通信中 PID 始终为 4(SYSTEM),因此需要用 Process Monitor 来确定调用方进程。  2 3 4 5 6 7 8 9

  6. Microsoft Japan Windows Technology Support Blog, NTLM の廃止に向けた対応について。关于 NTLM 的淘汰将分三个阶段推进(阶段1=可视化利用状况并审核,阶段2=计划于2026年下半年推出的针对 NTLM 依赖场景的应对功能,阶段3=在下一个主要版本中默认禁用网络 NTLM 认证);阶段2 计划提供 IAKERB(支持代理功能的协议)与本地 KDC(支持本地认证的功能);应用程序应使用 Negotiate;以及导致使用 NTLM 的典型原因包括以 IP 地址方式访问服务器、Kerberos 所需端口被防火墙限制、SPN 未注册、对有信任关系的对象进行认证、在工作组环境中认证。  2 3 4 5 6 7 8

  7. Microsoft Learn, Registry entries about Kerberos protocol and Key Distribution Center (KDC) configuration。关于 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters 下各设置项,尤其是 SkewTime 的默认值为 5 分钟,这是接受 Kerberos 认证的服务器或 KDC 与客户端计算机之间所允许的最大时间差,该值也用于判断票据是否可以重复使用;以及 SPN 缓存的有效期(SpnCacheTimeout,默认 15 分钟)用于客户端与成员服务器上「未找到 SPN」这一否定缓存条目的清理,域控制器上不启用 SPN 缓存。  2 3 4 5

  8. Microsoft Learn, Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers。关于设置值有「全部允许」「全部审核」「全部拒绝」「未定义」四种;建议的操作步骤是先选择「全部审核」,查看运行日志后再制定例外列表;审核与拦截事件记录在「应用程序和服务日志\Microsoft\Windows\NTLM」中;以及 NTLM 及 NTLMv2 认证容易受到包括 SMB 中继、中间人攻击、暴力破解在内的各种恶意攻击的影响,减少并消除环境中的 NTLM 认证,可以让 Windows 转而使用 Kerberos version 5 这类更安全的协议,或智能卡等其他认证机制;只有当服务器或域控制器处理 NTLM 请求时,这些攻击才可能成立。  2 3

  9. Microsoft Learn, Deprecated features in the Windows client。关于包括 LANMAN、NTLMv1、NTLMv2 在内的所有版本的 NTLM 都不再是积极开发的对象,均已弃用(公告于 2024年6月);NTLM 在下一版 Windows Server 及下一个年度发布的 Windows 中仍会继续可用;应把 NTLM 的调用替换为 Negotiate 的调用,Negotiate 会尝试用 Kerberos 认证,只有在必要时才回退到 NTLM;以及作为 2024年11月的更新,NTLMv1 已从 Windows 11 版本 24H2 及 Windows Server 2025 中移除。同时说明该列表中的功能不再被积极开发,未来的更新中可能被移除,即弃用(deprecated)与移除(removed)之间的区别。  2 3 4 5

  10. Microsoft Learn, NTLM overview in Windows Server。关于 NTLM 认证是包含在 Msv1_0.dll 中的一组认证协议,包括 LAN Manager 版本1、2 与 NTLM 版本1、2;挑战/响应机制是一种向服务器或域控制器证明账户密码持有权的方式;资源服务器每当需要新的访问令牌时,如果是域账户就要查询该账户所在域的域控制器上的认证服务,如果是本地账户就要参照本地账户数据库;作为工作组成员配置的系统的 Windows 认证,以及在非域控制器上进行的本地登录认证,仍然要使用、也必须使用 NTLM;在 Active Directory 环境中 Kerberos version 5 是推荐的认证方式,但微软及第三方应用程序有时会使用 NTLM;以及要减少 NTLM 的使用,既需要掌握已部署应用程序的需求,也需要配置使用其他协议。  2 3 4 5 6 7 8 9

  11. Microsoft Learn, Configuring Kerberos for IP Address。关于 Windows 10 版本 1507 及 Windows Server 2016 以后,Kerberos 客户端可以支持 SPN 中的 IPv4/IPv6 主机名;默认情况下,当主机名是 IP 地址时,Windows 不会对该主机尝试 Kerberos 认证,而是回退到 NTLM 等其他有效的认证协议;应用程序直接写死 IP 地址会导致回退到 NTLM,在逐步禁用 NTLM 的环境中可能引发兼容性问题;为减少这种影响而引入了可以把 IP 地址用作 SPN 主机名的功能,通过把客户端一侧的注册表值 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters 下的 TryIPSPN(REG_DWORD,默认不存在)设为 1 来启用,需要在每个需要通过 IP 地址访问受 Kerberos 保护的资源的客户端上进行设置;SPN 的格式为 service/hostname[:port];以及由于 IP 地址是临时性的,租约到期与更新可能引发冲突或认证失败,通常不应把它用来代替主机名,基于 IP 地址注册 SPN 属于手动操作,只应在无法切换为基于 DNS 的主机名时才使用;注册时使用 Setspn -s <service>/<ip.address> <domain-user-account>,由于一个 SPN 在 Active Directory 中一次只能注册给一个账户,使用 DHCP 时建议把 IP 地址设为静态保留。  2 3 4 5 6

  12. Microsoft Learn, Overview of Server Message Block signing in Windows。关于 SMB 签名会为所有 SMB 消息附加基于会话密钥与 AES 生成的签名,签名中除了包含整条消息的哈希,还包含原始发送方与预期接收方的身份;一旦在传输过程中被篡改,就会与签名不一致,从而保护免受中继攻击与冒充攻击;SMB 2/3 签名与加密的安全性依赖于会话密钥,签名确认发送方与接收方的身份,从而防止中继攻击;会话密钥由密码导出,因此建议使用长且复杂的非字典密码;为确保会话密钥从一开始就足够强,建议使用 Kerberos 而非 NTLMv2不要用 IP 地址或 CNAME 记录连接共享(因为这样会使用 NTLM 而非 Kerberos);域控制器默认会对 SYSVOL 与 NETLOGON 的连接方要求 SMB 签名,客户端一侧的 UNC 强化还会对这两个共享进一步要求 Kerberos;签名作为预认证完整性的一部分,也用于防止降级攻击;策略位置与注册表值(RequireSecuritySignature);以及 Windows 11 版本 24H2 以后可以使用审核功能检测不支持签名/加密的对象(如 Set-SmbClientConfiguration -AuditServerDoesNotSupportSigning 等,SMBClient/Audit 的 31998、31999,SMBServer/Audit 的 3021、3022)。  2 3

  13. Microsoft Learn, Block NTLM connections on SMB in Windows Server 2025。关于 SMB 客户端可以对远程发送连接拦截 NTLM 认证,从而防止把 NTLM 请求发送给恶意服务器这种手法,并能对抗暴力破解、破解、Pass-the-Hash 攻击;由于 Kerberos 通过票据机制能够验证服务器的身份,因此比 NTLM 更安全,把组织的认证协议切换到 Kerberos 需要用到 NTLM 拦截;另一方面,即使不完全禁用 NTLM,也可以只启用这一层保护;前提条件是 Windows Server 2025 以后或 Windows 11 版本 24H2 以后的 SMB 客户端,以及可以使用 Kerberos 的 SMB 服务器;以及这是 SMB 客户端一侧的功能。  2 3

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

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

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

常见问题

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

NTLM 与 Kerberos,归根结底有什么区别?
最大的区别在于「能否确认对方的身份」。微软明确指出,在 NTLM 中,客户端无法验证服务器的身份,一台服务器也无法验证另一台服务器的身份。NTLM 是为可以假定「服务器就是真的」这一前提的环境设计的,而 Kerberos 不做这样的假定。第二个区别是服务器是否需要向域控制器查询。在 NTLM 中,对于域账户的认证,应用服务器每次认证客户端时都要连接域控制器(如果是服务器本地的账户,则由服务器查阅自己的账户数据库自行判定,域控制器不会出场)。在 Kerberos 中,可更新的会话票据取代了这种直通认证,因此服务器除非需要验证 PAC,否则不必访问域控制器。第三点是 Kerberos 支持服务的委派(代表客户端连接到其他服务的机制)。
明明应该支持 Kerberos,为什么还是变成了 NTLM?
Kerberos 是以「连接目标的名称」为钥匙来签发票据的机制,因此名称解析不出来就无法成立。客户端会把要连接的服务的 SPN(服务主体名称)提交给 KDC 来申请服务票据,但默认情况下,当主机名是 IP 地址时 Windows 不会尝试 Kerberos 认证,而且如果服务账户没有注册 SPN,KDC 也无法签发票据。微软的审核指南也写明,如果事件 8001 的「目标服务器」既不是 NetBIOS 名称也不是 FQDN 形式,就不会使用 Kerberos(关于 IP 地址,可以在客户端设置 TryIPSPN 并手动注册 IP 地址的 SPN,例外性地让 Kerberos 成立,但这被视为在无法改为 DNS 名称时的最后手段)。此外,工作组机器或本地账户的认证(本来就在 Active Directory 之外)、无法到达域控制器的据点、对没有信任关系的对方进行认证,也都是 Kerberos 无法成立的条件。Negotiate 会在无法使用 Kerberos 时选择 NTLM,因此在这些情况下就会「回退」。
什么是 NTLM 中继攻击?为什么会成立?
这是一种攻击者把受害者引诱到自己的服务器,再把发到那里的 NTLM 认证往来原样中继给真正的服务器、从而冒充受害者的攻击。之所以成立,是因为 NTLM 的挑战/响应机制没有把「在向谁认证」绑定住的手段。客户端只是根据服务器发出的挑战计算并返回响应,却没有办法在客户端一侧确认这个响应究竟是发给真正的服务器,还是被攻击者中继过来的。微软自己也在策略设置文档中明确写明,NTLM 及 NTLMv2 认证容易受到包括 SMB 中继、中间人攻击、暴力破解在内的各种恶意攻击的影响。不过,中继并非对任何对象都能成立。如果连接目标要求 SMB 签名,由于签名要确认发送方与接收方的身份,中继就无法成立;对于强制要求 Extended Protection for Authentication(通道绑定)的服务也是同样的道理。反过来说,未启用签名也未启用通道绑定、且接受 NTLM 的对象就会成为攻击目标。在 Kerberos 中,由于服务票据是用该服务的长期密钥加密的,即使把发给别的服务的票据拿到另一个服务那里也无法解密。
Pass-the-Hash 是不是说即使不破解密码也能冒充身份?
正是如此。NTLM 的凭据由域名、用户名、密码的单向哈希构成。当前 Windows 使用的 NTLMv2 中,响应密钥是以密码的 MD4 哈希(NT 哈希)为密钥导出的 HMAC,再用这个密钥对服务器的挑战、时间、客户端一侧的挑战、目标信息汇总后的内容计算 HMAC。虽然并非单纯地对挑战加密,但出发点仍然是密码的哈希这一点没有变。也就是说,认证所需要的是哈希本身,而不是明文密码。因此,只要攻击者能从终端的内存等处取出哈希,即使不破解密码,也能以该用户的身份完成认证。把密码设得更长更复杂,也堵不住这条路径。微软准备 SMB 客户端侧的 NTLM 拦截功能,理由之一正是为了对抗 Pass-the-Hash 攻击。
只要用的是 NTLMv2,暂时就安全了吗?
NTLMv2 虽然比 NTLMv1 更强,但也没有被排除在弃用对象之外。微软的已弃用功能列表指出,包括 LANMAN、NTLMv1、NTLMv2 在内的所有版本的 NTLM 都不再是积极开发的对象,均已弃用。限制策略的行为也一样,官方说明审核和拦截策略对这两个版本具有相同的效果。另一方面,NTLMv1 的处理不同,它已经不只是弃用,而是进入了移除阶段,从 Windows 11 版本 24H2 和 Windows Server 2025 开始已被移除。因此正确的理解不是「因为是 NTLMv2 所以可以暂时放着不管」,而是「NTLMv1 现在就是期限,NTLMv2 则要一边推进盘点,一边朝着默认禁用的方向准备」。

作者简介

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

Go Komura

小村软件有限公司 代表

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

返回博客列表