Recutting the Kerberos Diamond Ticket

Glitch effectGlitch effectGlitch effect
Glitch banner

This blog was co-written with Charlie Clark (@exploitph)

Introduction

The Kerberos "Diamond Ticket" has, much like an uncut diamond, been misunderstood and undervalued since its initial inception. When the proof of concept (PoC) was first released, it lacked the polish of a fully developed technique; its "cut" was rough, its "clarity" clouded by a lack of operational context, and its "color" skewed by misconceptions. Over time, this has created a range of misunderstandings about its true purpose and potential.

In this post, we’ll refine the understanding of the diamond ticket, bringing its brilliance to light. By focusing on operational security (OPSEC), we aim to give this concept the precision and weight or "carat" it deserves to offer a more secure method of working with Kerberos ticket forgery. We’ll not only address these misconceptions but also introduce a more OPSEC-focused version for Ticket Granting Tickets (TGTs) and demonstrate how the concept can be applied to Service Tickets (STs).


Imperfect Diamond

Before we can appreciate the brilliance of an optimized "Diamond Ticket," we need to examine its current form. Much like an uncut diamond, the PoC in its current state demonstrated in Rubeus represents a minimal viable implementation with significant room for refinement. We’ll not only address these misconceptions but also introduce a more OPSEC-focused version for Ticket Granting Tickets (TGTs) and demonstrate how the concept can be applied to Service Tickets (STs). A key part of this involves looking at limitations in the PoC involving the Privilege Attribute Certificate (PAC), a critical component of a Kerberos ticket.

Unlike Golden Tickets, which involve forging a TGT entirely from scratch using only the KRBTGT key and essential metadata, Diamond Tickets take a more “genuine” approach. They begin with a legitimate AS-REQ to the domain controller (DC) to obtain a valid TGT via AS-REP, which is then decrypted, modified (for example, PAC attributes), and re-encrypted using the KRBTGT AES256 key. The only difference between Diamond and Golden or Silver tickets is this initial AS exchange, making the authentication flow appear more legitimate on the surface. This perceived legitimacy is arguably Diamond’s most misunderstood feature. While it mimics real Kerberos behavior, blatant modifications like swapping group memberships in the PAC or requesting a TGT for loki and altering it to thor are still trivially detectable with proper logging and inspection.

This method increases the authenticity of the attack by starting with a valid, signed ticket, preserving much of the original ticket’s structure, along with having a prior AS-REQ/REP exchange rather than a ticket appearing out of nowhere (the main reason we thought Diamond would be a useful idea). However, the PoC has limitations that create operational security (OPSEC) gaps. Specifically, the PAC is only minimally modified. While the PAC includes group memberships, they are left at pre-defined default values (520,512,513,519,518) similar to other attack tools, which are well-known and can serve as a clear indicator of compromise (IOC) if the PAC can be decrypted. Additionally, the PAC lacks other critical details that would align it more closely with a legitimate ticket, such as accurate logon session information and device attributes.

The implications of these gaps are significant. Kerberos environments that enforce strict PAC validation (for example, Protected Users group or Privileged Access Workstations) or employ advanced monitoring solutions can flag these discrepancies, rendering the "genuine" approach operationalized in the PoC less stealthy than intended. Furthermore, because the PAC is signed using the KRBTGT account’s key, any alteration to its structure that does not account for these gaps can potentially break compatibility with certain Kerberos implementations or monitoring configurations.

In this section, we’ll dissect the current PoC implementation found in Rubeus, breaking down its methodology step by step from the initial TGT request to its decryption, modification, and re-encryption process. We’ll also examine the technical shortcomings of the current approach and explore why addressing these issues, particularly around the PAC, is crucial for enhancing the OPSEC and practical viability of the Diamond Ticket in real-world scenarios.

Let’s create a Diamond Ticket in its current PoC form:

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

Figure 1: Default Rubeus Diamond Ticket

Supplying the values of /servicekey and /ticket to Rubeus’ describe function, we can decrypt and examine the PAC of our newly created Diamond Ticket.

Figure 2: Decrypted Diamond Ticket with original PoC

Looking at the above output, Rubeus populated the default groups into the PAC and left many of the fields blank or incorrect, which is not OPSEC safe if a defender or security tool gains visibility into the PAC.


PAC Examination with a Loupe or with Rubeus’ “Describe” Function

Like a jeweler with a loupe, sometimes you need to zoom in on a Kerberos ticket to see what it's really made of. Instead of diamonds, you're inspecting encrypted ticket blobs with Rubeus’ /describe.

Kerberos tickets are at the heart of authentication and authorization in Active Directory (AD) environments. They ensure that users are properly authenticated before accessing network resources, forming the backbone of secure communication within a domain.

To understand how access decisions are made, it helps to look inside the ticket itself.

Ticket (Mostly Encrypted): This section contains the client-related data that is encrypted with the service's long-term key. It’s used to validate and authorize client access to resources. A vital part of this section is the PAC, which carries the user’s privilege and identity data necessary for fine-grained access control decisions.

The following diagram is a visualization map to help you, the reader, understand the context of the PAC.

Key Insights from the Diagram:

  • The PAC resides within the Authorization-Data field of the ticket and is encrypted to protect its confidentiality.
    • For TGTs, the KRBTGT account key is used for encryption.
    • For STs, the service's specific key is used for encryption.
  • The PAC contains:
    • User attributes: Such as SID (Security Identifier) and Logon Domain Name, which are crucial for identifying the user within the domain.
    • Group memberships: Information on which groups the user is part of, which helps determine the user’s access rights.
    • Policy data: Data points like PasswordMustChange, ensuring that domain policies (e.g., password expiration) are followed.

This structure ensures both the confidentiality and integrity of the PAC, making it a reliable source for authorization decisions across services.

Why the PAC is necessary

While the Kerberos ticket itself proves the user’s identity, the PAC plays a vital role in linking authentication with authorization. The PAC is the data set that services use to determine what the user is allowed to do once they have been authenticated.

Key PAC Roles:

  • User Identity: The PAC includes the user’s SID, which uniquely identifies them within the domain, ensuring proper identification across the network.

  • Authorization: Group memberships within the PAC define what resources and services the user is permitted to access.

  • Enforcing Policies: Attributes like PasswordMustChange enforce organization-wide security policies, such as forcing users to change passwords after a certain period.

  • Cross-Domain Trust: The PAC can include trust information for cross-domain authentication, allowing users from one domain to access resources in another domain.

Below, we'll break down each field from our sample ticket above and explain its role and importance in maintaining secure authentication:


1. Service information
  • ServiceName: krbtgt/MARVEL.LOCAL
    • This field indicates the service associated with the ticket. The KRBTGT service is the TGT service, which is the central component in Kerberos authentication. It's responsible for issuing and renewing TGTs. In this case, the service is specific to the MARVEL.LOCAL domain.
  • ServiceRealm: MARVEL.LOCAL
    • The ServiceRealm is not where the service is located, but rather specifies the realm where the ticket was requested or issued. In cross-realm scenarios, when requesting a ticket for a service in a foreign domain, the ServiceRealm reflects the local realm where the client initiated the request, not necessarily the realm of the service itself.
2. User information
  • UserName: thor (NT_PRINCIPAL)

    • This field represents the username of the account requesting the ticket. In this case, it’s thor, an identifier for a user in the MARVEL.LOCAL domain. The term NT_PRINCIPAL signifies that it’s a standard NT (Windows) user principal.
  • UserRealm: MARVEL.LOCAL
    • This is the Kerberos realm where the user resides.
3. Ticket validity
  • StartTime: 1/13/2025 6:42:04 PM
    • The StartTime marks when the ticket becomes valid. It’s used to enforce time-based restrictions, preventing the ticket from being used before this timestamp. It adds an element of temporal security to the ticket.
  • EndTime: 1/14/2025 4:42:04 AM
    • The EndTime defines the expiration of the ticket. After this time, the ticket is no longer valid, preventing stale tickets from being used for unauthorized access.
  • RenewTill: 1/20/2025 6:42:04 PM
    • This is the latest time the ticket can be renewed. Renewal ensures that users don't need to re-authenticate constantly. It’s particularly useful for long sessions where users need continuous access without re-entering credentials.
4. Ticket flags
  • Flags: name_canonicalize, pre_authent, initial, renewable, forwardable
    • These flags indicate certain behaviors of the ticket:
      • name_canonicalize: Ensures the user’s name is in a canonical form (standardized and normalized).
      • pre_authent: This means that the user must undergo pre-authentication before the ticket can be issued. It ensures additional verification is needed, strengthening security.
      • initial: Marks the ticket as the initial one, meaning it was issued at the beginning of the user’s session.
      • renewable: The ticket can be renewed without re-authenticating the user, which is useful for maintaining long-term access.
      • forwardable: This flag allows the ticket to be passed between services for seamless cross-service authentication.
5. Encryption information
  • KeyType: aes256_cts_hmac_sha1
    • The KeyType specifies the encryption algorithm (etype) used for the session key. In this case, it uses AES-256 with HMAC-SHA1 for integrity, which is a strong, modern encryption algorithm designed to protect the session's communications from tampering and unauthorized access.
  • Base64(key): s2loS0ukhVb9HBn+YyrgyBBZCyQS0RFXLsoq7/OpCXc=
    • This field contains the session key used to secure communications between the user and the service, encoded in Base64. This key is a shared secret established during the ticket-granting process. It ensures that only authorized parties can decrypt the session data and use its contents.
6. Encrypted data
  • Block One Plain Text: 6382043D30820439
    • This field represents part of the encrypted ticket data in its raw form. This was added in order to perform attacks against DES encrypted tickets. It’s a block of binary data that would need the encryption key to be decrypted into a readable format.
7. Decrypted PAC 

The PAC contains critical user information and session details, which are decrypted from the ticket. Here’s a breakdown of what’s inside:

  • LogonInfo:

    • LogonTime: 12/30/2024 8:53:25 PM
      • The timestamp when the user logged in. It’s useful for tracking user activity and detecting unauthorized logins.
    • PasswordLastSet: 2/17/2023 7:24:59 PM
      • The date when the user last changed their password. This helps determine if the user’s credentials are up to date and whether the password is still within a secure validity period.
    • PasswordCanChange: 2/18/2023 7:24:59 PM
      • The date when the user is allowed to change their password. This is used to prevent a user from changing their password prematurely, maintaining system integrity.
    • LogonCount: 407
      • The number of successful logons by the user. A high count could indicate a high level of access, while an unexpectedly low count might raise concerns.
    • BadPasswordCount: 0
      • The number of failed login attempts. A count of zero means the user hasn’t experienced any failed login attempts, which is indicative of a secure login history.
    • UserFlags: (32) EXTRA_SIDS
      • Flags that provide additional information about the user account. The EXTRA_SIDS flag indicates that the user is associated with additional security identifiers (SIDs).
    • LogonServer: EARTH-DC
      • The domain controller that authenticated the user. It helps track where the authentication request was processed.
  • Groups: 520,512,513,519,518
    • A list of group RIDs that the user belongs to. These RIDs are important for defining what resources the user has access to.

8. Client and requestor information
  • ClientId: 1/13/2025 6:42:04 PM
    • This timestamp marks the exact moment when the client (in this case, thor) requested the ticket. It helps synchronize authentication events and logs.
  • Client Name: thor
    • The client’s username that requested the ticket. It confirms the identity of the user or system that initiated the request.
  • RequestorSID: S-1-5-21-208534352-3953284921-3886779260-1104
    • The SID of the entity requesting the ticket, typically the user. This field ensures that the account that requested the ticket is the same account it is being used for. This was added by Microsoft to protect against the samaccountname impersonation bug.

9. Checksums and signatures*
  • ServerChecksum:
    • Signature Type: KERB_CHECKSUM_HMAC_SHA1_96_AES256
    • This is the type of checksum used to validate the integrity of the ticket. In this case, it's based on HMAC-SHA1 and AES-256 encryption.
    • Signature: 1D4FF0E68C986BF62ADF85F2 (VALID)
    • The checksum value used to verify that the ticket has not been tampered with. The VALID status indicates that the ticket’s integrity is intact.
  • KDCChecksum:
    • Signature type: KERB_CHECKSUM_HMAC_SHA1_96_AES256
    • This is used to protect the server checksum, primarily useful for tickets which are not encrypted and signed with the KRBTGT key (for example service tickets).
    • Signature: 7C50B4A42F460F3B97F3F2D5 (VALID)
    • This checksum ensures that the ticket remains secure while being processed by the KDC.

* Just a reminder, as noted in our previous blog post, “Ticket and FullPAC Checksums are not present in TGTs or referrals. They are only present in service tickets.”


Why these fields matter

Each attribute in a Kerberos ticket contributes to its overall security and integrity. The fields ensure that the user’s identity is verified, that their access to services is properly controlled, and that the ticket cannot be tampered with during transmission.


Clarity enhancement / fracture filling

Just as fracture filling enhances the clarity of a diamond by revealing its true brilliance, Rubeus’ LDAP function uncovers and extracts vital details from AD, bringing critical information to the surface for PAC construction. Rubeus has an /ldap function that leverages LDAP queries and mounts the SYSVOL share of a domain controller to retrieve critical information for constructing a PAC. The PAC is a core component of Kerberos tickets and is essential for both authentication and authorization within AD. Below, we break down how Rubeus’ LDAP function operates in technical detail. The Networking.cs file handles how Rubeus interacts with LDAP in a given AD domain to retrieve the user and domain data, respectively. Upon a successful connection, which requires credential authentication, the root of the domain is queried via GetLDAPSearchRoot.

Rubeus works by:

  • Querying Active Directory over LDAP to extract user attributes and group memberships.
  • Mounting the SYSVOL share of a DC to retrieve account and group policies.
  • Extracting Kerberos and password policies to construct a forged PAC.

1. Establishing LDAP connection

Rubeus uses the System.DirectoryServices.Protocols library to communicate with an AD domain controller. The connection is established using LDAP (port 389) or LDAPS (port 636). If LDAPS is used, the connection is encrypted using TLS. The LdapConnection object is initialized with the DC’s hostname or IP address, and authentication is performed using provided credentials (plaintext password, NTLM hash, or Kerberos ticket).

A. Binding to the Domain Controller:

  • Rubeus binds to the LDAP service on the DC using either Simple Bind (with a username and password) or SASL Bind (with NTLM or Kerberos authentication).
  • A successful bind allows Rubeus to query user objects, groups, and domain security policies.

B. Executing LDAP Queries:

  • Rubeus sends three (3) LDAP queries to collect the information for the PAC.
Figure 4: Wireshark capture of LDAP traffic 

2. Mounting SYSVOL

Rubeus interacts with SYSVOL and IPC$ shares to extract Group Policy Objects (GPOs):    

  • Mounting Process:
    • Uses SMB (port 445) to authenticate to the DC and access SYSVOL.
    • Accesses:
      • \<DC>\IPC$ → Used for administrative access (initial connection)
      • \<DC>\SYSVOL → Stores domain-wide GPOs (superseding connection)
  • Extracted Policies from SYSVOL:
    • GptTmpl.inf: Stores password policy settings (e.g., MinimumPasswordLength).
    • Parameters: Stores Kerberos policy settings (e.g., MaxTicketAge).

3. Extracting user attributes

Once SYSVOL has been mounted and the relevant policies have been extracted, Rubeus then queries LDAP to retrieve user attributes from Active Directory. These attributes are used to construct the PAC, which is crucial for Kerberos authentication. The PAC includes information related to the user's identity, group memberships, permissions, and more, all of which are necessary for granting or denying access within the domain.

To construct the PAC, Rubeus retrieves specific LDAP attributes that represent the user's account information, their group memberships, and their security settings. 

4. Extracting password & Kerberos policies from SYSVOL

Rubeus extracts the root Active Directory (AD) domain’s Kerberos policies and password policies primarily from the GptTmpl.inf file, which is stored in the SYSVOL directory for Group Policy Objects (GPOs). This file contains key settings related to password policies (e.g., minimum password length, password expiration) and Kerberos ticket policies (e.g., ticket lifetime, renewal policies).

The SYSVOL directory is a shared folder that stores public domain information for Active Directory, including Group Policy settings and scripts. It's essential for distributing policy updates to domain controllers and ensures consistent application of these policies across all machines in the domain. Rubeus accesses this directory to retrieve domain-wide settings, which are critical for enforcing security policies and ensuring the correct configuration of authentication behaviors.

Rubeus extracts the password and Kerberos policies by reading Group Policy settings stored in SYSVOL:

\<DC>\SYSVOL\<domain>\Policies\{GUID}\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf

By reading the GptTmpl.inf file, Rubeus can retrieve the domain's configured password and Kerberos policies. These settings dictate crucial behaviors such as password complexity requirements, how often passwords must be changed, and how long Kerberos tickets remain valid. This information is vital for Kerberos authentication, where the PAC needs to be constructed with the appropriate policies in mind to ensure compliance and security.

These policy settings can have a direct impact on user authentication and authorization behavior, such as:

  • Ticket expiration times for Kerberos authentication, impacting how long a user can access resources without needing to re-authenticate.

  • Password expiration and complexity, enforcing strong passwords and regular changes to reduce the risk of password-based attacks.

The table below summarizes the most critical Kerberos and password policies that Rubeus extracts from the GptTmpl.inf file:


Policy Name

Extracted Value

Purpose

MinimumPasswordLength

7

Defines the minimum password length required for domain users to maintain secure passwords.

MaximumPasswordAge

42

Specifies the maximum number of days before a user is required to change their password.

LockoutBadCount

0

Determines how many failed login attempts will trigger an account lockout, ensuring protection against brute force attacks.

MaxTicketAge

10 hours

Specifies the maximum lifetime for a Kerberos TGT before it expires, controlling session duration.

MaxRenewAge

7 days

Defines the maximum age for which a TGT can be renewed. This prevents indefinite session extensions and ensures that credentials remain up-to-date.


Figure 5: Wireshark capture of retrieving password and Kerberos policies


5. Recutting the Diamond Ticket

The Kerberos TGT is essential for authenticating users in a domain and providing access to services without the need for repeated logins. By extracting Kerberos policies and LDAP attributes, Rubeus is capable of forging a valid TGT that mirrors the behavior of a legitimate Kerberos ticket. This forged ticket allows attackers or testers to bypass standard authentication mechanisms and escalate privileges within the domain.

For Golden and Silver tickets, the /ldap parameter has been an integral feature, enabling Rubeus to interact with LDAP-based resources and pull user-specific data, such as group memberships and user attributes. This LDAP functionality is a key part of making the forged tickets appear legitimate by ensuring that critical LDAP-related attributes in the PAC are populated correctly.

However, when working with Diamond tickets in Rubeus, this same functionality was originally missing as we only made a minimal viable PoC showcasing the technique. As a result, the LDAP-related attributes within the PAC were often left blank or incorrect (see Figure 2), diminishing the authenticity of the forged Diamond ticket. Diamond tickets were not fully leveraging the available LDAP attributes, making them less reliable and harder to use in sophisticated attacks or tests.


Adding LDAP integration to Diamond Tickets

To address this issue, we made the decision to rework Rubeus’ ForgeTicket.cs and Diamond.cs to support the /ldap parameter for Diamond tickets. This enhancement ensures that the LDAP attributes are correctly extracted and included in the PAC when creating a Diamond ticket. By doing so, the resulting PAC now reflects the actual user context, making the forged Diamond ticket more genuine and trustworthy.

With our modified code, let’s now supply /ldap to diamond as well as a supplied /ldapuser and /ldappassword, which can all be combined into /ldap later 🙂

New Rubeus Diamond Ticket command:

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$


Figure 6: Output showcasing Rubeus’ Diamond action with new output 
when /ldap, /ldapuser and /ldappassword are supplied

The complete transformation: Every field corrected

Let's perform a detailed comparison of a decrypted diamond ticket without /ldap against our new 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-WRKSTN\Odin's Vault

13

      HomeDirectory        :

13

      HomeDirectory        : \\asgard-wrkstn\users\thor

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                  : thor@marvel.local

35

      UPN                  : thor@marvel.local

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

The /ldap enhancement transforms nearly every field in the PAC with authentic data:

Critical Authentication Fields

  • LogonTime: Now reflects actual user's last logon instead of current time
  • LogonCount: Real count (41) vs artificial (460) prevents statistical anomalies
  • LogonServer: Populates with actual authentication server

Password Policy Compliance

  • PasswordLastSet: Current date instead of 2023
  • PasswordCanChange: Properly calculated based on domain policy
  • PasswordMustChange: Now populated, enforcing maximum password age

User Identity Accuracy

  • FullName: "Thor Odenson" instead of "Loki"
  • ProfilePath: Valid roaming profile location
  • HomeDirectory: Actual user's home directory
  • HomeDirectoryDrive: Correct drive mapping

Security Groups & Permissions

  • Groups: Real memberships (512,525,513) instead of default IOCs (520,512,513,519,518)
  • UserFlags: Clean (0) instead of suspicious EXTRA_SIDS
  • ExtraSIDs: Removed fake SIDs (S-1-5-21-0-0-0-497,S-1-18-1)

Account Control

  • UserAccountControl: (16400) NORMAL_ACCOUNT, NOT_DELEGATED instead of suspicious DONT_EXPIRE_PASSWORD

OPSEC improvements achieved

With LDAP integration, we create a complete, authentic user context that includes:

  • Valid session timing that aligns with the user's actual activity

  • Accurate identity attributes matching AD records

  • Real group memberships without IOC patterns

  • Proper password policy enforcement dates

  • Legitimate account control flags

  • No suspicious extra SIDs or artificial attributes

  • Complete profile and directory mappings

This comprehensive field accuracy transforms the Diamond Ticket from a detectable forgery into an authentic-looking ticket that can pass even strict PAC validation checks.


Adding /OPSEC integration to Diamond Tickets

We've also implemented support for the /opsec flag in Diamond tickets to ensure the network traffic generated during ticket creation matches genuine Windows Kerberos behavior. When enabled, the AS-REQ/AS-REP exchange follows Windows' standard two-step authentication pattern: first sending an AS-REQ without pre-authentication, then responding to the KDC's PREAUTH_REQUIRED error with a properly formatted pre-authenticated request. This makes the wire traffic during Diamond ticket generation indistinguishable from legitimate domain-joined Windows clients. The flag enforces AES256-only encryption and proper KDCOptions, eliminating network-level indicators that could distinguish forged tickets from authentic Kerberos authentication flows.

Thank you to Joe Dibley (@JoeDibley2) for his help in implementing the /opsec function into Diamond.

Figure 7: Rubeus diamond ticket action with new /opsec argument


Figure 8: Wireshark capture showcasing a more genuine-looking AS-REQ was sent

With both /ldap and /opsec in place, your Diamond tickets don’t just blend in. They stand up to close inspection with all the clarity, cut, and grade of the real thing and match legitimate Kerberos tickets even on the wire or in the PAC.

Service ticket functionality

Just as recutting a diamond enhances its clarity and value, we’ve refined the Diamond Ticket technique by extending it to service tickets through modifications to Rubeus. Originally limited to TGTs, this advancement calls into question the continued relevance of Silver Tickets, which lack the visible legitimacy of a genuine authentication flow and are easier to detect in modern environments. In doing so, we blur the lines between stealth and legitimacy making old-school Silver Tickets look rough and unrefined by comparison.

You might remember this line from our original blog post:

Upon concluding our research and creating a POC weaponization, Elad Shamir sent us Tim Medin’s DerbyCon 2014 talk, ‘Attacking Microsoft Kerberos: Kicking the Guard Dog of Hades.’ In his talk, Tim discusses the same technique—but in the context of Service Tickets.

This was back in July 2022, when we first released the initial Diamond Ticket POC.

Now that we’ve had more time to dig deeper, we figured there’s no better moment to revisit the concept and apply it directly to Service Tickets. 


What’s new

Our update allows you to apply the Diamond forgery technique to service tickets, which are normally issued based on a legitimate TGT. With this change, you can now forge a TGS directly using:

  • A legitimate or forged Kerberos ticket blob
  • The AES service key (i.e., the key used to encrypt the service ticket)

This enhancement enables the direct creation of forged service tickets using either a valid or previously forged TGT. The result is greater flexibility for Kerberos ticket manipulation, especially in scenarios requiring heightened operational discretion.

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>


Figure 9: Terminal output showcasing using a ticket and /servicekey supplied to Diamond



Figure 10: Final POC of Diamond’s ability to forge a Service Ticket


Conclusion

Through this journey of re-cutting the Diamond Ticket, we've transformed what was once a rough proof of concept into a polished technique worthy of serious consideration in modern Kerberos attack chains. By adding LDAP integration, implementing proper OPSEC controls, and extending functionality to service tickets, we've addressed the fundamental limitations that previously relegated Diamond Tickets to the realm of theoretical curiosities.

The enhancements we've implemented fundamentally change the risk calculus for both attackers and defenders. Consider how Diamond Tickets now compare to traditional ticket forgery techniques:

Kerberos ticket forgery comparison table

Technique

Ticket Type Forged

Requires DC Traffic?

Authentication Flow

Detection Risk

Golden

TGT

❌ No

❌ None (no AS-REQ or TGS-REQ)

High*

*see Charlie and Andrew’s presentation: "I've Got a Golden Twinkle In My Eye" for SANS Pentest and Hackfest Summit (14th November 2022)

Silver

TGS

❌ No

❌ None (no TGS-REQ)

Medium-High*

*see Charlie’s presentation: "I’ve Got a Forged Ticket In My Eye"

Diamond

TGT or TGS

✅ Yes (AS/TGS)

✅ Legit AS-REQ/TGS-REQ

Medium-High (doesn’t use LSASS to communicate from client to DC 🙁)

Sapphire

TGS via U2U

✅ Yes (TGS + TGT)

⚠️ Partial (TGS-REQ w/ ENC-TKT-IN-SKEY, U2U flow)

High (ENC-TKT-IN-SKEY flag + U2U service tickets always end in 8 or C), rare flow)

While Diamond Tickets still carry detection risk (especially since they bypass LSASS for client-to-DC communication), they offer a compelling middle ground. Golden and Silver tickets just appear out of nowhere with no authentication flow. Diamond Tickets? They actually go through real AS-REQ/AS-REP or TGS-REQ/TGS-REP exchanges. Combine this legitimate network traffic with our LDAP-populated PAC data, and you've got a ticket that can pass inspection at multiple levels.


The death of Silver Tickets?

Now that we've extended Diamond functionality to service tickets, we have to ask: are traditional Silver Tickets dead? Why forge a service ticket that appears from thin air when you can create one with actual authentication behind it? Silver Tickets still have their place when you absolutely can't touch a DC. But if you're an operator who values stealth over convenience, Diamond-forged service tickets are the natural evolution.

Implications for defenders

For blue teams, these improvements highlight why comprehensive Kerberos monitoring matters more than ever. Yes, you can still detect forged tickets, but we've definitely raised the bar. Defenders should focus on:

  • Looking at authentication patterns, not just PAC contents
  • Watching for weird client-to-DC communication patterns

  • Building SIEM rules that connect multiple indicators

  • Remembering that even "normal-looking" authentication might be hiding forged tickets

Looking forward

The polished Diamond Ticket technique shows that Kerberos attacks keep evolving. As defenders build better detection, attackers adapt to blend in more effectively. This constant back-and-forth pushes both sides to improve. At the end of the day, the enhanced Diamond Ticket proves that the most dangerous attacks are often the ones that look the most legitimate. They blend in so well that telling fake from real becomes a true test of defensive skill.

We have added these new features to Rubeus in this pull request.


Thanks to Joe Dibley (@JoeDibley2) for his help with implementing the /opsec function into Diamond, Elad Shamir (@elad_shamir) and Ceri Coburn (@_EthicalChaos_) for their help in reviewing this post, and to the countless folks at Huntress I subjected to reading and reviewing this blog post.

Categories
Share

Sign Up for Huntress Updates

Get insider access to Huntress tradecraft, killer events, and the freshest blog updates.

By submitting this form, you accept our Terms of Service & Privacy Policy
Oops! Something went wrong while submitting the form.
Huntress at work