Root-Me — Kerberos Authentication
Flag format: RM{userPrincipalName:password} The userPrincipalName must be written in lowercase.
TL;DR
The pcap contains a Kerberos authentication exchange for the user william.dupond in the realm CATCORP.LOCAL. The encrypted timestamp inside the AS-REQ pre-authentication data (PA-ENC-TIMESTAMP) is encrypted with a key derived from the user’s password. Extract that cipher, format it as a $krb5pa$18$... hash, and crack it with hashcat mode 19900.
Final flag: RM{[email protected]:kittycat12}
Background: Kerberos in 30 Seconds
Kerberos has 4 message types that show up in pcaps:
| Message | Purpose | What’s encrypted with the user’s key |
|---|---|---|
| AS-REQ (msg type 10) | “Hi KDC, I’d like a TGT” | The PA-ENC-TIMESTAMP if pre-auth is enabled — crackable |
| AS-REP (msg type 11) | KDC returns the TGT | Encrypted with user’s key only if pre-auth is disabled (AS-REP roasting) |
| TGS-REQ (msg type 12) | “Hi KDC, give me a service ticket” | Encrypted with TGT session key |
| TGS-REP (msg type 13) | KDC returns service ticket | Encrypted with the service account’s key (Kerberoasting) |
Step 1: Inventory the Pcap
Open the file in Wireshark with the filter kerberos, or use tshark to list message types and encryption types:
# What Kerberos messages exist?
tshark -r kerberos_auth.pcapng -Y "kerberos" \
-T fields -e kerberos.msg_type | sort | uniq -c
# What encryption types are used?
tshark -r kerberos_auth.pcapng -Y "kerberos" \
-T fields -e kerberos.msg_type -e kerberos.etypeResult:
2 10 (AS-REQ)
1 11 (AS-REP)
1 12,14 (TGS-REQ + AP-REQ)
1 13 (TGS-REP)
1 14 (AP-REP)
1 30 (KRB-ERROR)Almost everything uses etype 18 = AES256-CTS-HMAC-SHA1-96.
KRB-ERROR demanding pre-auth. The client retries with a PA-ENC-TIMESTAMP in the second AS-REQ. That second one is our target.Step 2: A Wrong Turn (Worth Documenting)
My first instinct was Kerberoasting the TGS-REP. I extracted the cipher from message type 13:
tshark -r kerberos_auth.pcapng -Y "kerberos.msg_type == 13" \
-T fields \
-e kerberos.CNameString \
-e kerberos.realm \
-e kerberos.SNameString \
-e kerberos.cipherOutput: william.dupond requesting cifs/DC01.catcorp.local. I formatted it as $krb5tgs$18$... and ran hashcat mode 19700 with rockyou. After 20+ minutes — nothing.
cifs/DC01.catcorp.local is encrypted with the DC01$ machine account’s key. Machine account passwords are random ~120-character strings auto-rotated by the DC. Uncrackable with any wordlist.Rule of thumb: Service tickets for SPNs that look like host/..., cifs/..., ldap/... on a domain controller are machine accounts. Skip them. Look for SPNs registered to user service accounts (e.g. MSSQLSvc/..., HTTP/...).
Step 3: The Right Target - AS-REQ PA-ENC-TIMESTAMP
The interesting packet is AS-REQ #51 (the second AS-REQ), which contains PA-DATA → PA-ENC-TIMESTAMP. This timestamp is encrypted with a key derived from the user’s password — so cracking it = cracking the password.
Extract via Wireshark (GUI)
- Filter:
kerberos.msg_type == 10 - Pick the AS-REQ that has padata (the second one)
- Expand:
Kerberos → as-req → padata → PA-ENC-TIMESTAMP → cipher - Right-click → Copy → Value
Extract via tshark (CLI)
tshark -r kerberos_auth.pcapng \
-Y "kerberos.msg_type == 10 && kerberos.padata_type == 2" \
-T fields \
-e kerberos.CNameString \
-e kerberos.realm \
-e kerberos.cipherExtracted values:
| Field | Value |
|---|---|
| Cname | william.dupond |
| Realm | CATCORP.LOCAL |
| Etype | 18 (AES256) |
| Cipher | fc8bbe22b2c967b222ed73dd7616ea71b2ae0c1b0c3688bfff7fecffdebd4054471350cb6e36d3b55ba3420be6c0210b2d978d3f51d1eb4f |
Step 4: Format the Hash for Hashcat
From hashcat --help, Kerberos etype 18 has three modes:
19700 | Kerberos 5, etype 18, TGS-REP | Kerberoasting
19900 | Kerberos 5, etype 18, Pre-Auth | ← what we want
28900 | Kerberos 5, etype 18, DB | NTDS dumpFormat for mode 19900:
$krb5pa$18$<username>$<REALM>$<cipher_hex>Build the hash file:
echo '$krb5pa$18$william.dupond$CATCORP.LOCAL$fc8bbe22b2c967b222ed73dd7616ea71b2ae0c1b0c3688bfff7fecffdebd4054471350cb6e36d3b55ba3420be6c0210b2d978d3f51d1eb4f' > preauth.txtStep 5 — Crack with Hashcat
hashcat -m 19900 -a 0 preauth.txt /usr/share/wordlists/rockyou.txt| Flag | Meaning |
|---|---|
-m 19900 | Hash mode: Kerberos 5 etype 18 Pre-Auth |
-a 0 | Attack mode: dictionary |
preauth.txt | The hash file |
rockyou.txt | Wordlist |
-w 1 to reduce workload, or run on a VPS.After cracking:
hashcat -m 19900 preauth.txt --showOutput:
$krb5pa$18$william.dupond$CATCORP.LOCAL$fc8bbe22b2c967b222ed73dd7616ea71b2ae0c1b0c3688bfff7fecffdebd4054471350cb6e36d3b55ba3420be6c0210b2d978d3f51d1eb4f:kittycat12The cracked potfile lives at:
~/.local/share/hashcat/hashcat.potfileStep 6: Build the Flag
The flag format is RM{userPrincipalName:password}. A UPN is user@domain (not just the username), all lowercase per the challenge instructions:
- userPrincipalName:
[email protected] - password:
kittycat12
RM{[email protected]:kittycat12}RM{william.dupond:kittycat12} — rejected. A UPN includes the realm. Always check whether the challenge wants the SAM account name (william.dupond), the UPN ([email protected]), or the DN (CN=William Dupond,OU=Users,DC=catcorp,DC=local).Tools Used
- Wireshark + tshark — pcap analysis, Kerberos packet decoding
- hashcat v6.2.6 — offline password cracking (mode 19900)
- rockyou.txt — standard CTF wordlist (
/usr/share/wordlists/rockyou.txt)
Lessons Learned
- Always inventory the pcap first. Use
tsharkto count message types and check etypes before picking an attack path. - PA-ENC-TIMESTAMP > TGS-REP for user passwords. Pre-auth data targets the user’s key directly. TGS-REPs target service account keys, which for machine accounts (DC$, computer accounts) are uncrackable.
- Hashcat Kerberos mode cheat sheet:
13100→ TGS-REP RC4 (etype 23)18200→ AS-REP RC4 (etype 23) — AS-REP roasting19600→ TGS-REP AES128 (etype 17)19700→ TGS-REP AES256 (etype 18)19800→ AS-REQ Pre-Auth AES128 (etype 17)19900→ AS-REQ Pre-Auth AES256 (etype 18)
- Read the flag format carefully. UPN ≠ username.
- Misdirection is real. The challenge intro says “WOOF WOOF WOOF” but the company is Cat Corporation — the password was
kittycat12. Don’t bias your wordlist before cracking.
Reproducible One-Liner (for future me)
# 1. Extract the AS-REQ pre-auth cipher
CIPHER=$(tshark -r kerberos_auth.pcapng \
-Y "kerberos.msg_type == 10 && kerberos.padata_type == 2" \
-T fields -e kerberos.cipher | head -n1)
# 2. Build the hash
echo "\$krb5pa\$18\$william.dupond\$CATCORP.LOCAL\$${CIPHER}" > preauth.txt
# 3. Crack
hashcat -m 19900 -a 0 preauth.txt /usr/share/wordlists/rockyou.txt
# 4. Show result
hashcat -m 19900 preauth.txt --showReferences
- Hack’n’Do — Kerberos deep-dive
- Hashcat example hashes
- Impacket — for live AD pentesting (
GetNPUsers.py,GetUserSPNs.py)

