很早就听说过黄金票据需要 krbtgt 的 NTLM-HASH 和白银票据需要服务器的 NTLM-HASH 才能伪造,但是一直不知道为什么。学习内网渗透怎么能够对 kerberos 通信认证协议不了解呢?
先来介绍一下 NTLM 和一些基础概念吧!
NTLM
NTLM 是 NT LAN Manager 的缩写,是基于挑战 / 应答的身份验证协议。Windows 可用它验证本地账户,也可通过域控验证域账户;在网络访问中,目标名称、协议支持和策略会影响是否使用 NTLM。
基本流程
- 客户端准备当前账户的凭据,发送 Type 1(NEGOTIATE)。
- 服务器生成 8 字节(64 位)随机 Challenge,通过 Type 2 返回。
- 客户端结合 NTLM Hash、Challenge 等输入计算 Response,通过 Type 3 提交响应、用户名和域等信息。NTLMv1 与 NTLMv2 的计算方式不同,下面分别说明。
- 域账户通常由成员服务器通过 Netlogon 将账户信息、Challenge 和 Response 等验证材料提交给域控。
- 域控使用 AD 中保存的账户密钥材料计算预期响应,比较后返回验证结果及相应会话密钥材料。本地账户则由目标本机验证。
- 服务端完成所需的 MIC、绑定等检查,再按账户权限建立会话。
三条消息及响应计算见微软 MS-NLMP。
Hash
LM Hash
LM Hash(LAN Manager Hash)是早期 Windows 保存口令摘要的一种形式,计算中使用 DES。它会将密码转为大写,并把两段分别计算,安全性较弱。Vista / Server 2008 起默认不再保存 LM Hash;旧账户是否仍有残留,还取决于策略与后续密码更新。
LM Hash的计算方式为:
- 将密码转为大写,并按 OEM 字符集编码;LM 形式最多支持 14 字节,过长或无法表示的密码没有可用的 LM 摘要。
- 不足 14 字节时用
0x00补齐,再分成两段,每段 7 字节。 - 每段扩展成一个带校验位的 DES 密钥,分别加密固定字符串
KGS!@#$%。 - 将两段 8 字节密文拼接,得到 16 字节 LM Hash。
计算定义见 MS-NLMP 的 LMOWFv1。
NTLM Hash
NT Hash(通常也叫 NTLM Hash)保留密码的大小写,使用 MD4 计算口令摘要。
Windows 2000 / XP / Server 2003 可以同时保存 NT Hash 和用于兼容旧系统的 LM Hash。密码长度与策略会影响 LM Hash 是否保存;NT Hash 的使用适用于这些系统中的长、短密码。参见微软口令存储说明。
NTLM Hash 的计算方法为:
- 将密码编码为 UTF-16LE 字节序列
- 基于 MD4 计算哈希值
NTLM Hash 与 Net-NTLM Hash 的区别
| NTLM Hash | Net-NTLM Hash | |
|---|---|---|
| 是什么 | 密码的哈希值,存储在 SAM/ntds.dit 中 | 认证过程中网络传输的 Challenge-Response |
| 计算方式 | MD4(UTF-16LE(Password)) |
NTLMv2:先由 NT Hash、用户名和域名派生 ResponseKeyNT,再计算 NTProofStr 并拼接 Blob;公式见下文 |
| 能否直接登录 | 允许 NTLM 且满足账户与资源权限时,可用于 Pass The Hash | 捕获的数据可离线破解;在线中继需要目标的本次 Challenge 与保护条件匹配 |
| 存储位置 | 本地 SAM 或 ntds.dit | 认证交换中携带,也可能被抓包或捕获工具保存 |
| 攻击方式 | PTH;在允许 RC4 的环境中也可作为 Kerberos RC4 密钥 | 离线破解(如 hashcat);在线转交目标的挑战与本次响应 |
密码不变时,NT Hash 也保持不变。网络上传输的 Net-NTLM 响应则与本轮 Challenge 等输入有关;NTLMv2 还包含客户端随机数、时间戳和目标信息等。
NTLM Relay 将目标本轮生成的 Challenge 转交给客户端,再将客户端算出的响应交回目标验证。这样双方使用的是同一轮挑战响应。
NTLM 认证协议的版本:NTLMv1 与 NTLMv2
NTLM 认证协议有 NTLMv1 和 NTLMv2 两个版本。前面提到的三条消息(Type 1 / Type 2 / Type 3)是两个版本共同的消息结构——NTLMv1 和 NTLMv2 的区别体现在 Type 3(AUTHENTICATE_MESSAGE)中 Response 的构造方式。NTLMv1 已基本淘汰(LMCompatibilityLevel >= 3 的 Windows 默认使用 NTLMv2):
| 版本 | 加密算法 | 响应长度 | MIC 保护 | 安全性 |
|---|---|---|---|---|
| NTLMv1 | DES + MD4 | NT 响应 24 字节;LM 响应字段通常另占 24 字节 | 无 | 弱,易爆破 |
| NTLMv2 | HMAC-MD5 | Variable(含 Blob) | Type 3 可携带,是否要求取决于协商、标志与实现 | 较强 |
NTLMv2 Response 的内部结构
NTLMv2 响应由 NTProofStr 和客户端构造的 blob 组成,随 Type 3 消息发给服务端:
NTLMv2 Response = NTProofStr (16 bytes) + Blob (variable)
NTProofStr:
HMAC-MD5(ResponseKeyNT, ServerChallenge + Blob)
ResponseKeyNT = HMAC-MD5(NTLM Hash, UTF-16LE(Uppercase(User) + Domain))
Blob 包括时间戳、8 字节客户端随机数及 AV_PAIR(Attribute-Value Pair)等:
- MsvAvTimestamp (服务端 TargetInfo 中提供的时间戳,存在时影响客户端响应构造)
- MsvAvNbComputerName (服务端 NetBIOS 机器名)
- MsvAvNbDomainName (服务端 NetBIOS 域名)
- MsvAvDnsComputerName (服务端 DNS 计算机名)
- MsvAvDnsDomainName (服务端 DNS 域名)
- MsvAvTargetName (目标 SPN,如 cifs/fileserver)
- MsvAvChannelBindings (通道绑定信息的摘要,可选)
- MsvAvFlags (标志位,指示 MIC 是否存在)
客户端会结合 Type 2 的 TargetInfo 和自身掌握的目标、通道信息构造响应。
MsvAvTargetName可用于服务绑定,MsvAvChannelBindings可用于通道绑定。跨协议中继能否继续,取决于接收服务实际验证哪些绑定,以及后续是否要求消息签名。
SSP 与 SSPI
Windows 应用程序通过 SSPI(Security Support Provider Interface) 调用认证功能,具体协议由 SSP(Security Support Provider) 实现。应用可以选用某个 SSP,也可以交给 Negotiate 选择认证机制。
Windows 内置了几个主要的 SSP:
| SSP 名称 | DLL 文件 | 实现的协议 |
|---|---|---|
| NTLM SSP | msv1_0.dll |
NTLM 认证(Challenge/Response) |
| Kerberos SSP | kerberos.dll |
Kerberos 认证(Ticket-based) |
| Negotiate SSP | lsasrv.dll(Negotiate 实现) |
按凭据、名称和策略协商 Kerberos 或 NTLM |
| Digest SSP | wdigest.dll |
HTTP Digest 认证 |
| Schannel SSP | schannel.dll |
TLS/SSL 认证 |
应用程序可以指定 Negotiate SSP,让它在 Kerberos 和 NTLM 间选择。Negotiate 通常优先使用 Kerberos。缺少 Kerberos 所需的信息时,如果客户端和服务端策略允许,可以选用 NTLM。见微软 SSPI 架构说明。
应用程序(如 SMB 服务、IIS、SQL Server)
│
▼
SSPI(通用接口:AcquireCredentialsHandle / InitializeSecurityContext)
│
├── Negotiate SSP(协商选择)
│ │
│ ├── Kerberos SSP (kerberos.dll)
│ └── NTLM SSP (msv1_0.dll)
│
▼
LSASS.exe(加载各 SSP 的 DLL)
│
▼
Netlogon (netlogon.dll) —— 域账户 NTLM 验证可经安全通道提交域控
Kerberos SSP 另与 KDC 交换 Kerberos 消息
Netlogon:服务端与域控的桥梁
Netlogon 是 Windows 的一个核心服务(netlogon.dll,由 LSASS 加载),它负责域成员机器与域控制器之间的安全通信。在 NTLM 认证的语境中,Netlogon 承担着一个关键角色:帮助服务端向域控验证用户凭据。
域成员服务器收到域账户的 Type 3(AUTHENTICATE)后,通常通过 Netlogon 的 NetrLogonSamLogon 系列方法请求域控验证。提交的网络登录信息包含账户标识、Challenge 和 NT / LM 响应等字段,结构见 NETLOGON_NETWORK_INFO。域控验证响应后返回账户与会话密钥材料;服务端继续执行所需的本地完整性和绑定检查。本地账户则使用目标本机保存的凭据验证。
客户端(Client) 服务端(Server) 域控(DC)
│ │ │
│ 1. Type 1 (Negotiate) │ │
│──────────────────────────>│ │
│ │ │
│ 2. Type 2 (Challenge) │ │
│<──────────────────────────│ │
│ │ │
│ 3. Type 3 (Authenticate) │ │
│──────────────────────────>│ │
│ │ │
│ │ 4. Netlogon RPC │
│ │ NetrLogonSamLogon │
│ │ Identity / Challenge │
│ │ Response 等 │
│ │───────────────────────────>│
│ │ │
│ │ DC 用 NTLM Hash 计算 │
│ │ Response 并比对 │
│ │ │
│ │ 5. 验证结果(通过/失败) │
│ │<───────────────────────────│
│ │ │
│ 6. 认证通过,服务端 │ │
│ 为 Client 创建会话 │ │
│<──────────────────────────│ │
这对 Relay 攻击的意义:
在线中继时,攻击者把 Server-B 的本次 Challenge 转交给 Client,再将 Client 计算的 Response 交给 Server-B。Server-B 可以经 Netlogon 请求域控验证这组匹配的挑战响应;接下来还要满足 MIC、目标绑定、通道绑定和应用消息签名等检查。服务端自身也参与协议保护,单独捕获 Server-A 的旧 Response 无法直接用于任意新挑战。
Kerberos
Kerberos 是一种基于加密 Ticket 的身份认证协议
Key Distribution Center: 简称 KDC,密钥分发中心,默认安装在域控。
Authentication Service: 身份验证服务,简称 AS,用于 KDC 对 Client 的认证
Ticket Granting Service: 票据授予服务,简称 TGS,接受客户端的 TGT 和认证器,为其签发目标服务的 ST 及对应会话密钥。
Session Key【AS|TGS】:本文分别用 Session-Key AS 表示 TGT 会话密钥,用 Session-Key TGS 表示服务票据会话密钥。它们由 KDC 生成,交给客户端及对应的验证方使用。
PAC:Privilege Attribute Certificate,保存用户 SID、组 SID 等授权信息。Windows 服务端可据此构造访问令牌,并结合资源 ACL 判断访问权限。
TGT:由 KDC 使用 krbtgt 账户的长期密钥加密生成,内部包含 Session-Key AS、Client-info、PAC、票据生命周期等信息,用于后续向 TGS 申请服务票据。
ST:Service Ticket,服务票据。票据的加密部分由目标服务账户的长期密钥保护。客户端持有 ST 及配套会话密钥,用会话密钥生成 Authenticator,连同 ST 一起向服务证明身份。
三个阶段
下面分别说明账户长期密钥和票据会话密钥的用途。使用 RC4-HMAC 时,账户长期密钥与 NT Hash 数值相同;使用 AES 时则需要对应的 AES Key。
认证过程主要有三个阶段,下面这张图就比较清晰的展示了主要流程

AS-REQ & AS-REP
此阶段是 Client 和 AS 的认证获得 TGT
AS-REQ:
下面以口令派生密钥和加密时间戳预认证为例。客户端向 KDC 的 AS 发送 AS-REQ,明文请求字段包含客户端、目标服务和支持的加密类型等信息;预认证数据中的时间戳使用客户端账户的长期密钥加密。RC4 场景下,这个密钥在数值上等于 NT Hash。已有登录凭据时,这一步可自动完成。
AS-REP:
AS 查询账户,使用对应密钥验证预认证数据,并检查时间戳、账户状态与策略。允许的时钟偏差通常为 5 分钟,按域策略确定。验证通过后,KDC 生成 Session-Key AS:将它放入用 krbtgt 密钥加密的 TGT,同时放入用客户端密钥加密的 AS-REP 回复部分,使客户端也能取得它。
我们来整理一下客户端收到的响应包:客户端密钥加密的回复部分(包含 Session-Key AS 等信息)、TGT(其加密部分包含 Session-Key AS、Client-info、PAC、票据生命周期等)。外层票据名等字段可读。
TGS-REQ & TGS-REP
此阶段是客户端与 TGS 进行认证,获得 ST
TGS-REQ:
客户端收到 AS-REP 后,用对应的账户密钥解密回复部分,恢复 Session-Key AS,然后本地缓存 TGT 和 Session-Key AS。
如果 Client 需要访问某台服务器上的服务,它需要向 TGS 发送 TGS-REQ 请求获得对应的 ST
TGS-REQ 包括:TGT、用 Session-Key AS 加密的 Authenticator,以及请求访问的目标 SPN 等字段。Authenticator 中包含客户端身份和当前时间戳,并通过校验和绑定请求体。
TGS-REP:
TGS 用 krbtgt 的密钥解密 TGT,取得 Session-Key AS,再用它验证 Authenticator,检查客户端身份、时钟偏差、票据有效期及相应策略。通过后生成 Session-Key TGS,并将它放进两处:一处是返回客户端的加密回复部分,通常使用 Session-Key AS 保护(请求提供认证器子密钥时使用该子密钥);另一处是用目标服务账户密钥加密的 ST。具体资源访问权限随后由服务端判断。
TGS-REP 包括:客户端可解密的回复部分(包含 Session-Key TGS 等信息)、ST(其加密部分包含 Session-Key TGS、Client-info、PAC 等)。
AP-REQ & AP-REP
此阶段是 Client 和 Server 的认证
AP-REQ:
客户端收到 TGS-REP 后,解密回复部分取得 Session-Key TGS,再用它加密 Client-info、当前时间戳等信息,生成 Authenticator。然后把 Authenticator 和 ST 一起发送给 Server。
AP-REQ 发送内容:Session-Key TGS 加密的 Client-info 和时间戳、ST
服务端收到 AP-REQ 后,用服务账户的密钥解密 ST,取得 Session-Key TGS,再用它解密 Authenticator,核对客户端身份、票据有效期、时间戳和重放缓存。时钟偏差通常允许 5 分钟,票据生命周期另由域策略决定。
AP-REP:
进行双向认证时,服务端使用 Session-Key TGS 加密客户端 Authenticator 中的时间戳等字段,返回 AP-REP;其中也可携带服务端子密钥和序列号。客户端解密并核对回复,从而验证服务端。上述三阶段的协议结构见 RFC 4120。
Windows 服务端还会处理票据中的 PAC,根据 SID、组成员等信息构造访问令牌,再结合资源 ACL 授权。PAC 带有服务端签名及 KDC 签名等保护。服务账户密钥用于验证对应服务端签名;需要校验 KDC 签名时,服务端可通过 Netlogon 将验证请求提交域控,由持有 krbtgt 密钥的 KDC 完成检查。
Kerberos 加密类型
Kerberos 支持多种加密算法,实际选择受客户端声明、账户可用密钥、KDC 和服务配置共同影响。票据自身的加密类型、回复部分的加密类型、票据内会话密钥的类型需要分别判断。
用户密码(明文)
│
├── MD4(UTF-16LE(password)) ──────→ RC4-HMAC 密钥(= NTLM Hash)
│
├── PBKDF2-HMAC-SHA1 → DK(tkey, "kerberos") → AES128 长期密钥
│
└── PBKDF2-HMAC-SHA1 → DK(tkey, "kerberos") → AES256 长期密钥
| 加密类型 | 密钥长度 | EType 编号 | 现状 |
|---|---|---|---|
| DES-CBC-CRC | 56 bit | 1 | 已禁用(Windows 7 / 2008 R2 起默认禁用) |
| DES-CBC-MD5 | 56 bit | 3 | 已禁用 |
| RC4-HMAC | 128 bit | 23 | 已弃用;是否允许取决于账户配置、域策略与更新 |
| AES128-CTS-HMAC-SHA1-96 | 128 bit | 17 | 支持 |
| AES256-CTS-HMAC-SHA1-96 | 256 bit | 18 | 推荐,现代域控默认优先使用 |
关键事实:
- RC4 密钥在数值上等于 NTLM Hash:
MD4(UTF-16LE(Password))。这是OverPass The Hash和Pass The Key(RC4 变体)能够工作的核心原因。 - AES 密钥可由密码、salt 和迭代参数派生:对这里的 AES-SHA1 类型,PBKDF2 产生中间值后还要执行
DK(tkey, "kerberos")。RFC 缺省迭代参数解释为 4096 次,密钥长度分别为 128 / 256 位。只有 NT Hash 时,无法直接转换出对应 AES Key;使用已有 AES Key 认证则无需重新知道密码。见 RFC 3962。 - 加密类型按各部分分别选择:TGT 由 krbtgt 可用密钥保护,AS-REP 回复部分按客户端预认证密钥等条件保护,会话密钥也有自己的类型。用 RC4 进行预认证取得 TGT 后,后续 ST 可使用目标支持的其他类型。
- 加密类型可用于审计:在平时主要使用 AES 的环境中,异常出现的 RC4 认证可作为排查线索。
使用 RC4 做 OverPass The Hash,需要环境仍允许该认证方式。票据或预认证的加密类型、异常来源和请求行为都可能成为检测线索;使用 AES Key 也需要结合这些行为判断。2026 年的 KDC 更新进一步收紧了未显式配置服务账户的 RC4 票据默认行为,见微软 CVE-2026-20833 更新说明。
黄金票据
学习了上面的 Kerberos 认证,再来看黄金票据。掌握域内 krbtgt 的长期密钥后,就可以构造 TGT 的加密部分,并生成相应的 PAC 保护信息。RC4 场景使用 krbtgt 的 NT Hash;AES 场景使用对应 AES Key。
伪造时可自行生成 Session-Key AS,将它放进 TGT,同时保存到供客户端使用的票据凭据中。后续向 TGS 请求 ST 时,客户端仍要用这把会话密钥生成 Authenticator,KDC 解密 TGT 后取得同一把密钥来验证请求。用户名、SID、组成员和票据时间等信息也要按目标环境构造。
这解释了黄金票据为何能绕过获取原始用户口令的步骤。最终能申请哪些票据、访问哪些资源,仍受 KDC 对账户和 PAC 的检查、域信任边界及目标授权影响。工具生成与保存会话密钥的过程可参见 Mimikatz 的票据构造实现。
krbtgt 密钥泄露后,攻击者可以持续构造新的 TGT,因此仅等待已伪造票据过期无法消除影响。
伪造黄金票据还需要以下信息:
- 需要构造的用户名及对应用户 RID / SID、组成员等授权信息
- 完整的域名
- 域 SID
- krbtgt 的相应长期密钥(下面的旧版示例使用 RC4 / NT Hash)
这里使用 msf 的 meterpreter 中的 kiwi 生成 RC4 黄金票据,使用的密钥是 krbtgt 的 NT Hash。
首先导入 kiwi
meterpreter > load kiwi
然后输入
golden_ticket_create -d whoamianony.org -k 6be58bfcc0a164af2408d1d3bd313c2a -s S-1-5-21-1315137663-3706837544-1429009142 -u administrator -t /root/krbtgt.ticket
# golden_ticket_create -d 域名 -k krbtgt用户的Hash -s 域sid -u 需要伪造的域管理员用户名 -t /root/krbtgt.ticket
kerberos_ticket_list # 查看本地储存的票据
kerberos_ticket_use /root/krbtgt.ticket # 将票据注入内存
白银票据
白银票据伪造的是面向目标服务的 ST,需要掌握该 SPN 对应服务账户的长期密钥。这个账户可能是机器账户,也可能是独立的服务账户。伪造时生成 Session-Key TGS,构造客户端身份与 PAC 等信息,再用服务密钥加密票据;保存票据时也要保留会话密钥,客户端才能生成 Authenticator。
机器账户密钥与目标服务
Windows 上以机器身份提供的服务,通常使用域机器账户的密钥。例如,DC01 上的 CIFS 服务通常使用 DC01$ 的长期密钥。这里所说的“服务器机器 Hash”,指这个域机器账户的 NT Hash;本地 SAM 中 Administrator 的 Hash 属于另一个账户。
服务账户密钥保护服务端收到的票据,票据中的 cname 则记录客户端身份。掌握 DC01$ 的密钥后,攻击者可以构造面向 DC01 服务、客户端身份为 Administrator 的票据,并填写 PAC 中的用户 RID、组成员等信息。
目标收到 AP-REQ 后,用自己的服务密钥解开 ST,再用票据里的 Session-Key TGS 验证 Authenticator。攻击者在构造票据时就生成了这把会话密钥,因此也能构造 Authenticator,并为后续 SMB 请求计算签名。随后是否接受票据中的身份,还要经过 PAC 验证及资源授权。
制作白银票据需要以下信息:
- 域名
- 域 SID
- 目标服务器的 FQDN (全限定域名,同时带有计算机名和域名)
- 可利用的服务
- 服务账户的相应长期密钥(下面示例使用 RC4 / NT Hash)
- 要伪造的用户名
使用服务器机器账户密钥
这里以 testjd.local 的 DC01 为目标。已取得 DC01$ 的 NT Hash 后,使用 Impacket 构造 CIFS/dc01.testjd.local 的服务票据:
impacket-ticketer -nthash da2a7a521bc0b7f755fad934da64556f -domain-sid S-1-5-21-1725890813-49703812-595888014 -domain testjd.local -spn CIFS/dc01.testjd.local Administrator
-nthash 提供服务账户的 RC4 密钥,-domain-sid 提供域 SID,最后的 Administrator 是要写入票据的客户端用户名。ticketer 默认用户 RID 为 500,与这里的域内置 Administrator 对应;构造其他用户身份时,-user-id 应与目标用户的 RID 对应。参数与票据生成过程见 ticketer.py。
生成的 Administrator.ccache 同时保存服务票据及其会话密钥。让 Impacket 从这个缓存读取凭据:
export KRB5CCNAME=Administrator.ccache
impacket-wmiexec -k -no-pass -dc-ip 192.168.147.128 testjd.local/[email protected] -codec gbk 'whoami'
-k 使用 Kerberos,-no-pass 不提示输入密码,-dc-ip 指定 KDC 地址;服务名称仍按 dc01.testjd.local 构造。-codec gbk 用于解码远程命令的中文输出。
wmiexec 的连接包含 SMB 与 DCOM/RPC 两部分。在这里引用的 Impacket 实现中,RPC 认证会请求 HOST/dc01.testjd.local;缓存查找支持复用同一主机、同一 realm 的其他服务类型票据,并替换票据外层的服务名。CIFS 与 HOST 对应服务使用相同机器账户密钥时,便具备这种复用的密钥基础。不同服务使用独立账户,或服务端有额外名称检查时,需要按各自的密钥与检查处理。相关实现见 Kerberos RPC 认证、票据缓存选择与转换。
这条白银票据命令直接在本地构造 ST,生成阶段不经过 AS、TGS 交换。接收服务若请求域控验证 PAC,仍会产生与域控的通信。RC4 票据也需要目标能够接受对应加密类型。
Mimikatz 同样可以构造服务票据:
kerberos::golden /domain:域名 /sid:域sid /target:全限定域名 /service:服务名 /rc4:服务账号的NTLM-HASH /user:伪造的用户名 /ptt
PAC 签名与域控验证
PAC 中的授权信息带有多种签名。服务密钥与 krbtgt 密钥分别承担不同的验证作用:
| 签名 | 使用的密钥 | 保护内容 |
|---|---|---|
| Server Signature | 目标服务账户密钥 | 保护 PAC,接收服务可据此检查完整性 |
| KDC Signature | krbtgt 密钥 | 对 Server Signature 再计算校验和,提供 KDC 的签发证明 |
| Ticket Signature | krbtgt 密钥 | 绑定票据的 EncTicketPart,计算时将 PAC 所在位置替换为规定的零字节 |
| Extended KDC Signature / Full PAC Signature | krbtgt 密钥 | 直接保护整个 PAC,检测其他主体对授权数据的修改 |
后两类签名主要用于非 krbtgt、非信任账户密钥加密的服务票据。各类签名的计算范围见 Server Signature、KDC Signature、Ticket Signature和 Extended KDC Signature。
只掌握服务账户密钥,可以生成有效的 Server Signature。需要 krbtgt 密钥的签名则无法据此正确计算。这就是白银票据与 PAC 回查之间的关系:接收服务若只沿本地处理路径使用票据,攻击者可能取得伪造身份;请求域控验证相应 KDC 签名时,域控能够识别这份签发证明不匹配。
执行 PAC 回查时,服务器通过 Netlogon 发送 Network Ticket Logon 请求,域控再交由 KDC 验证服务票据中的 PAC 签名,返回用户与设备信息。服务账户跨域时,请求还可能经信任关系转发。协议中的角色关系见 Kerberos PAC Validation Details。
Windows 原本就会按接收服务的身份决定是否进行这次回查。微软列出的可跳过情形包括服务具有 SeTcbPrivilege,以及服务由任务计划程序运行。SYSTEM 上下文中的 SMB 文件共享、LDAP 服务是文档列出的典型例子。其他适用场景会对入站 Kerberos 认证执行 PAC 验证,见 KB5037754 的验证流程及适用条件。
PAC 加固的默认行为
PAC 验证并非到某个补丁日期才整体开启。后续更新增加签名保护、改造回查协议,并逐步将相应验证切换为强制模式:
| 更新阶段 | 变化 |
|---|---|
| 2022 年 11 月起 | CVE-2022-37967 更新引入完整 PAC 签名保护,分阶段部署与强制验证 |
| 2023 年 10 月起 | 完整 PAC 签名进入完整强制阶段,移除 KrbtgtFullPacSignature 的兼容控制 |
| 2024 年 4 月起 | CVE-2024-26248 / CVE-2024-29056 更新引入新的 Network Ticket Logon 验证流程,初期保留兼容处理 |
| 2025 年 1 月起 | 新验证流程默认进入 Enforce;已有显式注册表配置仍可覆盖默认值 |
| 2025 年 4 月起 | 移除 PacSignatureValidationLevel、CrossDomainFilteringLevel 的兼容开关,强制新流程 |
前两阶段见 KB5020805,后三阶段见 KB5037754。这里的强制模式约束执行 PAC 回查时使用的验证流程,服务身份对应的跳过情形仍然存在。
因此,判断白银票据的使用条件,要沿接收服务继续追踪:先确认它使用哪个账户密钥,再看是否请求域控验证,以及验证时采用的签名与协议规则。服务能解开 ST,与域控确认票据中的授权信息由 KDC 签发,是两个环节。
旧资料中的 ValidateKdcPacSignature 是与服务进程身份相关的历史设置。它的适用条件见微软的 PAC 验证说明。当前环境应结合接收服务和上述更新判断,开启新流程的时间以相应补丁阶段为依据。
不含 PAC 的票据请求
Rubeus 的 /nopac 用于在请求中设置不包含 PAC 的意图,影响的是请求内容。接收端的验证规则由服务端处理,KDC 是否按该意图签发也有自己的规则。
安装 2021 年 11 月 9 日起相关更新后,Windows KDC 会为域账户的 TGT 加入 PAC,即使客户端请求不要 PAC。这组变化还增加了对原始请求者身份的绑定,见 KB5008380。PAC 中的用户 SID 和组信息用于构造授权身份,省去这份数据本身也不会产生管理员组授权。
钻石票据
钻石票据从一张正常取得的 TGT 开始,解开其中的加密部分,修改客户端身份及 PAC,再重新签名、加密。TGT 使用 krbtgt 的密钥保护,因此这里仍然需要掌握对应的 krbtgt 长期密钥。它与白银票据使用服务器机器账户密钥的前提不同。
Rubeus 的 /tgtdeleg 从当前域登录会话的 SSPI 委派输出中取得 TGT 及会话密钥。随后 diamond 使用 /krbkey 提供的 krbtgt 密钥解密 TGT,修改身份与组信息,重算适用的 PAC 签名,并重新加密。TGT 的生命周期、会话密钥等基础信息沿用原票据,后续客户端仍用这把会话密钥向 TGS 证明自己持有 TGT。
这里使用 krbtgt 的 AES256 密钥,将票据身份改为 administrator,并写入 RID 500、组 RID 512:
rubeus.exe diamond /tgtdeleg /ticketuser:administrator /ticketuserid:500 /groups:512 /krbkey:6d293fbe01b9e228ea6681c512601f512e44b77793105055b32cbbcc63acf703 /nowrap
| 参数 | 作用 |
|---|---|
/tgtdeleg |
通过当前登录会话的委派输出取得用于改写的 TGT |
/krbkey |
krbtgt 的长期密钥,用于解密 TGT、重签 PAC 及重新加密 |
/ticketuser、/ticketuserid |
改写票据用户名和用户 RID;这里的 500 对应域内置 Administrator |
/groups:512 |
把域内 Domain Admins 的组 RID 写入 PAC |
/nowrap |
将 Base64 票据输出为一行,便于传给后续命令 |
身份修改还涉及 TGT 内部的 cname、PAC 中的客户端信息,以及请求者 SID 等字段的一致性。Rubeus 的相应处理见 Diamond 命令和 ModifyTicket 实现。
取得改写后的票据,再通过 ptt 导入当前登录会话:
rubeus.exe ptt /ticket:doIFvDCCBbigAwIBBaEDAgEWooIEvDCCBLhhggS0MIIEsKADAgEFoQ4bDFRFU1RKRC5MT0NBTKIhMB+gAwIBAqEYMBYbBmtyYnRndBsMVEVTVEpELkxPQ0FMo4IEdDCCBHCgAwIBEqEDAgEDooIEYgSCBF7Sf4+uT9RsXm4NbioGkyfbowgPBFuEfHhl5YDVWLkqjwI87zTDDqvWqWyW/T2v/OQCNHJ1BDy3PsBp9cVezeTS+P7OZ8m6UEE5QILwqPu7nlK0e9cZCxQPQZNr6JPvrmJHJ8VmHVvV7ONTu6maFBEbIjDrKLIW31WJWhVg2a/iRV4ihX43bYRhAilencUIDynzAZcKA77WWqoGmXF3LsZIsaj3FM3eSJPaYTEKcKcEtGNSzGG2Te0qHtb8KT43yQFQl6KKf9Wiq1WceFo4pLrRodTo3Wwzg6UWjlHZLDDnu+I633sj1uocnNXWxIsFQgL1m7qrCW7FgdGkooD9+N7EHNAoG2W3WoyKfyMcPaJwg27eq+3yH2xmkaUePvR1JWxQpKkhD8q2ZzsvnhATtu92wUuYea6z2/W5gSiC6iXv6Z2/jMQY9UACDq7ibYv8SKPddo/ElFPFkPlzhkuTpMAiDA7G3TaFYF+m9F7aZHmW8lZJSrbAwuCvAtzfwwOx4CKRuTCnIdAbT5HMUbrHolsP80lpSogEYzvuu5RJ9lwzkFnZzVMMGbTNIz2gejAyN2f1dOC2DLYoBQ7Ev/FNRWbYQHhwwj5b6W7DDXfNS7OaXjjR9HgXJy5+YC1zeK5vY2KQj6eC07N7Svxcii+4/YU5jnYovMxxXrW24D83pEAYJTbwyjP6cuu6J87LzigqnyEJZWLYKI4G7ULSLhoCCSD5RqSqraqVJHuuM9ENOLzRNDG4fK5IhAGhGdxDX2VuLndU5yn6VnAr2RBNOnQS+cgrWGVu+DjrnyPUB9uEt5dDjlGyTJ9fOJG7jR0VQaKINiK8fZWgGyQv7NR9F0lIAXYYI0Gy+VCDciG0OSFK5HBjcrHQzJ58lEw//oWFbstwzCcM3FDn12RIuYKUdhLY97cfzhC+ioXb2Ja1lbS+69suI9ql3rpOEy+Y5xhUbtTjdws5/a7Zqrua1qBC76qlTPX10yzXggrzkif4BY6ac6f7gyocdJ+00ufyVWK0QXPEC8+4vE3BNWc8MFyXxwsgQWkLYTri1lVx1AL6Lm2fKYbQ69asky/8kmeazlOEiJIJSE9AsB8jzV3lQ7aZJTaD0XgBfe4W2Skf5URUHERDKvh86zq5UZtUg3o+ef9RbfRFzisY765Wnefmb8Tz9s8x4sRkj+2/9hgcw7DAjb70eHPCpPNoANZ5nvIZPJaMAMqptCc5RlMvAtNTrqQn+ziQy0ref7t+hXA+CoAQj+Y9tshikVo3nniawW9Cqbcq+JFK3q+UFErIScouHlKVJriFv4BNnVGPy93r3IOT6rJjg6jmTh+9ugrBph43kETupUr+UypOxzguRa0rIQerao6tsw+jKp5lMX5/5L7GotZ+hzzkRh9W8yHjYxhQ4OR4bnjnduIcOigkHXbJZ25nI+UzNXr9Q+JlX0PzbUAjxI3tfk50o2Que33wzBckerWnktJkWn8NUwplUzHpqXs7qwPt9aOB6zCB6KADAgEAooHgBIHdfYHaMIHXoIHUMIHRMIHOoCswKaADAgESoSIEIM9oWm6WOZjvsJIOPSUogK9dFcKVfEgPeF//iI91vGDToQ4bDFRFU1RKRC5MT0NBTKIaMBigAwIBAaERMA8bDWFkbWluaXN0cmF0b3KjBwMFAGChAAClERgPMjAyNjEwMzAxMDMxMDhaphEYDzIwMjYxMDMwMjAxODQxWqcRGA8yMDI2MTEwNjEwMTg0MVqoDhsMVEVTVEpELkxPQ0FMqSEwH6ADAgECoRgwFhsGa3JidGd0GwxURVNUSkQuTE9DQUw=
Rubeus 会先后输出原票据与改写后的票据,这里使用 Encrypting Modified TGT 之后输出的那份。ptt 也支持从 .kirbi 文件读取凭据,参数格式见 Rubeus 的 ptt 说明。
这份示例票据的结束时间为 2026 年 10 月 30 日 20:18:41 UTC,即北京时间 10 月 31 日 04:18:41。重新生成票据后,导入时使用对应的新输出。
导入更新的是当前登录会话中的 Kerberos 票据缓存。后续访问网络服务时,客户端使用这张 TGT 请求 ST,再向服务认证;本地已有进程的访问令牌仍由原登录建立,直接运行本地 whoami 会显示原进程身份。
这里攻击者已经持有 krbtgt 密钥,可以重算 TGT 所需的签名。PAC 加固验证签名和身份字段的一致性,域控仍会按对应账户、信任边界及请求类型处理后续取票。
NTLM Hash 与 Kerberos Key 的关系
从同一个密码派生出不同的密钥
Windows 从同一个密码计算 NT Hash,也可以派生出用于 Kerberos 的 AES 密钥。账户数据库保存这些口令摘要和密钥材料。
用户密码(明文)
│
├─── MD4(UTF-16LE(password)) ──────────────→ NTLM Hash
│ │
│ ├── 用于 NTLM 认证
│ │
│ └── 可直接作为 Kerberos RC4 密钥
│
└─── PBKDF2 + DK(密码、salt、参数)──────→ Kerberos AES Long-term Keys
│
├── AES128-CTS-HMAC-SHA1-96
└── AES256-CTS-HMAC-SHA1-96
关键结论:
- NTLM Hash 和 Kerberos RC4 Key 在数值上完全相同,都等于
MD4(UTF-16LE(password)) - 使用场景不同:NTLM Hash 参与 NTLM 响应计算;相同数值也可作为 Kerberos RC4 长期密钥,用于相应加密类型的预认证或票据保护
- AES Key 则通过不同的密钥派生函数从明文密码计算,无法从 NTLM Hash 直接得到
这意味着:拿到 NTLM Hash,也就掌握了同一账户的 Kerberos RC4 Key。环境允许 RC4 时,可以将它用于相应 Kerberos 认证。
Windows 存储的密钥形式
域账户的数据保存在域控的 ntds.dit 中,本地账户数据保存在本机 SAM 中。下表列出了常见的口令摘要和密钥。旧域账户可在支持 AES 的域环境中通过更新密码生成相应的 Kerberos 密钥。
| 密钥类型 | 存储位置 | 用途 |
|---|---|---|
| NTLM Hash | SAM / ntds.dit | NTLM 认证、Kerberos RC4 |
| Kerberos AES-128 Key | ntds.dit | Kerberos AES 加密 |
| Kerberos AES-256 Key | ntds.dit | Kerberos AES 加密(优先) |
本地账户的口令验证通常使用 SAM 中的 NT Hash;域账户的 AES 密钥材料保存在 AD 的相应凭据属性中。域成员机上也可能在登录会话或 LSA Secret 等位置保存域凭据材料,这些位置与本地 SAM 分别处理。
Pass-the-X 技术族
理解了密钥派生关系之后,各种 Pass-the-X 技术的本质就很清晰了:它们都是用不同形式的凭据绕过需要输入明文密码的步骤,直接完成认证。
| 技术 | 传递的凭据 | 认证协议 | 最终目的 |
|---|---|---|---|
| Pass The Password | 明文密码 | 任意 | 正常登录 |
| Pass The Hash | NTLM Hash | NTLM | 以目标账户身份访问资源 |
| OverPass The Hash | NTLM Hash(充当 RC4 Key) | Kerberos | 申请 TGT,转入 Kerberos 体系 |
| Pass The Key | Kerberos AES/RC4 Key | Kerberos | 申请 TGT,转入 Kerberos 体系 |
| Pass The Ticket | TGT 或 ST 及其配套会话密钥(如 kirbi / ccache 凭据) | Kerberos | 使用已有 TGT 申请 ST,或使用 ST 向服务认证 |
| Pass The Certificate | 证书 + 私钥 | PKINIT | 通过证书预认证申请 TGT |
Pass The Hash(PTH)
原理:使用已有 NT Hash 参与 NTLM 响应计算。NTLMv1 与 NTLMv2 使用不同算法,NTLMv2 还会结合用户名和域名派生 ResponseKeyNT,因此无需先恢复明文密码。
使用场景:目标允许 NTLM,且对应账户可通过网络登录并具有资源访问权限时。Windows 通过 IP 地址访问服务时,默认通常使用 NTLM;Kerberos 的常见访问方式则使用能匹配 SPN 的主机名。
局限:只能用于 NTLM 认证,对强制要求 Kerberos 的服务无效。
OverPass The Hash(也叫 Pass The Key / RC4 变体)
原理:NTLM Hash 与 Kerberos RC4 Key 数值相同。用该密钥加密时间戳,放入 AS-REQ 的预认证数据,KDC 用同样的值解密验证,从而申请到 TGT。
效果:在 KDC 接受相应加密类型与预认证后取得 TGT,后续按账户权限及域策略申请 ST,再向服务认证。
与 PTH 的核心区别:
PTH → Hash → NTLM Challenge-Response → 向目标服务认证
OverPTH/PTK → Hash/AES Key → Kerberos AS-REQ → 申请 TGT → 申请 ST 并按权限访问服务
Pass The Key(PTK)
Pass The Key 使用已有的 Kerberos 长期密钥进行认证,常见用法是使用 AES-128 / AES-256 Key。RC4 Key 在数值上等于 NT Hash,因此 OverPass The Hash 也常被视作 Pass The Key 的 RC4 用法;不同工具对术语的使用略有差异。
特点:AES Key 可用于不接受 RC4 的环境。所用算法与正常 AES 认证相同,检测仍可结合来源、请求模式、账户使用行为和票据信息。
获取 AES Key:可从有权读取的 AD 凭据数据、具备相应权限的内存会话(如 mimikatz sekurlsa::ekeys)获取,也可在已知密码、正确 salt 和参数时派生。
Pass The Ticket(PTT)
原理:把已有的票据凭据导入登录会话或凭据缓存。常见 kirbi / ccache 中同时保存 TGT 或 ST 以及对应会话密钥;客户端使用会话密钥生成新的 Authenticator。使用现有有效票据凭据时,无需再知道账户长期密钥或明文密码。
两种票据的区别:
| 票据类型 | 适用范围 | 默认最大有效期 |
|---|---|---|
| TGT | 向对应域的 KDC 申请策略允许的 ST | 10 小时 |
| ST | 向票据对应服务认证,仍需服务验证与授权 | 10 小时 |
黄金票据和白银票据使用掌握的长期密钥构造票据凭据,随后也可以通过 PTT 导入使用。两者分别依赖 krbtgt 密钥和服务账户密钥。
表中 10 小时对应 Windows 域默认票据策略的上限。KDC 会结合请求的结束时间与域、账户的生命周期限制确定有效期;通过 TGT 申请 ST 时,ST 的结束时间也受到 TGT 剩余有效期限制。参见微软服务票据生命周期说明。
Pass The Certificate(PTC)
原理:Kerberos 的 PKINIT 扩展支持证书预认证。客户端用对应私钥对预认证数据签名,KDC 验证签名、证书信任及账户映射等条件;双方通过相应密钥交换方式建立回复保护所需的密钥材料,客户端据此取得 TGT 和配套会话密钥。见 RFC 4556。
使用场景:在 ADCS(Active Directory Certificate Services)攻击中,攻击者通过 ESC 系列漏洞申请到目标账户的证书,再用 PTC 将证书兑换成 TGT。
特点:账户改密通常不会同时撤销已经签发的证书。证书和私钥仍可用于认证时,需同时满足有效期、信任、撤销状态、账户状态和映射要求;Windows KDC 的证书强映射要求见 KB5014754。
PTC 需要证书及使用其对应私钥的能力。证书携带公钥和身份信息,私钥用于完成签名。常见 .pfx/.p12 可同时保存证书与私钥,也可以通过智能卡等方式调用私钥完成认证。
按手中已有的凭据,可以把这些技术对应起来:
已有凭据
│
├── 明文密码 ─────────────────────────────→ Pass The Password
│ │
│ ├── MD4 → NT Hash
│ └── KDF → AES Key
│
├── 账户长期密钥
│ │
│ ├── NT Hash → NTLM 响应计算 ────────→ Pass The Hash
│ ├── NT Hash(RC4 Key)→ Kerberos ───→ OverPass The Hash
│ └── AES / RC4 Key → Kerberos ───────→ Pass The Key
│
├── 已有 TGT / ST 及其会话密钥 ───────────→ Pass The Ticket
│
└── 证书 + 使用对应私钥的能力 → PKINIT ───→ Pass The Certificate