9.1 Web Authentication Attacks & Login Brute-Forcing
Key Takeaways
Form-based authentication passes user credentials via HTTP POST bodies or headers, relying on session identifiers or JSON Web Tokens (JWTs) for state management.
Username enumeration vulnerabilities arise when web applications output differential error responses, status codes, or response timings for valid versus invalid accounts.
Hydra's http-post-form module requires specifying the target URI, parameter string with replacement variables (^USER^ and ^PASS^), and a condition string prefixed with F= (failure) or S= (success).
Burp Suite Intruder supports four attack modes: Sniper for single-parameter tests, Battering Ram for synchronized multi-field tests, Pitchfork for lockstep multi-list testing, and Cluster Bomb for exhaustive Cartesian product testing.
Password spraying mitigates account lockout by testing a single high-probability password across an enumerated list of usernames rather than attacking individual accounts with large wordlists.
9.1 Web Authentication Attacks & Login Brute-Forcing
Authentication mechanisms represent the primary security perimeter for web applications, guarding access to administrative portals, sensitive databases, and user accounts. During practical penetration testing assessments—such as those encountered on the eJPT exam—evaluating authentication robustness is a critical milestone. Attackers and penetration testers regularly target web authentication mechanisms to discover administrative interfaces, identify default credentials, exploit predictable session handling, or automate credential dictionary attacks.
Securing or attacking web authentication requires a deep technical comprehension of how browsers and servers establish, verify, and maintain identity over a stateless HTTP transport layer. When controls like rate limiting, account lockout thresholds, and generic error handling are missing or misconfigured, automated tools like THC-Hydra and Burp Suite Intruder allow testers to rapidly identify valid credentials.
Web Authentication Architectures & State Management
Because the HTTP protocol is inherently stateless, applications must implement supplementary protocols and data structures to authenticate users and persist their authenticated state across successive HTTP requests.
+---------------------------------------------------------------------------------------+
| WEB AUTHENTICATION & SESSION LIFECYCLE |
+---------------------------------------------------------------------------------------+
| 1. Client Submission --> POST /login.php HTTP/1.1 (username=admin&password=secret) |
| 2. Server Validation --> Queries DB / Hash verification (e.g., bcrypt/Argon2) |
| 3. Session Creation --> Server generates crypto-random session token (PHPSESSID) |
| 4. Token Issuance --> Set-Cookie: PHPSESSID=d41d8cd98f00b204e980; HttpOnly; Secure|
| 5. Subsequent Access --> GET /dashboard.php (Cookie: PHPSESSID=d41d8cd98f00b204e980) |
+---------------------------------------------------------------------------------------+
1. Form-Based Authentication
Form-based authentication is the most ubiquitous mechanism on modern websites. The user submits credentials via an HTML form using the HTTP POST method:
<form method="POST" action="/login.php">
<input type="text" name="username" placeholder="Username" />
<input type="password" name="password" placeholder="Password" />
<button type="submit" name="submit">Log In</button>
</form>
Upon submission, the browser transmits the credentials within the HTTP request body encoded as application/x-www-form-urlencoded or formatted as a JSON payload (application/json). The server validates the credentials against a database or directory service (such as LDAP or Active Directory). If valid, the server instantiates a session.
2. HTTP Basic Authentication
Defined in RFC 7617, HTTP Basic Authentication relies directly on HTTP headers rather than custom HTML forms. When a client requests a protected resource, the server responds with a 401 Unauthorized status code and a WWW-Authenticate: Basic realm="Secure Area" header.
The browser then prompts the user via a native operating system dialog and transmits the credentials inside an Authorization header on all subsequent requests:
GET /admin/ HTTP/1.1
Host: 192.168.1.105
Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=
The credentials string admin:password123 is encoded in Base64 (YWRtaW46cGFzc3dvcmQxMjM=). Base64 provides zero confidentiality or encryption; anyone monitoring network traffic can decode the header instantly with base64 -d. Basic Authentication must always be paired with TLS/HTTPS to protect credentials in transit.
3. Session Cookies and Tokens
Once authentication succeeds, the server returns an HTTP response containing a Set-Cookie header:
HTTP/1.1 302 Found
Location: /admin/dashboard.php
Set-Cookie: session_id=f78a2e1d09b64c23; Path=/; HttpOnly; Secure; SameSite=Strict
The client stores this cookie and supplies it in the Cookie header of every future request. The server maintains an internal mapping (in memory, Redis, or a relational database) linking f78a2e1d09b64c23 to the authenticated user account.
4. JSON Web Tokens (JWT)
In modern single-page applications (SPAs) and REST APIs, JSON Web Tokens (JWTs) are widely used for stateless authentication. A JWT consists of three base64url-encoded parts separated by periods (header.payload.signature):
- Header: Specifies the token type and cryptographic signing algorithm (e.g.,
{"alg": "HS256", "typ": "JWT"}). - Payload: Contains claims regarding user identity, roles, and expiration timestamps (e.g.,
{"sub": "12345", "user": "admin", "admin": true}). - Signature: A cryptographic signature generated by hashing the header and payload with a private key or secret HMAC key.
Because the token is stateless, the server verifies validity solely by validating the signature without querying a central session database.
Vulnerabilities in Web Authentication
Web applications often suffer from implementation flaws that expose login interfaces to compromise:
Default & Hardcoded Credentials
Turnkey web applications, commercial off-the-shelf software (COTS), content management systems (CMS), and network appliance portals frequently ship with factory default credentials. Common examples include:
- Routers / Gateways:
admin:admin,admin:password,root:root - Tomcat Manager:
tomcat:s3cret,admin:admin - Webmin:
root:root,admin:admin - Database Management Interfaces (phpMyAdmin):
root:<empty>
Penetration testers should always cross-reference identified web applications and service banners with vendor documentation or repository collections like SecLists' default-passwords/.
Username Enumeration
An application allows username enumeration when an attacker can reliably distinguish between registered and unregistered accounts through observable server behavior:
- Differential Error Messages: Submitting an invalid username displays
Username does not exist, whereas submitting a valid username with an incorrect password displaysIncorrect password for user. An attacker can use this difference to compile a list of confirmed valid usernames. - Differential Response Status Codes: An invalid username might return
HTTP 404 Not FoundorHTTP 200 OK, while a valid username returnsHTTP 401 UnauthorizedorHTTP 302 Redirect. - Response Timing Discrepancies: If an application performs expensive cryptographic hashing (such as bcrypt or Argon2) only after discovering a valid username in the database, requests for existing accounts will take significantly longer (e.g., 250ms) than requests for non-existent accounts (e.g., 15ms).
Absence of Rate Limiting & Account Lockouts
Without mechanisms limiting the number of failed authentication attempts per IP address or per user account over a specified duration, an attacker can launch automated dictionary attacks with thousands of candidate passwords per minute without interruption.
Automated Web Login Brute-Forcing with THC-Hydra
THC-Hydra is a premier parallelized network authentication cracker supporting dozens of protocols, including web form logins via http-post-form and http-get-form.
Anatomy of the http-post-form Module
To brute-force a form-based login with Hydra, you must provide a target, the module name, and an instruction string consisting of three colon-delimited components:
"<URL_Path>:<Request_Body>:<Condition_String>"
hydra 192.168.1.105 http-post-form \
"/login.php:username=^USER^&password=^PASS^&Login=Login:F=Invalid username or password" \
-l admin \
-P /usr/share/wordlists/rockyou.txt \
-V -f
| Component | Syntax / Example | Purpose & Mechanics |
|---|---|---|
| URL Path | /login.php | Specifies the action URI where the HTTP POST request is submitted. |
| Request Body | username=^USER^&password=^PASS^&Login=Login | The payload string containing form parameter names. The placeholders ^USER^ and ^PASS^ are dynamically replaced by Hydra for each attempt. |
| Condition String | F=Invalid username or password | Instructs Hydra how to determine whether an attempt failed (F=) or succeeded (S=). If the response contains this text, Hydra marks the attempt as failed. |
| User Specification | -l admin or -L users.txt | -l specifies a single target username; -L specifies a wordlist of usernames to test. |
| Password List | -P /usr/share/wordlists/rockyou.txt | Specifies the dictionary file containing candidate passwords. |
| Exit Flag | -f | Instructs Hydra to stop immediately once the first valid credential pair is discovered. |
| Verbosity | -V or -v | -V outputs each password attempt in real-time, providing visibility into attack progress. |
| Port Specification | -s 8080 | Specifies a non-standard HTTP port (default is port 80 for HTTP, 443 for HTTPS). |
Distinguishing F= (Failure) vs. S= (Success)
Choosing between F= and S= is critical:
- Failure Condition (
F=): Most commonly used. If the web server returns200 OKon every attempt but prints"Invalid credentials"in the HTML body on failure, defineF=Invalid credentials. Hydra considers any response lacking that string to be a successful login. - Success Condition (
S=): Used when successful logins yield a unique signature, such as a redirect header (Location: /admin/dashboard.php) or specific greeting (S=Welcome back, Administrator). If the response contains this string, Hydra flags the credential as valid.
Adding HTTP Headers and Cookies to Hydra
Some web applications require an existing session cookie or an anti-CSRF token to accept form submissions. Additional HTTP headers can be appended to the Hydra request string after an optional third colon:
hydra 192.168.1.105 http-post-form \
"/dvwa/login.php:username=^USER^&password=^PASS^&Login=Login:F=login failed:H=Cookie: PHPSESSID=d41d8cd98f00b204e980; security=low" \
-l admin \
-P /usr/share/wordlists/rockyou.txt
Web Login Testing with Burp Suite Intruder
Burp Suite Intruder is a specialized tool for automating custom HTTP requests against web applications. It allows penetration testers to place variable injection markers anywhere within an intercepted HTTP request.
The Intruder Workflow
- Intercept a valid login request in Burp Proxy.
- Right-click the request and select Send to Intruder (or press
Ctrl+I). - Navigate to the Positions tab. Clear the default automated markers by clicking Clear §.
- Highlight the target parameters and add payload markers (
§) around the values to test (e.g.,username=§admin§&password=§secret§). - Select the Attack Type from the dropdown menu.
- Under the Payloads tab, configure payload sources (wordlists, brute-force sets, numbers).
- Click Start Attack and analyze the response table.
+---------------------------------------------------------------------------------------+
| BURP INTRUDER ATTACK MODES |
+---------------------------------------------------------------------------------------+
| 1. SNIPER 2. BATTERING RAM 3. PITCHFORK 4. CLUSTER BOMB |
| Single Wordlist Single Wordlist Multiple Wordlists Multiple Wordlists |
| |
| User: [Payload 1] User: [Payload 1] User: [Payload 1A] User: [Payload 1A] |
| Pass: [Base Value] Pass: [Payload 1] Pass: [Payload 1B] Pass: [Payload 1B] |
| |
| User: [Base Value] User: [Payload 2] User: [Payload 2A] User: [Payload 1A] |
| Pass: [Payload 1] Pass: [Payload 2] Pass: [Payload 2B] Pass: [Payload 2B] |
| |
| (Tests 1 mark at (Inserts same value (Iterates lists (Cartesian product:|
| a time) into all markers) in lockstep) all combinations) |
+---------------------------------------------------------------------------------------+
Deep Dive: The Four Intruder Attack Types
Understanding the mechanics of each Intruder attack mode is essential for both field assessments and the eJPT exam:
| Attack Mode | Payload Sets | Position Behavior | Formula for Request Count | Primary Penetration Testing Use Case |
|---|---|---|---|---|
| Sniper | 1 Set | Tests one marker position at a time while leaving all other marked positions at their baseline default values. | Positions × Payloads | Fuzzing individual input fields for SQLi, XSS, or testing passwords against a single fixed username. |
| Battering Ram | 1 Set | Places the exact same payload simultaneously into every defined marker position for each request. | 1 × Payloads | Testing scenarios where username and password might be identical (e.g., admin:admin, guest:guest, test:test). |
| Pitchfork | Multiple Sets (1 per marker) | Iterates through multiple payload lists in lockstep simultaneously. Request 1 uses User 1 and Pass 1; Request 2 uses User 2 and Pass 2. | Min(Payload Set Sizes) | Testing paired credentials (such as known leaked credential lists where user and password are paired 1-to-1). |
| Cluster Bomb | Multiple Sets (1 per marker) | Tests every possible permutation (Cartesian product) across all payload sets. Every item in Set 1 is tested against every item in Set 2. | Size(Set 1) × Size(Set 2) × ... | Exhaustive brute-forcing testing a list of 50 usernames against a list of 1,000 passwords (yielding 50,000 requests). |
Analyzing Intruder Results
When an attack completes, Intruder displays a results table with columns for Request, Status, Error, Timeout, Length, and Time. Penetration testers locate successful authentications by looking for anomalies:
- Response Length: A successful authentication almost always returns a response body differing in size from failed attempts (e.g., failed attempts produce 3,450 bytes containing "Invalid credentials", while a successful redirect or welcome page produces 420 or 5,120 bytes).
- HTTP Status Code: Failed attempts typically return
200 OK(displaying the error form again), whereas successful logins often return302 Foundor303 See Otherto redirect the user to a dashboard. - Response Cookies: Inspecting the response headers of anomalous requests will reveal
Set-Cookiedirectives issuing authenticated session tokens.
Credential Stuffing & Password Spraying Strategies
When attacking authentication interfaces protected by account lockout policies (e.g., locking accounts after 3 or 5 consecutive failed attempts), traditional single-account brute-forcing will quickly lock out legitimate users, alerting network administrators and halting testing.
Password Spraying Methodology
Password spraying reverses the traditional brute-force vector:
+---------------------------------------------------------------------------------------+
| PASSWORD SPRAYING MODEL |
+---------------------------------------------------------------------------------------+
| Target User Accounts: [user1, user2, user3, user4, user5, ..., user500] |
| |
| Attempt Cycle 1: Test "CompanyAutumn2026!" across all 500 accounts |
| Cool-Down Window: Sleep 30 minutes (exceeds account lockout counter reset) |
| Attempt Cycle 2: Test "Welcome123!" across all remaining uncompromised accounts|
+---------------------------------------------------------------------------------------+
By testing a single, highly plausible password (such as Company2026!, Welcome1!, or Summer2026!) against hundreds or thousands of enumerated user accounts, the tester never triggers the per-account failed-attempt threshold. Once all accounts have been queried once, the tester pauses execution for the duration of the lockout reset window (e.g., 30 or 60 minutes) before spraying the next candidate password.
Credential Stuffing
Credential stuffing takes advantage of widespread credential reuse across the web. Testers compile lists of confirmed username/email and password pairs compromised in third-party corporate data breaches. Automated tools systematically replay these exact pairs against the target organization's web portal, single sign-on (SSO) gateway, or external VPN interfaces.
A penetration tester is running THC-Hydra against a form-based web login at /login.php. The target application returns an HTTP 200 OK status code on both valid and invalid login attempts, but prints the string 'Authentication failed: bad password' inside the HTML response when credentials are incorrect. How should the condition string within Hydra's http-post-form module be configured?
S=Authentication failed: bad password
F=Authentication failed: bad password
STATUS=200
H=Authentication failed: bad password
You have intercepted a login request in Burp Suite and configured two payload markers: username=§user§&password=§pass§. You have loaded a list of 20 corporate usernames into Payload Set 1 and a dictionary of 500 common passwords into Payload Set 2. You want to test every password against every username, resulting in 10,000 total requests. Which Burp Intruder attack type must you select?
Sniper
Battering Ram
Cluster Bomb
Pitchfork
An enterprise web portal enforces an account lockout policy that disables any user account that experiences more than 3 consecutive incorrect password attempts within a 15-minute window. Which password attack strategy is specifically engineered to gain unauthorized access without triggering account lockouts?
Password spraying one common password across many user accounts, followed by a cool-down delay
Exhaustive dictionary brute-forcing against the domain administrator account using rockyou.txt
Rapid multi-threaded Hydra attacks using 64 parallel tasks against a single high-privilege account
Burp Suite Battering Ram attacks testing 10,000 combinations against the service accounts
Sections you finish are checked off in the contents.