This is a Windows 2019 Server running as a domain controller with several overly permissive misconfigurations, that we enumerate with the new BloodHound CE tool, and a vulnerable AD CS template. First we upgrade our rig: we install the new Bloodhound CE and update our data collector tool so it is compatible with the new BloodHound version. Once all is running, we enumerate the Active Directory and discover overly permissive ACEs that enable a shadow credentials attack on one account. As a result of the attack we obtain an NT hash and gain the user flag.
Regarding escalation, we enumerate AD CS templates and find one vulnerable to ESC9. This is abused to generate an administrator certificate and obtain the administrator NT hash.
KEYWORDS
BloodHound CE, BloodHound-CE-Python, Impacket, owneredit.py, dacledit.py, shadow credentials attack, pyWhisker, bloodyAD, Active Directory Certificate Services (AD CS), ESC9.
This looks like an excellent opportunity to test BloodHound CE, the new version of the legendary graphical Active Directory enumeration tool Bloodhound. It seems the original release is now called BloodHound Legacy, and there is another BloodHound Enterprise version.
Let's follow instructions to install BloodHound CE. The process can be done with Docker Compose, and looks simplified with regards how was done in the classic release.
Download the composer file and run it.
> curl -L https://ghst.ly/getbhce > .\docker-compose.yml
> docker compose up
When finished, access BHCE GUI via http://localhost:8080/ui/login. Username is admin, and the password is provided in the Docker Compose output. Take note of it as it needs to be reset during first login.
Once inside the tool, we are presented an empty database.
We need a collector to gather data to ingest. We do not have a shell in the host so we cannot use SharpHound.exe. We will have to collect the data remotely with BloodHound.py. However, it seems collectors for BloodHound Legacy do not work anymore with BHCE, so we will have to update our toolbox.
Just take the JSON files and ingest the data in BHCE. Click on Settings → Administration → Upload Files.
Now we can start exploring the domain. The built-in queries are available in Explore → Cypher → Open. For example, let's list all domain admins.
To enumerate judith.mader, click on "Search" and type the username, the user icon is displayed. Then click on "Outbound Object Control" to list which objects the user judith.mader can control or manipulate.
We see she has WriteOwner rights over the management@certified.htb group, meaning she has permissions to change the owner of this group.
USER
By clicking on the WriteOwner edge, the application itself suggests an exploitation path.
Basically, the abuse path is:
Leverage the WriteOwner right to set judith.mader as the group owner.
Grant judith.mader permission to add any user to the group.
Add judith.mader to the group.
Let's start by enumerating the management@certified.htb group with ldapsearch
owneredit.py allows to work with either sAMAccountName or distinguishedName to identify the target and new owner accounts. We can take any of these from BHCE.
Next step would be to edit the group DACL adding a new ACE that grants judith.mader permission to add new members. It is done with Impacket's dacledit.py
We have taken ownership of management@certified.htb group and added ourselves as a member. We mark this as "Owned" in BHCE and continue enumerating from there.
The group has another member, the user management_svc, over which we have GenericWrite permissions as group owners. Again, by clicking on the edge, the tool suggests possible ways to abuse this.
In summary, in a shadow credentials attack, the attacker populates the msDS-KeyCredentialLink attribute on the targeted account, for which GenericAll or GenericWrite is needed. Then the attacker requests a PFX certificate for this target user, that is used to authenticate and request either a TGT or the target's NT hash. Both of them allow to get a shell under the context of the target account.
Let's start by populating the attribute with pywhisker.py. First we check current status of the attribute.
The tool generates a PFX file containing a certificate and a private, and suggests we can use with PKINITtools.
The procedure explaining how to request a TGT ticket with gettgtpkinit.py and a PEM certificate is explained at pyWhisker GitHub repository. In our case we have a PFX certificate, but only a minor modification to the command is needed.
Before using the tool PKINITtools, it is needed to manually install a dependency Minikerberos.
Now let's request a TGT ticket for managemenet_svc using the PFX certificate and gettgtpkinit.py. As always when requesting TGT tickets, remember to synchronize clock to avoid skew errors.
Start from the management_svc shell and take the opportunity to enumerate the system.
Get-ComputerInfo
WindowsBuildLabEx : 17763.1.amd64fre.rs5_release.180914-1434
WindowsCurrentVersion : 6.3
WindowsProductName : Windows Server 2019 Standard
WindowsVersion : 1809
Enumerate the user in BHCE, we see it has GenericAll over another user ca_operator. Clicking over the edge the application suggest an abuse path, including a force password change.
The new credential does not work for Evil-WinRM, but we can check the password has been successfully changed via SMB.
> smbmap -H certified.htb -P 445 -u ca_operator -p password
[+] IP: certified.htb:445 Name: unknown
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
IPC$ READ ONLY Remote IPC
NETLOGON READ ONLY Logon server share
SYSVOL READ ONLY Logon server share
The username ca_operator strongly suggests AD CS is running on the machine. Since we cannot have a local shell as ca_operator we cannot enumerate templates with certify.exe, but we can do it remotely with Certipy as we did in Authority.
Which reports there is a template CertifiedAuthentication vulnerable to ESC9.
These ESC codes are given following the terminology used in the original AD CS abuse whitepaper that initially described 8 different domain escalation attacks, and were later expanded by subsequent researches.
Let's abuse ESC9 following the researcher's step-by-step. We comply with the requirements for this attack since management_svc has has GenericWrite over ca_operator, who in turn is allowed to enroll in the certificate template ESC9, that contains the CT_FLAG_NO_SECURITY_EXTENSION flag in the msPKI-Enrollment-Flag value.
Following the guide, first we change ca_operator UPN to "Administrator", using management_svc credentials (in this case management_svc hash is used for authentication).
Finally, we try to authenticate with the certificate so we receive the NT hash of the Administrator. You will need to add domain since there is no domain specified in the certificate.
Also, we have to deal with skew errors, stopping the timedatectl auto synchronization, and synchronizing manually with rdate
> sudo timedatectl set-ntp off
> sudo rdate -n 10.10.11.41
Sat Jan 11 04:36:07 GMT 2025
Now, we can run certipy to request a TGT and retrieve the Administrator NT hash.