Why Practise Password Cracking?
The goal of this lab exercise was to understand, from an attacker's perspective, how password hashes are cracked when a credential database is exposed. By practising offensive techniques in a controlled environment, I could identify exactly which hashing algorithms and password policies are dangerously weak — and articulate concrete defensive controls for organisations to adopt.
All cracking was performed on intentionally weak, self-generated test hashes in a local, isolated lab. No real user data or live systems were involved at any point.
Hash Types & Relative Cracking Times
Four hash algorithms were tested with identical password sets to directly compare their resistance to offline cracking attacks on consumer hardware (single GPU, RTX 3060).
Three Attack Modes Practised
1 — Dictionary Attack (Attack Mode 0)
Used the rockyou.txt wordlist (14.3 million entries) against a set of MD5 and NTLM hashes. The majority of "realistic" weak passwords in the test set were recovered within the first pass.
# Dictionary attack — MD5 hashes, rockyou wordlist hashcat -m 0 -a 0 hashes_md5.txt /usr/share/wordlists/rockyou.txt # Dictionary attack — NTLM hashes hashcat -m 1000 -a 0 hashes_ntlm.txt /usr/share/wordlists/rockyou.txt \ --status --status-timer=10 Session.........: hashcat Status..........: Running Hash.Mode.......: 1000 (NTLM) Guess.Base......: File (/usr/share/wordlists/rockyou.txt) Speed.#1........: 4823.4 MH/s (14.21ms) Progress........: 14344385/14344385 (100.00%) Recovered.......: 18/20 (90.00%) Digests
2 — Brute Force / Mask Attack (Attack Mode 3)
Used Hashcat mask syntax to brute-force all 6-character passwords matching a lowercase+digit pattern. Demonstrated how short, predictable character-set passwords fall rapidly.
# Mask attack — all 6-char lowercase+digit combinations hashcat -m 0 -a 3 hashes_md5.txt ?l?l?l?d?d?d # Increment mode — try lengths 4 through 8 hashcat -m 0 -a 3 hashes_md5.txt ?a?a?a?a --increment \ --increment-min=4 --increment-max=8 Mask......: ?l?l?l?d?d?d [6] Recovered.: 5/5 (100.00%) Digests Time.Est..: 0 secs (completed)
3 — Rule-Based Attack (Attack Mode 0 + Rules)
Applied Hashcat's built-in best64.rule and dive.rule to transform wordlist entries with common leet-speak substitutions, capitalisation, and number appending — patterns users commonly apply thinking their password is "unique".
# Rule-based attack — rockyou + best64 rules (NTLM) hashcat -m 1000 -a 0 hashes_ntlm.txt rockyou.txt \ -r /usr/share/hashcat/rules/best64.rule # Stacked rules — dive.rule for deeper mutations hashcat -m 1000 -a 0 hashes_ntlm.txt rockyou.txt \ -r /usr/share/hashcat/rules/dive.rule --outfile cracked.txt Added rule mutations: 64 (best64) / 99076 (dive) Recovered additional: 3/20 previously uncovered hashes Rule "p@$$w0rd" variant cracked: "password123" -> "p@$$w0rd123"
Python: Hash Generation & Results Parser
A Python script automated hash generation from a test wordlist and parsed Hashcat's potfile output to produce a summary report — practising the kind of scripting a SOC analyst might use to automate bulk credential-checking tasks.
#!/usr/bin/env python3 # hash_gen_parse.py — lab study script # Generates MD5/NTLM test hashes from a wordlist, then parses cracked output import hashlib, binascii, os, argparse def make_md5(plaintext: str) -> str: return hashlib.md5(plaintext.encode()).hexdigest() def make_ntlm(plaintext: str) -> str: return hashlib.new( 'md4', plaintext.encode('utf-16le') ).hexdigest() def generate_hashes(wordlist_path: str, algo: str) -> list[str]: hashes = [] with open(wordlist_path) as f: for line in f: pw = line.strip() if algo == 'md5': hashes.append(make_md5(pw)) elif algo == 'ntlm': hashes.append(make_ntlm(pw)) return hashes def parse_potfile(potfile: str) -> dict: """Return {hash: plaintext} from hashcat .potfile""" recovered = {} with open(potfile) as f: for line in f: parts = line.strip().split(':') if len(parts) >= 2: recovered[parts[0]] = ':'.join(parts[1:]) return recovered # --- Results summary --- Total hashes generated : 500 Recovered (MD5) : 478 / 500 (95.6%) Recovered (NTLM) : 491 / 500 (98.2%) Recovered (SHA-256) : 312 / 500 (62.4%) Recovered (bcrypt-12) : 4 / 500 ( 0.8%) Longest plaintext found: "iloveyou2009" Most common pattern : [word]+[2-digit year]
Bash: Multi-Mode Attack Wrapper
A Bash wrapper script ran all three attack modes sequentially and logged timestamped results — practising automation patterns useful for lab documentation and reproducible testing.
#!/usr/bin/env bash # run_attacks.sh — lab study wrapper # Runs dictionary, mask, and rule-based attacks; logs with timestamps HASHFILE="${1:-hashes_ntlm.txt}" WORDLIST="/usr/share/wordlists/rockyou.txt" RULES_DIR="/usr/share/hashcat/rules" LOGFILE="results_$(date +%Y%m%d_%H%M%S).log" MODE=1000 # NTLM log() { echo "[$(date '+%H:%M:%S')] $*" | tee -a "$LOGFILE"; } log "=== Phase 1: Dictionary attack ===" hashcat -m $MODE -a 0 "$HASHFILE" "$WORDLIST" \ --potfile-path=./hashcat.pot --quiet log "Recovered so far: $(wc -l < ./hashcat.pot)" log "=== Phase 2: Mask attack (6-char ?l?d combos) ===" hashcat -m $MODE -a 3 "$HASHFILE" "?l?l?l?d?d?d" \ --potfile-path=./hashcat.pot --quiet log "Recovered after mask: $(wc -l < ./hashcat.pot)" log "=== Phase 3: Rule-based (best64) ===" hashcat -m $MODE -a 0 "$HASHFILE" "$WORDLIST" \ -r "$RULES_DIR/best64.rule" \ --potfile-path=./hashcat.pot --quiet log "Final recovered: $(wc -l < ./hashcat.pot)" log "Full log written to: $LOGFILE" [09:12:03] === Phase 1: Dictionary attack === [09:14:31] Recovered so far: 18 [09:14:31] === Phase 2: Mask attack (6-char ?l?d combos) === [09:14:35] Recovered after mask: 21 [09:14:35] === Phase 3: Rule-based (best64) === [09:16:47] Final recovered: 24 [09:16:47] Full log written to: results_20240315_091203.log
What the Lab Demonstrated
Monash Bootcamp Conference Presentation
The findings from this study project were presented at the Monash University Cybersecurity Bootcamp's final demo-day conference. The presentation covered the attack methodology, live Hashcat demonstrations (on self-generated test hashes), and — most importantly — the defensive controls that organisations can implement to make offline cracking attacks economically infeasible.
The audience included bootcamp peers, instructors, and industry representatives. Presenting technical offensive findings to a mixed audience reinforced the importance of framing attack knowledge in terms of concrete, actionable defence.
How Organisations Should Respond
This is the most operationally relevant section. Understanding how attackers crack passwords directly informs the controls a SOC or IT security team should advocate for.
/var/log/auth.log). Password-spray attacks use low-frequency, high-breadth patterns to evade per-account lockout. Correlation rules should flag >50 failures across >10 unique accounts within a 10-minute window.