Ledger — TryHackMe Writeup
High-speed port scanning identified a Windows Server 2019 Domain Controller (LABYRINTH.THM.LOCAL). Verified Kerberos clock skew within acceptable limits (<1s).
Enumerated anonymous LDAP subtree reading on port 389. Filtered 27,900 lines of directory records to recover a plaintext onboarding password in user descriptions, gaining valid credentials for SUSANNA_MCKNIGHT.
Parsed domain objects, ACLs, and AD CS certificate templates using pharaohound. Identified vulnerable ESC1 templates (ServerAuth) alongside a stealthy MAQ -> RBCD delegation vector.
Enrolled a valid administrator certificate via ESC1 template ServerAuth, but KDC PKINIT authentication was refused. Pivoted to the second path: exploited GUESTS GenericWrite on the DC computer object via RBCD.
Injected the forged Administrator service ticket into KRB5CCNAME to connect directly to the C$ administrative share via Kerberos, capturing both user.txt and root.txt.
Challenge Overview
Ledger is a medium-rated Windows Active Directory machine on TryHackMe that reflects two fundamental realities of real-world enterprise infrastructure:
- ▹Human Operational Fatigue: System administrators routinely store onboarding notes, temp passwords, and reset reminders directly inside LDAP user attributes (
description,info,comment), treating directory services as personal scratchpads. - ▹Dual Escalation Architecture: The room author deliberately designed two viable privilege escalation avenues into the domain:
- ▹Active Directory Certificate Services (AD CS) ESC1: An enterprise CA template configured with
ENROLLEE_SUPPLIES_SUBJECTandClient AuthenticationExtended Key Usage (EKU). - ▹Resource-Based Constrained Delegation (RBCD): A subtle Access Control List (ACL) misconfiguration where the built-in
GUESTSgroup possessesGenericWriterights over the Domain Controller's own computer object (LABYRINTH$).
- ▹Active Directory Certificate Services (AD CS) ESC1: An enterprise CA template configured with
While the ESC1 certificate can be requested without issue, environmental PKINIT friction (KDC_ERR_PADATA_TYPE_NOSUPP) blocks certificate-to-TGT exchange on modern tooling. This makes the RBCD delegation road through the guest account the most elegant, robust, and reliable path to full Domain Admin compromise.
1. Reconnaissance & Environment Baseline
::1.1 Full TCP Port Scan
We initiate the assessment with an aggressive, all-ports TCP scan to establish the listening perimeter:
::1.2 Service Fingerprinting & Architecture
With the open ports identified, we execute a deep script and service version detection scan (-sC -sV):
::1.3 Exposed Service Profile
| Port | Protocol | Service | Architectural Significance |
|---|---|---|---|
| 53 | TCP/UDP | DNS | Active Directory Domain Name System |
| 88 | TCP/UDP | Kerberos | KDC authentication server (thm.local) |
| 135 | TCP | MSRPC | Endpoint Mapper & DCOM services |
| 139 / 445 | TCP | NetBIOS / SMB | File sharing, IPC pipe access, and administrative shares |
| 389 / 636 | TCP | LDAP / LDAPS | Directory queries, authentication binds, schema access |
| 3268 / 3269 | TCP | Global Catalog | Multi-domain AD search partitions |
| 3389 | TCP | RDP | Remote Desktop Protocol administrative endpoint |
| 47001 | TCP | WinRM | Windows Remote Management service listener |
::1.4 Host Mapping & Kerberos Clock Sync
Kerberos is strictly timestamp-sensitive. The Kerberos Ticket Granting protocol enforces an RFC 4120 maximum clock skew tolerance of 5 minutes (300 seconds) between the client and the KDC. If your workstation clock drifts past this threshold, all AS-REQ and TGS-REQ ticket requests fail instantly with KRB_AP_ERR_SKEW.
We map the hostname and verify clock synchronization:
The offset is less than half a second—well within the acceptable skew window.
Whenever testing Active Directory environments, always add both the fully qualified domain name (labyrinth.thm.local) and the NetBIOS name (LABYRINTH) to /etc/hosts. Kerberos SPN resolution requires exact hostname matching; connecting via raw IP addresses forces NTLM fallback and will break ticket-based attacks.
2. Null Sessions & Anonymous LDAP Intelligence
::2.1 Testing Guest SMB Authentication
Active Directory domain controllers frequently maintain the built-in guest account with an empty password enabled by default for legacy interoperability. We verify null and guest authentication via netexec:
The guest account authenticates cleanly, confirming the identity is recognized by the Domain Controller. However, file shares are locked down.
::2.2 Anonymous LDAP Subtree Dump
Next, we probe the directory service on port 389. While Windows Server 2003 and earlier supported anonymous LDAP binds out of the box, later versions require explicit administrative misconfiguration (dsHeuristics attribute seventh character set to 2).
We execute an unauthenticated search query against the domain root partition:
The Domain Controller permitted a full anonymous directory subtree export, returning 27,914 lines of Active Directory objects (users, groups, organizational units, computers, and service descriptors).
::2.3 Hunting Credential Leaks in User Attributes
Rather than manually scrolling through thousands of lines, we leverage regex filters across standard attribute fields where administrators frequently leave notes (description, info, comment, userPassword):
A plaintext password stands out: CHANGEME2023!.
We trace this specific attribute back to the containing user objects in the directory dump:
Two domain accounts—IVY_WILLIS and SUSANNA_MCKNIGHT—share the initial onboarding password CHANGEME2023!.
::2.4 Credential Validation & Foothold Verification
We test the discovered credentials across SMB using netexec:
Both accounts are active with valid credentials. We have established our initial authenticated foothold in the domain.
3. Domain Graph & Attack Path Mapping (pharaohound)
::3.1 Automated In-Memory Graph Collection
With valid domain credentials for SUSANNA_MCKNIGHT, we map out the domain hierarchy, group memberships, ACL delegations, and certificate infrastructure.
Instead of deploying the legacy bloodhound-python script and spinning up a resource-heavy Neo4j graph database, we deploy pharaohound—our dedicated high-performance Active Directory collection and analysis engine. It pulls LDAP objects directly into memory and executes 30+ vulnerability analyzers locally:
::3.2 Foothold Privilege Audit
pharaohound cross-references our compromised accounts against sensitive administrative groups:
SUSANNA_MCKNIGHT is uniquely valuable: she possesses membership in both Remote Desktop Users (granting direct RDP access on port 3389) and Remote Management Users (granting WinRM interactive access on port 47001).
We also note the Machine Account Quota:
Because ms-DS-MachineAccountQuota is set to 10, any authenticated domain user can create up to 10 computer objects.
4. Road One: The AD CS ESC1 Template
::4.1 Understanding ESC1 Vulnerabilities
Active Directory Certificate Services (AD CS) misconfigurations are catalogued as ESC classes (defined in SpecterOps' seminal paper Certified Pre-Owned).
The ESC1 attack vector represents the most straightforward certificate abuse pattern. A certificate template is vulnerable to ESC1 if it satisfies four simultaneous conditions:
- ▹Enrollment Permissions: Low-privileged users (
Domain Users,Authenticated Users) possess enrollment rights. - ▹Manager Approval Disabled: Certificates are issued immediately upon request without administrative sign-off.
- ▹Authentication EKU: The template includes Extended Key Usages for domain authentication (
Client Authentication,Smart Card Logon,PKINIT, orAny Purpose). - ▹Subject Alternative Name (SAN) Control: The flag
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECTis enabled, permitting the applicant to specify an arbitrary Subject Alternative Name (SAN), such as a Domain Admin's User Principal Name (UPN).
::4.2 Enumerating Certificate Templates with Certipy
We scan the Enterprise CA thm-LABYRINTH-CA using certipy-ad:
The template ServerAuth meets every ESC1 criterion.
::4.3 Minting a Domain Admin Certificate
We request a certificate from thm-LABYRINTH-CA based on the ServerAuth template, supplying the User Principal Name of Domain Admin BEVERLY_FARRELL:
The certificate requests and issues seamlessly. We receive beverly_farrell.pfx containing the private key and signed certificate.
::4.4 The PKINIT Roadblock (Why We Pivot)
Under standard AD CS exploitation, the operator presents the .pfx certificate to the KDC via Kerberos PKINIT extension (AS-REQ with padata-type 16: PA-PK-AS-REQ) to obtain a Kerberos Ticket Granting Ticket (TGT) and extract the user's NTLM hash:
We test multiple administrative UPNs (ADMINISTRATOR@thm.local, BRADLEY_ORTIZ@thm.local), yet the KDC systematically returns:
The Technical Cause: KDC_ERR_PADATA_TYPE_NOSUPP indicates that the Domain Controller's KDC service does not have a valid Domain Controller certificate installed in its Personal store (MY), or lacks the required Smartcard/PKINIT pre-authentication extensions. Without a DC certificate to anchor mutual authentication, the KDC cannot validate the client's signature or return an encrypted AS-REP.
Rather than wasting hours troubleshooting a lab-environment KDC limitation or attempting to push a DC certificate, a professional penetration tester immediately shifts focus to the alternative vector surfaced during initial mapping: Resource-Based Constrained Delegation (RBCD).
5. Road Two: Exploiting Resource-Based Constrained Delegation (RBCD)
::5.1 The Mechanics of RBCD & S4U Extensions
Kerberos delegation allows a service account to impersonate users to access back-end resources on their behalf.
- ▹Traditional Constrained Delegation: Configured on the calling service account via
msDS-AllowedToDelegateTo. Configuring it requires the highly restrictedSeEnableDelegationPrivilegeuser right (typically reserved for Domain Admins). - ▹Resource-Based Constrained Delegation (RBCD): Introduced in Windows Server 2012, RBCD inverts the security model. The delegation authority is configured on the target resource via the attribute
msDS-AllowedToActOnBehalfOfOtherIdentity.
The attribute msDS-AllowedToActOnBehalfOfOtherIdentity contains a binary Security Descriptor (DACL). Any principal that holds write permissions (GenericWrite, GenericAll, or WriteProperty) over the target computer object can edit this DACL to allow any machine account under the attacker's control to impersonate any domain user (including Domain Admins) to services hosted on that computer.
::5.2 Uncovering the Golden Misconfiguration
During our pharaohound audit, analyzer Chain #6 highlighted a rare permission grant on the domain controller computer object LABYRINTH$:
The built-in GUESTS group holds GenericWrite permissions directly over the Domain Controller's own computer object (LABYRINTH$).
Because the guest account is a member of GUESTS, and can authenticate with an empty password, we can perform this modification without needing elevated privileges.
::5.3 Step 1: Provisioning a Machine Account (MAQ Abuse)
Since ms-DS-MachineAccountQuota is 10, we use impacket-addcomputer with SUSANNA_MCKNIGHT's credentials to provision a new machine account named ATTACKERSYSTEM$:
We now possess the credentials for a computer account in the domain: ATTACKERSYSTEM$ / Password123!.
::5.4 Step 2: Modifying msDS-AllowedToActOnBehalfOfOtherIdentity
We now write ATTACKERSYSTEM$'s Security Identifier (SID) into LABYRINTH$'s msDS-AllowedToActOnBehalfOfOtherIdentity attribute using impacket-rbcd.
Because the tool rbcd.py can encounter string parsing issues when passed a literal empty password (-p ''), we provide the well-known NTLM hash of an empty password:
We execute the delegation write authenticated as thm.local\guest:
The write succeeds. ATTACKERSYSTEM$ is now authorized to act on behalf of any user against LABYRINTH$.
::5.5 Step 3: Forging the Administrator CIFS Service Ticket (S4U)
With RBCD established, we execute the Kerberos Service-for-User (S4U) ticket exchange using impacket-getST:
- ▹S4U2Self:
ATTACKERSYSTEM$requests a Kerberos TGS to itself on behalf ofAdministrator. Because machine accounts possess protocol transition capability, the KDC issues a forwardable service ticket namingAdministrator. - ▹S4U2Proxy:
ATTACKERSYSTEM$sends the ticket back to the KDC requesting an authorization ticket for the servicecifs/LABYRINTH.THM.LOCAL. The KDC checksLABYRINTH$'smsDS-AllowedToActOnBehalfOfOtherIdentity, seesATTACKERSYSTEM$is listed, and returns an official ticket forcifs/LABYRINTH.THM.LOCALimpersonatingAdministrator.
We have generated an authentic, cryptographic Kerberos service ticket (.ccache) granting Administrator privileges to CIFS/SMB on the Domain Controller.
::
We configure our shell environment to use the forged .ccache ticket via the standard KRB5CCNAME environment variable, then connect to SMB using Kerberos authentication (-k -no-pass):
The forged ticket grants full administrative access over C$, allowing us to pull both flags directly from the file system.
6. Flag Capture
::6.1 User Flag
::6.2 Root Flag
7. References
::

Red Team Consultant · Penetration Tester · Bug Bounty Hunter
Offensive security professional with 250+ vulnerabilities reported across 50+ organizations including Atlassian, Vimeo, and AT&T. Sharing research, tools, and field notes.