Ethical Hacking
Brute Force Attacks
Lesson 21 covered offline cracking — working against hashes on your own machine. This lesson covers online attacks — testing credentials directly against live running services. Different tools, different risks, different rules of engagement.
Offline vs online — a critical distinction
Offline cracking happens entirely on your machine. You have the hash, you run hashcat or John against it, nothing touches the target. The only limit is your hardware speed. You can run ten billion guesses per second against an MD5 hash and the target system never knows.
Online brute forcing is different. Every guess is a real authentication attempt sent across the network to a live service. Each one appears in server logs. Each one can trigger account lockout policies. Each one generates detectable traffic patterns. The service you are attacking controls the pace — not your hardware.
That changes the approach completely. Where offline cracking rewards raw speed, online brute forcing rewards precision — the right usernames, the right passwords, at a rate that does not trigger defences. Spray too fast and you lock accounts, alert the SOC, or get blocked entirely. The skill is applying just enough pressure to find weak credentials without burning the engagement.
Account lockout — the constraint that changes everything
Most production systems implement account lockout — lock an account after a certain number of failed attempts. Five wrong passwords and the account is locked for thirty minutes, or until an admin resets it. This creates a real problem for brute force testing: if you try a hundred passwords against a single account, you will lock it after attempt five and potentially disrupt a real user.
Traditional brute force
Many passwords, one account
Try hundreds of passwords against a single account. Fast at finding the password — but runs straight into lockout policies. Effective only when lockout is disabled or you are targeting a single high-value account and the lockout threshold is high.
Risk: Locks the target account. Generates obvious log patterns. Almost always detected.
Password spraying
One password, many accounts
Try one or two common passwords against every account in the organisation. No account gets more than two attempts so lockout is never triggered. Slower at finding specific passwords — but avoids defences entirely and scales across large user lists.
Risk: Lower detection profile. The preferred approach on real engagements with lockout policies in place.
Hydra — the online brute force tool
Hydra is the standard tool for online credential testing on Kali. It supports dozens of protocols — SSH, FTP, HTTP, SMTP, MySQL, RDP, SMB, and more — with a consistent command structure across all of them. Learn the flag syntax once and it applies everywhere.
One practical note before you run it: Hydra is not subtle. It makes authentication attempts in rapid succession and generates obvious log entries. On a real engagement, always confirm that credential testing against live services is explicitly within scope — and understand whether the client wants you to avoid account lockouts or whether triggering them is an acceptable finding in itself.
The scenario: During service enumeration you confirmed SSH running on port 22 and FTP on port 21 on Metasploitable. You have a short list of three valid usernames from SMTP enumeration in Lesson 16 — msfadmin, user, and service. You want to test whether any of them use predictable passwords before moving to exploitation. The engagement scope explicitly covers credential testing against this host.
# Hydra online brute force against SSH on Metasploitable
# Every attempt is a real authentication request to the live service
# Only run this inside your authorised lab or engagement scope
# -L path to a file containing usernames — one per line
# we use the three confirmed usernames from SMTP enumeration
# -P path to a wordlist file containing passwords to try
# fasttrack.txt is small (222 entries) and focuses on trivially weak passwords
# starting small avoids locking accounts if lockout is configured
# -t 4 run 4 parallel threads — keeps the attack reasonably fast
# without generating the sudden burst of traffic that triggers IDS alerts
# ssh the protocol to attack — Hydra handles the SSH handshake automatically
# 192.168.56.101 the target IP
hydra -L users.txt -P /usr/share/wordlists/fasttrack.txt \
-t 4 ssh://192.168.56.101
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak [DATA] max 4 tasks per 1 server, overall 4 tasks, 666 login tries [DATA] attacking ssh://192.168.56.101:22/ [22][ssh] host: 192.168.56.101 login: msfadmin password: msfadmin [22][ssh] host: 192.168.56.101 login: user password: user 1 of 1 target successfully completed, 2 valid passwords found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished.
Breaking it down:
Three usernames times 222 fasttrack entries equals 666 attempts. From those, two valid credential pairs — both matching the pattern of password equals username, which John also cracked offline in Lesson 21. The consistency between offline hash cracking and live service testing confirms both methods are working correctly and the findings are genuine.
Four parallel threads means Hydra tests four credential combinations simultaneously. Higher thread counts are faster but generate more simultaneous connections — which looks more like an attack to a network monitor. For lab work -t 4 is fine. On a sensitive production system, drop to -t 1 to space out the attempts and reduce detection risk.
fasttrack.txt has 222 entries. rockyou.txt has 14 million. Against a service with lockout after five attempts, rockyou.txt would lock every account before getting anywhere. Starting with fasttrack — trivially weak passwords, default credentials, common service defaults — catches the low-hanging fruit quickly and safely before escalating to a larger list if needed.
Testing FTP and web login forms
Hydra uses the same flag structure across different protocols — swap out the protocol name and adjust one or two service-specific options. FTP is almost identical to SSH. HTTP form logins require a few extra parameters to tell Hydra what form fields to fill and what a failed login response looks like.
# Brute force FTP — same structure as SSH, just change the protocol
# FTP credentials are transmitted in plaintext so a successful login here
# also means credentials could have been captured by a network sniffer
hydra -L users.txt -P /usr/share/wordlists/fasttrack.txt \
-t 4 ftp://192.168.56.101
# HTTP form-based login brute force — requires more parameters
# http-post-form tells Hydra this is a POST request to a web login form
# The string after the URL has three parts separated by colons:
# Part 1 — the URL path of the login form
# Part 2 — the POST body with ^USER^ and ^PASS^ as placeholders
# Hydra substitutes actual usernames and passwords here
# Part 3 — a string that appears in the response when login FAILS
# Hydra compares every response against this — no match means success
hydra -L users.txt -P /usr/share/wordlists/fasttrack.txt \
-t 4 192.168.56.101 \
http-post-form "/dvwa/login.php:username=^USER^&password=^PASS^&Login=Login:Login failed"
[21][ftp] host: 192.168.56.101 login: msfadmin password: msfadmin [21][ftp] host: 192.168.56.101 login: user password: user [80][http-post-form] host: 192.168.56.101 login: admin password: password login: admin password: admin
Breaking it down:
"Login failed" is the text that appears on the page when authentication is rejected. Hydra sends credentials, reads the response, and checks whether this string is present. If it is absent — meaning the failure message did not appear — Hydra concludes the login succeeded. Getting this string wrong is the most common reason Hydra reports false positives on web forms. Always test a manual failed login first to confirm exactly what text the page returns.
The DVWA application — Damn Vulnerable Web Application — ships with admin:admin as default credentials. Finding default credentials on a web application in a real engagement is a finding in its own right. It suggests the application was deployed without any post-installation hardening and raises the question of what other defaults were left in place.
Rate limiting and detection — what to watch for
Online brute forcing leaves traces. Understanding what those traces look like helps you operate more quietly and helps you assess how well a client's defences would catch a real attacker doing the same thing.
Repeated authentication failures from a single source IP
The most obvious signal. Any SIEM worth its licence flags 50+ failed login attempts from the same IP in a short window. Slowing down with -t 1 and adding --wait-retry helps but does not eliminate the pattern — it just extends the detection window.
Account lockout events
On Active Directory environments, account lockout events generate Windows Event ID 4740. Security teams are often specifically alerted on these. Multiple lockouts across different accounts in the same window is a high-confidence signal of a spray or brute force attempt.
Unusual user-agent strings in HTTP logs
Hydra sends a recognisable user-agent by default — "Hydra/9.5" — that appears verbatim in web server access logs. Use the -U flag to set a realistic browser user-agent string if stealth matters. On a black box test where you are not supposed to be obvious, the default Hydra user-agent is a giveaway.
Rate limiting responses — HTTP 429 or CAPTCHA
Well-configured web applications respond to rapid login attempts with HTTP 429 Too Many Requests or introduce CAPTCHA challenges. When Hydra starts receiving these, its success detection logic breaks — every response looks like a failure because the failure string detection does not account for rate-limiting responses. If you see Hydra claiming everything failed on a web target, check for 429s first.
In a report, document every detection signal that the client's environment did or did not generate. If the SOC did not alert on 666 SSH login attempts from a single IP, that is a finding — not just a note. It means a real attacker could have run the same attack without triggering any response.
Password spraying in practice
For environments with lockout policies, spraying is the safer approach. The idea is simple — pick one or two passwords that are statistically likely to exist somewhere in a large organisation ("Spring2024!", "Company123", "Welcome1") and try them against every account. With hundreds or thousands of accounts, even a 1% hit rate produces useful credentials.
# Password spray — one password tried against many usernames
# Each account gets only ONE attempt — lockout is never triggered
# This is Hydra's most important mode for real-world engagements
# -L the full user list (could be hundreds of accounts)
# -p lowercase p — a single password string rather than a file
# we try just one password across all accounts
# -t 1 one thread — deliberate slowness to avoid detection
# -w 5 wait 5 seconds between attempts — mimics slow manual login behaviour
# Try "Password1" — one of the most commonly used compliant passwords
hydra -L all_users.txt -p "Password1" \
-t 1 -w 5 ssh://192.168.56.101
# Try "msfadmin" — the company/service name as password
# People frequently use the system name or company name as their password
hydra -L all_users.txt -p "msfadmin" \
-t 1 -w 5 ssh://192.168.56.101
[22][ssh] host: 192.168.56.101 login: msfadmin password: msfadmin 1 of 1 target completed, 1 valid password found. [INFO] No accounts locked. Spray completed without triggering lockout policy.
Breaking it down:
Lowercase -p takes a single password string. Uppercase -P takes a file of passwords. The distinction is fundamental to spraying — you want exactly one password per account, not a file. Using -P with a large wordlist against a locked-out environment will burn every account in the user list. Always double-check which flag you are using before running against production.
A five-second delay between attempts spreads 100 login attempts across eight minutes rather than eight seconds. Slow enough to avoid most rate limiting, fast enough to stay practical. On environments with strict detection, increase this to -w 30 or longer — patience is cheaper than a locked account or a triggered alert.
No accounts locked. The finding — weak credential found without triggering any lockout — goes into the report as two separate issues: the weak password itself (critical, should be changed immediately) and the absence of detection capability (the 666 SSH attempts generated no alert). Both are findings. Both belong in the report.
Teacher's Note: Before running any online brute force against a client's live services, confirm in writing that account lockout testing is within scope. The engagement contract covers you legally — but an account lockout that locks out a director at 9am on a Monday morning needs to have been authorised in advance, not apologised for afterwards.
Practice questions
Scenario:
Scenario:
Scenario:
Quiz
Scenario:
Scenario:
Scenario:
Up Next · Lesson 23
Credential Harvesting
Beyond brute force — how credentials are captured from phishing, memory, cached sessions, and misconfigured services during an engagement.