Recutting the Kerberos Diamond Ticket Huntress
免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。
本文由 Charlie Clark (@exploitph) 共同撰写
引言
Kerberos “Diamond Ticket”(钻石票)自提出以来,就像未经切割的钻石一样,常被误解和低估。最初发布的 PoC(概念验证) 技术粗糙,缺乏完整的实战打磨;其“切工”不精,其“净度”因缺乏实际操作场景而模糊,其“色泽”也因误解而失真。随着时间推移,围绕其真正用途和潜力的误区愈发明显。
本文将对 Diamond Ticket 进行“精修”,聚焦于 OPSEC(操作安全),让这一概念真正发挥其“克拉”级的安全价值,提供更安全的 Kerberos ticket forgery(Kerberos 票据伪造) 方法。我们不仅会澄清常见误区,还将介绍更注重 OPSEC 的 TGT(Ticket Granting Ticket,票据授权票)变体,并演示该思路如何扩展到 ST(Service Ticket,服务票)。
不完美的钻石
要理解优化后的“Diamond Ticket”有多强大,先得审视其现有形态。正如未经雕琢的钻石,Rubeus 中的 PoC 只是最小可用实现,仍有大量提升空间。我们将聚焦于 PoC 中 Privilege Attribute Certificate(PAC,权限属性证书)相关的局限——PAC 是 Kerberos 票据的核心组成部分。
与 Golden Ticket(黄金票)不同,后者完全用 KRBTGT 密钥和基础元数据伪造 TGT,Diamond Ticket 采用更“真实”的方式:先通过合法的 AS-REQ(认证服务请求)向域控(DC)获取有效 TGT(AS-REP),再解密、修改(如 PAC 属性),最后用 KRBTGT AES256 密钥重新加密。Diamond 与 Golden/Silver Ticket 的唯一区别就是这一步 AS 交换,使认证流程表面上更“合规”。但这种“合规性”其实是 Diamond 最被误解的特性。虽然它模拟了 Kerberos 的真实行为,但如果直接篡改 PAC 里的组成员或将 TGT 用户从 loki 换成 thor,这些操作在有日志和检测的环境下依然极易被发现。
这种方法通过起始于有效签名票据,保留了大部分原始结构,并且有真实的 AS-REQ/REP 交换(而不是票据凭空出现——Diamond 设计的初衷),提升了攻击的“可信度”。但 PoC 仍有 OPSEC 缺陷,尤其是 PAC 仅做了最小修改。PAC 中的组成员字段被设置为预定义默认值(520,512,513,519,518),与其他攻击工具类似,这些值早已被安全圈熟知,一旦 PAC 被解密就是明显的 IOC(入侵指示器)。此外,PAC 还缺少诸如真实登录会话信息、设备属性等关键细节,难以伪装成真正的票据。
这些缺陷影响很大。Kerberos 环境如果启用严格 PAC 校验(如 Protected Users 组或 Privileged Access Workstations),或部署了高级监控方案,这些异常都能被检测到,使 PoC 的“真实”思路失去隐蔽性。而且,PAC 是用 KRBTGT 账户密钥签名的,任何未考虑这些细节的结构修改都可能导致与部分 Kerberos 实现或监控配置不兼容。
本节将详细拆解 Rubeus 中现有 PoC 的实现,从 TGT 请求、解密、修改到重新加密的每一步,并分析其技术短板,尤其是 PAC 相关问题,为提升 Diamond Ticket 的 OPSEC 和实战可用性提供思路。
下面演示如何用当前 PoC 生成 Diamond Ticket:
Rubeus.exe diamond /krbkey:<aes256_krbtgt_key> /user:loki /password:Mischief$ /enctype:aes /domain:marvel.local /dc:earth-dc.marvel.local /ticketuser:thor /ticketuserid:1104 /nowrap
将 /servicekey
和 /ticket
参数传给 Rubeus 的 describe 功能,可以解密并分析新生成的 Diamond Ticket 的 PAC。
如上图所示,Rubeus 将默认组填入 PAC,且许多字段为空或错误。如果防御方或安全工具能看到 PAC,这种做法极不利于 OPSEC。
用“放大镜”或 Rubeus“Describe”功能审查 PAC
就像珠宝商用放大镜检查钻石,有时你也需要“放大”Kerberos 票据,看看它的真实成分。这里不是钻石,而是用 Rubeus 的 /describe
检查加密票据 blob。
Kerberos 票据是 Active Directory(AD)环境中认证与授权的核心。它确保用户在访问网络资源前已被正确认证,是域内安全通信的基石。
要理解访问决策如何做出,必须深入票据内部。
Ticket(大部分加密):此部分包含用服务长期密钥加密的客户端相关数据,用于验证和授权客户端访问资源。PAC 是其中关键,承载用户权限和身份数据,实现细粒度访问控制。
下图是帮助理解 PAC 结构的可视化示意:
"I've Got a Golden Twinkle In My Eye," SANS Pentest and Hackfest Summit 2022)
图示要点:
-
PAC 位于票据的 Authorization-Data 字段内,并被加密以保护机密性。 -
TGT 由 KRBTGT 账户密钥加密。 -
ST 由目标服务的专用密钥加密。 -
PAC 包含: -
用户属性:如 SID(安全标识符)、Logon Domain Name(登录域名),用于唯一标识域内用户。 -
组成员信息:用户所属组,决定其访问权限。 -
策略数据:如 PasswordMustChange(密码必须更改),确保域策略(如密码过期)被执行。
这种结构既保证了 PAC 的机密性,也保证了其完整性,使其成为各服务间授权决策的可靠依据。
为什么 PAC(Privilege Attribute Certificate)必不可少
虽然 Kerberos ticket(票据)本身可以证明用户身份,但 PAC(Privilege Attribute Certificate)在认证(authentication)与授权(authorization)之间起着关键纽带作用。PAC 是服务端用来判断用户认证后能做什么的核心数据集。
PAC 的核心作用:
-
用户身份(User Identity): PAC 内含用户的 SID(安全标识符,Security Identifier),在域内唯一标识用户,确保网络范围内的身份一致性。 -
授权(Authorization): PAC 中的组成员信息(Group Memberships)决定用户可访问哪些资源和服务。 -
策略强制(Enforcing Policies): 如 PasswordMustChange(密码必须更改)等属性,用于强制执行组织级安全策略,比如定期要求用户更改密码。 -
跨域信任(Cross-Domain Trust): PAC 可包含跨域认证(cross-domain authentication)所需的信任信息,允许用户访问其他域的资源。
下面详细拆解上文样例票据的各字段,说明其在安全认证中的作用和重要性:
1. 服务信息(Service information)
-
ServiceName: krbtgt/MARVEL.LOCAL
-
该字段指明票据关联的服务。KRBTGT 服务即 TGT(Ticket Granting Ticket)服务,是 Kerberos 认证的核心,负责签发和续签 TGT。本例中服务属于 MARVEL.LOCAL
域。 -
ServiceRealm: MARVEL.LOCAL
-
ServiceRealm 并非服务实际所在位置,而是票据请求或签发时的 realm。在跨域(cross-realm)场景下,ServiceRealm 反映客户端发起请求的本地 realm,而不一定是服务本身的 realm。
2. 用户信息(User information)
-
UserName: thor (NT_PRINCIPAL)
-
票据请求账户的用户名,本例为 thor
,属于MARVEL.LOCAL
域。NT_PRINCIPAL 表示标准 NT(Windows)用户主体。 -
UserRealm: MARVEL.LOCAL
-
用户所属的 Kerberos realm。
3. 票据有效期(Ticket validity)
-
StartTime: 1/13/2025 6:42:04 PM -
票据生效时间,用于强制时间限制,防止票据提前被滥用,提升时效安全性。 -
EndTime: 1/14/2025 4:42:04 AM -
票据失效时间,过期后票据不可再用,防止“僵尸票据”被滥用。 -
RenewTill: 1/20/2025 6:42:04 PM -
票据可续签的最晚时间,便于长会话持续访问,无需频繁重新认证。
4. 票据标志(Ticket flags)
-
Flags: name_canonicalize, pre_authent, initial, renewable, forwardable -
name_canonicalize: 用户名标准化(规范化)。 -
pre_authent: 票据签发前需预认证(pre-authentication),增加安全性。 -
initial: 标记为初始票据,表示用户会话的起点。 -
renewable: 票据可续签,便于长期访问。 -
forwardable: 票据可转发,支持跨服务无缝认证。 -
这些标志定义票据行为:
5. 加密信息(Encryption information)
-
KeyType: aes256_cts_hmac_sha1 -
会话密钥的加密算法(etype),本例为 AES-256 + HMAC-SHA1,属于现代强加密算法,保障会话通信的机密性和完整性。 -
Base64(key): s2loS0ukhVb9HBn+YyrgyBBZCyQS0RFXLsoq7/OpCXc= -
用于用户与服务间通信的会话密钥,Base64 编码。该密钥在票据签发过程中协商,只有授权方可解密会话数据。
6. 加密数据(Encrypted data)
-
Block One Plain Text: 6382043D30820439 -
票据加密数据的原始片段。此字段用于针对 DES 加密票据的攻击(相关攻击分析),需密钥解密后才能读取。
7. 解密后的 PAC(Decrypted PAC)
PAC 解密后包含关键用户信息和会话细节,具体如下:
-
LogonInfo:
-
LogonTime: 12/30/2024 8:53:25 PM 用户登录时间,便于追踪活动和检测异常登录。 -
PasswordLastSet: 2/17/2023 7:24:59 PM 上次密码更改时间,判断凭据是否过期。 -
PasswordCanChange: 2/18/2023 7:24:59 PM 用户可更改密码的最早时间,防止过早更改,维护策略一致性。 -
LogonCount: 407 成功登录次数,过高或过低都可能提示异常。 -
BadPasswordCount: 0 登录失败次数,0 说明无异常尝试,安全性较高。 -
UserFlags: (32) EXTRA_SIDS 用户账户附加标志,EXTRA_SIDS 表示有额外 SID 关联。 -
LogonServer: EARTH-DC 认证用户的域控(Domain Controller),便于溯源。 -
Groups: 520,512,513,519,518
-
用户所属组的 RID 列表,决定其访问权限范围。
8. 客户端与请求者信息(Client and requestor information)
-
ClientId: 1/13/2025 6:42:04 PM -
客户端(如 thor)请求票据的精确时间点,便于事件同步与日志审计。 -
Client Name: thor -
发起请求的客户端用户名,确认身份。 -
RequestorSID: S-1-5-21-208534352-3953284921-3886779260-1104 -
请求票据实体的 SID,通常为用户。该字段确保请求者与实际使用者一致,微软为防止 samaccountname 冒充漏洞而引入。
9. 校验和与签名(Checksums and signatures)*
-
ServerChecksum: -
Signature Type: KERB_CHECKSUM_HMAC_SHA1_96_AES256 校验票据完整性的算法,基于 HMAC-SHA1 和 AES-256。 -
Signature: 1D4FF0E68C986BF62ADF85F2 (VALID) 校验值,VALID 表示票据未被篡改。 -
KDCChecksum: -
Signature type: KERB_CHECKSUM_HMAC_SHA1_96_AES256 用于保护 ServerChecksum,主要针对非 KRBTGT 密钥签名的服务票据(如 Service Ticket)。 -
Signature: 7C50B4A42F460F3B97F3F2D5 (VALID) 确保票据在 KDC 处理期间的安全性。
* 注意:如 TrustedSec 博客 所述,“Ticket 和 FullPAC 校验和不会出现在 TGT 或 referral,只存在于 Service Ticket 中。”
为什么这些字段至关重要
Kerberos 票据(Kerberos Ticket)中的每个属性都直接关系到其整体安全性与完整性。这些字段确保用户身份被验证、服务访问被正确控制,并防止票据在传输过程中被篡改。
清晰度增强 / 裂隙填充(Fracture Filling)
正如钻石的裂隙填充(Fracture Filling)能提升其透明度,Rubeus 的 LDAP 功能(/ldap)通过从 Active Directory(AD)提取关键信息,为 PAC(Privilege Attribute Certificate)构建提供了“真实数据填充”。Rubeus 的/ldap 参数利用 LDAP 查询并挂载域控(Domain Controller, DC)的 SYSVOL 共享,获取构建 PAC 所需的核心信息。PAC 是 Kerberos 票据的核心组成部分,是 AD 认证与授权的基础。下面详细拆解 Rubeus 的 LDAP 功能技术细节。Networking.cs 文件负责 Rubeus 与 LDAP 的交互,分别检索用户和域数据。连接成功(需凭证认证)后,通过 GetLDAPSearchRoot 查询域根。
Rubeus 的主要操作流程:
-
通过 LDAP 查询 Active Directory,提取用户属性和组成员关系 -
挂载 DC 的 SYSVOL 共享,获取账户和组策略 -
提取 Kerberos 和密码策略,用于伪造 PAC
1. 建立 LDAP 连接
Rubeus 使用 System.DirectoryServices.Protocols 库与 AD 域控通信。连接可通过 LDAP(389 端口)或 LDAPS(636 端口)建立。若使用 LDAPS,则通过 TLS 加密。LdapConnection 对象以 DC 主机名或 IP 初始化,认证方式支持明文密码、NTLM 哈希或 Kerberos 票据。
A. 绑定到域控(Binding to the Domain Controller):
-
Rubeus 可用 Simple Bind(用户名 + 密码)或 SASL Bind(NTLM 或 Kerberos 认证)绑定 LDAP 服务 -
绑定成功后,可查询用户对象、组及域安全策略
B. 执行 LDAP 查询(Executing LDAP Queries):
-
Rubeus 会发送三次 LDAP 查询,收集 PAC 所需信息
2. 挂载 SYSVOL
Rubeus 通过与 SYSVOL 和 IPC$共享交互,提取组策略对象(GPO):
-
挂载流程:
-
IPC$ → 管理访问(初始连接) -
SYSVOL → 存储域级 GPO(后续连接) -
通过 SMB(445 端口)认证访问 DC,挂载 SYSVOL -
访问路径: -
从 SYSVOL 提取的策略:
-
GptTmpl.inf:存储密码策略(如 MinimumPasswordLength) -
Parameters:存储 Kerberos 策略(如 MaxTicketAge)
3. 提取用户属性
挂载 SYSVOL 并提取相关策略后,Rubeus 再通过 LDAP 查询 AD,获取用户属性。这些属性用于构建 PAC,是 Kerberos 认证的关键。PAC 包含用户身份、组成员、权限等信息,决定域内访问控制。
Rubeus 会检索特定 LDAP 属性,涵盖账户信息、组成员关系及安全设置,用于 PAC 构建。
4. 从 SYSVOL 提取密码与 Kerberos 策略
Rubeus 主要从 SYSVOL 目录下的 GptTmpl.inf 文件提取根域的 Kerberos 策略和密码策略。该文件包含密码策略(如最小密码长度、密码过期)和 Kerberos 票据策略(如票据生命周期、续期策略)等关键配置。
SYSVOL 目录是 AD 的共享文件夹,存储 GPO、脚本等公共域信息。它确保策略在所有域控间一致分发。Rubeus 访问此目录,获取全域安全策略,确保认证行为配置正确。
Rubeus 通过读取 SYSVOL 中的 GptTmpl.inf 文件,提取密码与 Kerberos 策略:
<DC>SYSVOL<domain>Policies{GUID}MachineMicrosoftWindows NTSecEditGptTmpl.inf
读取 GptTmpl.inf 后,Rubeus 可获取域内配置的密码与 Kerberos 策略。这些设置决定密码复杂度、变更周期、Kerberos 票据有效期等关键行为。对于 Kerberos 认证,PAC 需结合这些策略,确保合规与安全。
这些策略直接影响认证与授权行为,例如:
-
Kerberos 认证的票据过期时间,决定用户无需重新认证可持续访问的时长 -
密码过期与复杂度,强制强密码与定期更换,降低密码攻击风险
下表总结了 Rubeus 从 GptTmpl.inf 提取的关键 Kerberos 与密码策略:
策略名称 |
提取值 |
用途 |
MinimumPasswordLength |
7 |
定义域用户密码的最小长度,提升密码安全性 |
MaximumPasswordAge |
42 |
指定用户需更换密码的最大天数 |
LockoutBadCount |
0 |
定义连续失败登录次数触发账户锁定,防止暴力破解 |
MaxTicketAge |
10 hours |
Kerberos TGT 最大生命周期,控制会话时长 |
MaxRenewAge |
7 days |
TGT 最大续期时长,防止无限会话,确保凭据及时更新 |
5. 重切钻石票据(Recutting the Diamond Ticket)
Kerberos TGT(Ticket Granting Ticket)是域内用户认证和无缝访问服务的核心。通过提取 Kerberos 策略和 LDAP 属性,Rubeus 可伪造出与真实 Kerberos 票据行为一致的 TGT。该伪造票据可让攻击者或测试者绕过标准认证机制,实现权限提升。
对于 Golden Ticket 和 Silver Ticket,/ldap 参数一直是核心功能,使 Rubeus 能与 LDAP 资源交互,拉取用户组成员和属性,确保 PAC 中关键 LDAP 相关字段被正确填充,提升伪造票据的可信度。
但在 Rubeus 的 Diamond Ticket 场景中,早期 PoC 未集成此功能,导致 PAC 内 LDAP 相关字段常为空或错误(见图 2),削弱了伪造 Diamond Ticket 的真实性。Diamond Ticket 未充分利用 LDAP 属性,难以用于高阶攻击或测试。
为 Diamond Ticket 添加 LDAP 集成
为解决上述问题,我们重构了 Rubeus 的 ForgeTicket.cs 和 Diamond.cs,使 Diamond Ticket 支持/ldap 参数。这样在创建 Diamond Ticket 时,PAC 会自动提取并填充 LDAP 属性,最终 PAC 能真实反映用户上下文,伪造票据更具可信度。
现在,使用我们修改后的代码,可以为 diamond 命令同时指定/ldap、/ldapuser 和/ldappassword 参数(后续可合并为/ldap 参数)。
新版 Rubeus Diamond Ticket 命令示例:
Rubeus.exe diamond /krbkey:<aes256_krbtgt_key> /user:loki /password:Mischief$ /enctype:aes /domain:marvel.local /dc:earth-dc.marvel.local /ticketuser:thor /ticketuserid:1104 /nowrap /ldap /ldapuser:loki /ldappassword:Mischief$
完整变革:每个字段都被修正
下面对比未使用/ldap 与新票据的解密 Diamond Ticket:
1 |
Decrypted PAC : |
1 |
Decrypted PAC : |
2 |
LogonInfo : |
2 |
LogonInfo : |
3 |
LogonTime : 2/21/2025 5:15:39 AM |
3 |
LogonTime : 2/17/2025 2:36:03 PM |
4 |
LogoffTime : |
4 |
LogoffTime : |
5 |
KickOffTime : |
5 |
KickOffTime : |
6 |
PasswordLastSet : 2/17/2023 7:24:59 PM |
6 |
PasswordLastSet : 2/4/2025 8:03:10 PM |
7 |
PasswordCanChange : 2/18/2023 7:24:59 PM |
7 |
PasswordCanChange : 2/5/2025 8:03:10 PM |
8 |
PasswordMustChange : |
8 |
PasswordMustChange : 3/18/2025 8:03:10 PM |
9 |
EffectiveName : thor |
9 |
EffectiveName : thor |
10 |
FullName : Loki |
10 |
FullName : Thor Odenson |
11 |
LogonScript : |
11 |
LogonScript : |
12 |
ProfilePath : |
12 |
ProfilePath : \ASGARD-WRKSTNOdin's Vault |
13 |
HomeDirectory : |
13 |
HomeDirectory : \asgard-wrkstnusersthor |
14 |
HomeDirectoryDrive : |
14 |
HomeDirectoryDrive : Z: |
15 |
LogonCount : 460 |
15 |
LogonCount : 41 |
16 |
BadPasswordCount : 0 |
16 |
BadPasswordCount : 0 |
17 |
UserId : 1104 |
17 |
UserId : 1104 |
18 |
PrimaryGroupId : 513 |
18 |
PrimaryGroupId : 513 |
19 |
GroupCount : 5 |
19 |
GroupCount : 3 |
20 |
Groups : 520,512,513,519,518 |
20 |
Groups : 512,525,513 |
21 |
UserFlags : (32) EXTRA_SIDS |
21 |
UserFlags : (0) 0 |
22 |
UserSessionKey : 0000000000000000 |
22 |
UserSessionKey : 0000000000000000 |
23 |
LogonServer : EARTH-DC |
23 |
LogonServer : |
24 |
LogonDomainName : MARVEL |
24 |
LogonDomainName : MARVEL |
25 |
LogonDomainId : S-1-5-21-208534352-3953284921-3886779260 |
25 |
LogonDomainId : S-1-5-21-208534352-3953284921-3886779260 |
26 |
UserAccountControl : (528) NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD |
26 |
UserAccountControl : (16400) NORMAL_ACCOUNT, NOT_DELEGATED |
27 |
ExtraSIDCount : 2 |
27 |
ExtraSIDCount : 0 |
28 |
ExtraSIDs : S-1-5-21-0-0-0-497,S-1-18-1 |
28 |
|
29 |
ResourceGroupCount : 0 |
29 |
ResourceGroupCount : 0 |
30 |
ClientName : |
30 |
ClientName : |
31 |
Client Id : 2/21/2025 5:15:45 AM |
31 |
Client Id : 2/21/2025 5:15:56 AM |
32 |
Client Name : thor |
32 |
Client Name : thor |
33 |
UpnDns : |
33 |
UpnDns : |
34 |
DNS Domain Name : MARVEL.LOCAL |
34 |
DNS Domain Name : MARVEL.LOCAL |
35 |
UPN : [email protected] |
35 |
UPN : [email protected] |
36 |
Flags : (2) EXTENDED |
36 |
Flags : (2) EXTENDED |
37 |
SamName : thor |
37 |
SamName : thor |
38 |
Sid : S-1-5-21-208534352-3953284921-3886779260-1104 |
38 |
Sid : S-1-5-21-208534352-3953284921-3886779260-1104 |
39 |
Attributes : |
39 |
Attributes : |
40 |
AttributeLength : 2 |
40 |
AttributeLength : 2 |
41 |
AttributeFlags : (1) PAC_WAS_REQUESTED |
41 |
AttributeFlags : (1) PAC_WAS_REQUESTED |
42 |
Requestor : |
42 |
Requestor : |
43 |
RequestorSID : S-1-5-21-208534352-3953284921-3886779260-1104 |
43 |
RequestorSID : S-1-5-21-208534352-3953284921-3886779260-1104 |
/ldap 增强后,PAC 几乎每个字段都被真实数据填充:
关键认证字段
-
LogonTime:反映真实用户上次登录时间,而非当前时间 -
LogonCount:真实计数(41),避免异常统计 -
LogonServer:填充实际认证服务器
密码策略合规
-
PasswordLastSet:当前日期,非 2023 年 -
PasswordCanChange:基于域策略正确计算 -
PasswordMustChange:现已填充,强制最大密码周期
用户身份准确性
-
FullName:"Thor Odenson"而非"Loki" -
ProfilePath:有效漫游配置文件路径 -
HomeDirectory:实际用户主目录 -
HomeDirectoryDrive:正确的驱动器映射
安全组与权限
-
Groups:真实组成员(512,525,513),无 IOC 特征组 -
UserFlags:清零(0),无可疑 EXTRA_SIDS -
ExtraSIDs:移除伪造 SID(S-1-5-21-0-0-0-497,S-1-18-1)
账户控制
-
UserAccountControl:(16400) NORMAL_ACCOUNT, NOT_DELEGATED,替换掉可疑的 DONT_EXPIRE_PASSWORD
OPSEC 提升
集成 LDAP 后,能构建完整、真实的用户上下文,包括:
-
合理的会话时间,匹配用户实际活动 -
与 AD 记录一致的身份属性 -
无 IOC 特征的真实组成员 -
正确的密码策略日期 -
合规的账户控制标志 -
无可疑 Extra SIDs 或伪造属性 -
完整的配置文件与目录映射
/ldap 增强功能使 PAC(Privilege Attribute Certificate,权限属性证书)中的几乎每个字段都被真实数据填充:
关键认证字段(Critical Authentication Fields)
-
LogonTime(登录时间):现在反映真实用户的上次登录时间,而非当前时间 -
LogonCount(登录计数):真实计数(41)替代伪造值(460),避免统计异常 -
LogonServer(认证服务器):填充为实际的认证服务器
密码策略合规性(Password Policy Compliance)
-
PasswordLastSet(密码最后设置时间):为当前日期,而非 2023 年 -
PasswordCanChange(密码可更改时间):基于域策略正确计算 -
PasswordMustChange(密码必须更改时间):现已填充,强制最大密码周期
用户身份准确性(User Identity Accuracy)
-
FullName(全名):"Thor Odenson" 替代 "Loki" -
ProfilePath(漫游配置文件路径):有效的漫游配置文件位置 -
HomeDirectory(主目录):实际用户主目录 -
HomeDirectoryDrive(主目录驱动器):正确的驱动器映射
安全组与权限(Security Groups & Permissions)
-
Groups(组成员):真实组成员(512,525,513),而非默认 IOC(520,512,513,519,518) -
UserFlags(用户标志):清零(0),无可疑 EXTRA_SIDS -
ExtraSIDs(额外 SID):移除伪造 SID(S-1-5-21-0-0-0-497, S-1-18-1)
账户控制(Account Control)
-
UserAccountControl(账户控制标志):(16400)NORMAL_ACCOUNT, NOT_DELEGATED,替换掉可疑的 DONT_EXPIRE_PASSWORD
OPSEC(运营安全)提升
通过集成 LDAP(轻量级目录访问协议),我们能够构建完整且真实的用户上下文,包括:
-
合理的会话时间,匹配用户实际活动 -
与 AD(Active Directory,活动目录)记录一致的身份属性 -
无 IOC(Indicator of Compromise,威胁指示器)特征的真实组成员 -
正确的密码策略日期 -
合规的账户控制标志 -
无可疑 Extra SIDs 或伪造属性 -
完整的配置文件与目录映射
这种字段级别的准确性,使 Diamond Ticket(钻石票据)从易被检测的伪造票据,转变为能够通过严格 PAC 校验的“真实”票据。
Diamond Ticket 的 /OPSEC 集成
我们还为 Diamond Ticket 实现了 /opsec 参数,确保票据生成过程中的网络流量与真实 Windows Kerberos 行为一致。当启用该参数时,AS-REQ/AS-REP(Kerberos 认证请求/响应)流程遵循 Windows 标准的两步认证模式:首先发送不带预认证的 AS-REQ,收到 KDC(Key Distribution Center,密钥分发中心)的 PREAUTH_REQUIRED 错误后,再发送格式正确的预认证请求。这使得 Diamond Ticket 生成过程中的网络流量与真实域内 Windows 客户端完全一致。该参数强制使用 AES256 加密算法,并设置正确的 KDCOptions,消除了可用于区分伪造票据与真实 Kerberos 认证流量的网络层指纹。
特别感谢 Joe Dibley (@JoeDibley2) 对 Diamond /opsec 功能的实现提供的帮助。
当 /ldap 与 /opsec 同时启用时,Diamond Ticket 不仅能够“融入环境”,还能经受严格检查,无论是在网络流量还是 PAC 字段层面都与真实 Kerberos 票据高度一致。
Service Ticket(服务票据)功能扩展
正如切割钻石能提升其清晰度与价值,我们通过对 Rubeus 的改造,将 Diamond Ticket 技术扩展到 Service Ticket(服务票据)。最初该技术仅支持 TGT(Ticket Granting Ticket,票据授权票据),这一进步让 Silver Ticket(银票)在现代环境下的实用性受到质疑,因为 Silver Ticket 缺乏真实认证流,且更易被检测。通过此扩展,我们进一步模糊了隐蔽性与合法性的界限,让传统 Silver Ticket 显得粗糙且易识别。
你可能还记得我们最初博客中的这句话:
在完成研究并开发出 POC(概念验证)武器化后,Elad Shamir 向我们推荐了 Tim Medin 在 DerbyCon 2014 的演讲《Attacking Microsoft Kerberos: Kicking the Guard Dog of Hades》。Tim 在演讲中讨论了类似技术——但应用于 Service Ticket 场景。
这发生在 2022 年 7 月,我们首次发布 Diamond Ticket POC 时。
经过更深入的研究,我们认为现在正是将该技术直接应用于 Service Ticket 的最佳时机。
新特性
本次更新允许你将 Diamond 伪造技术应用于 Service Ticket(服务票据),而 Service Ticket 通常基于合法 TGT 颁发。现在,你可以直接使用以下方式伪造 TGS(Ticket Granting Service,服务票据):
-
合法或伪造的 Kerberos 票据 blob -
AES 服务密钥(即用于加密服务票据的密钥)
此增强功能支持直接利用有效或已伪造的 TGT 创建服务票据(Service Ticket),为 Kerberos 票据操作带来更大灵活性,尤其适用于需要高度隐蔽性的场景。
New Rubeus Diamond Ticket command:
Rubeus.exe diamond /enctype:aes /domain:marvel.local /dc:earth-dc.marvel.local /ticketuser:thor /ticketuserid:1104 /ldap /ldapuser:loki /ldappassword:Mischief$ /nowrap /opsec /ticket:<output_of_service_ticket> /service:<SPN> /servicekey:<aes256_service_key>

总结
在本次“重切割”Diamond Ticket(钻石票据)的过程中,我们已将其从一个粗糙的概念验证(POC)打磨成了现代 Kerberos 攻击链中值得严肃对待的实用技术。通过集成 LDAP、实现完善的 OPSEC(运营安全)控制,并将功能扩展到 Service Ticket(服务票据),我们解决了此前让 Diamond Ticket 仅停留在理论层面的根本局限。
这些增强功能从根本上改变了攻击者与防御者的风险评估。对比下 Diamond Ticket 与传统票据伪造技术的差异:
Kerberos 票据伪造对比表
Technique(技术) |
Ticket Type Forged(伪造票据类型) |
Requires DC Traffic?(需要 DC 流量?) |
Authentication Flow(认证流程) |
Detection Risk(检测风险) |
Golden |
TGT |
❌ No |
❌ None(无 AS-REQ 或 TGS-REQ) |
High* *详见 Charlie 和 Andrew 的演讲:"I've Got a Golden Twinkle In My Eye" for SANS Pentest and Hackfest Summit (2022 年 11 月 14 日) |
Silver |
TGS |
❌ No |
❌ None(无 TGS-REQ) |
Medium-High* *详见 Charlie 的演讲:"I’ve Got a Forged Ticket In My Eye" |
Diamond |
TGT 或 TGS |
✅ Yes(AS/TGS) |
✅ 合法 AS-REQ/TGS-REQ |
Medium-High(不通过 LSASS 进行 client 到 DC 通信 🙁) |
Sapphire |
TGS via U2U |
✅ Yes(TGS + TGT) |
⚠️ 部分(TGS-REQ 带 ENC-TKT-IN-SKEY,U2U 流程) |
High(ENC-TKT-IN-SKEY 标志 + U2U 服务票据总以 8 或 C 结尾,极为罕见的流量) |
虽然 Diamond Ticket 依然存在被检测的风险(尤其是因为其绕过了 LSASS 进行 client 到 DC 的通信),但它在隐蔽性和实用性之间提供了一个极具吸引力的平衡点。Golden Ticket 和 Silver Ticket(银票)都是“凭空出现”,没有任何认证流量;而 Diamond Ticket 则会实际走完整的 AS-REQ/AS-REP 或 TGS-REQ/TGS-REP 交换流程。结合 LDAP 自动填充的 PAC 数据,这种票据能在多个层面通过检查。
Silver Ticket(银票)已死?
既然 Diamond 技术已扩展到 Service Ticket(服务票据),那传统 Silver Ticket 是否已经“过时”?为什么还要伪造一个“凭空出现”的服务票据,而不是生成一个有真实认证流量的?Silver Ticket 依然适用于你完全无法接触 DC 的场景。但如果你更看重隐蔽性而非便利性,Diamond 伪造的服务票据才是进化方向。
对防御者的启示
对蓝队来说,这些改进再次强调了全面 Kerberos 监控的重要性。虽然伪造票据依然可被检测,但我们确实提高了检测门槛。防御者应关注:
-
关注认证行为模式,而不仅仅是 PAC 内容 -
监控异常的 client 到 DC 通信模式 -
构建能关联多种指标的 SIEM 规则 -
牢记“看似正常”的认证流量也可能隐藏伪造票据
展望
打磨后的 Diamond Ticket 技术表明,Kerberos 攻击手法仍在不断演进。防御者提升检测能力,攻击者则持续伪装以融入环境。这种攻防博弈推动双方不断进步。最终,增强版 Diamond Ticket 证明:最危险的攻击往往是那些看起来最“正常”的。它们伪装得如此之好,真假难辨,真正考验防御者的能力。
我们已在 此 Pull Request 中将这些新特性合入 Rubeus。
感谢 Joe Dibley (@JoeDibley2) 协助实现 Diamond 的 /opsec 功能,Elad Shamir (@elad_shamir) 和 Ceri Coburn (@_EthicalChaos_) 审阅本文,以及所有 Huntress 团队成员的反馈。
原文始发于微信公众号(securitainment):重塑 Kerberos Diamond Ticket(钻石票)攻防实践
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论