Login Page Enumeration
Login page enumeration maps all authentication entry points on the target, identifies what mechanism each uses, and assesses whether default credentials or weak authentication controls are in play. Run this after content discovery gives you a full path list. Authentication surfaces found here feed into credential attacks and authentication bypass testing.
Discover Login Panels
Probe common authentication paths alongside content discovery results:
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Specifies the wordlist file to use for fuzzing. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword as the injection point. |
| $TARGET_IP:$PORT | Placeholder for the target IP address and port number. |
| -mc 200,301,302,401 | Match only responses with these specific HTTP status codes. |
| -iE 'login|admin|auth|signin|portal|console|manage' | Case-insensitive extended regex filter for auth-related directory names. |
200 /login 302 /admin 200 /administrator 404 /auth
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure SSL connections, skipping certificate verification. |
| -I | Send HEAD request only, fetching headers without response body. |
| http://$TARGET_IP:$PORT$path | Target URL built from IP, port, and iterated path variable. |
Identify Authentication Mechanism
Determine what type of authentication is in use — form-based, HTTP Basic, NTLM, or API token — before attempting anything:
WWW-Authenticate: Basic realm="Admin Area"
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure SSL/TLS connections, skipping certificate verification. |
| -I | Send a HEAD request and fetch HTTP headers only. |
| http://$TARGET_IP:$PORT/admin/ | Target URL with variable host IP and port to probe the /admin/ path. |
| -iE | Case-insensitive match using extended regular expressions. |
| 'www-authenticate|set-cookie|location|content-type' | Filter for auth, cookie, redirect, and content-type response headers. |
WWW-Authenticate: Basic means HTTP Basic auth — credentials go in the Authorization header. WWW-Authenticate: NTLM or Negotiate means Windows authentication. A 200 with a form in the body means form-based login. A 302 to a login URL with a session cookie means the app redirects unauthenticated requests.
Test Default Credentials
Before any brute force, manually try common defaults matched to the identified platform:
admin:admin: 200 admin:password: 401
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure TLS connections, skipping certificate verification. |
| -u $cred | Supplies HTTP Basic Auth credentials in user:password format. |
| -o /dev/null | Discards response body by writing output to /dev/null. |
| -w '%{http_code}' | Prints the HTTP response status code after the request. |
| $TARGET_IP:$PORT | Placeholder for the target host IP address and port number. |
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure TLS connections; skips certificate verification. |
| -c /tmp/cookies.txt | Save received cookies to the specified cookie jar file. |
| http://$TARGET_IP:$PORT/login | Target URL with variable host and port placeholders. |
| -X POST | Use HTTP POST method for the request. |
| -d 'username=admin&password=admin' | Send specified URL-encoded data as the POST request body. |
| -L | Follow HTTP redirects automatically. |
| -i | Perform case-insensitive pattern matching in grep. |
| 'welcome\|dashboard\|logout\|invalid\|error' | Grep pattern to detect login success or failure keywords. |
Assess Username Enumeration
Check whether the login form gives different responses for valid versus invalid usernames. Send a request with a likely-valid username and one with a random string:
Invalid password for user admin
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allows insecure SSL/TLS connections, skipping certificate verification. |
| -X POST | Specifies HTTP POST as the request method. |
| http://$TARGET_IP:$PORT/login | Target URL with variable host and port for the login endpoint. |
| -d 'username=admin&password=wrongpassword' | Sends URL-encoded form data as the POST request body. |
| -iE | Case-insensitive search (-i) with extended regex (-E) pattern matching. |
| 'invalid|error|incorrect|not found' | Regex pattern matching common authentication failure response strings. |
Invalid username or password
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allows insecure SSL connections by skipping certificate verification. |
| -X POST | Specifies HTTP POST as the request method. |
| http://$TARGET_IP:$PORT/login | Target URL with variable host and port for the login endpoint. |
| -d 'username=randomxyz123&password=wrongpassword' | Sends URL-encoded POST body with bogus credentials. |
| -iE | Case-insensitive search with extended regex pattern matching. |
| 'invalid|error|incorrect|not found' | Regex pattern to detect common authentication failure response keywords. |
Different error messages between the two requests confirm username enumeration. The first message reveals the account exists while the second is generic — this lets you enumerate valid usernames before password attacks.
Check Lockout Behavior
Send several failed attempts and check whether the account locks or responses change. This determines whether credential spraying is viable:
Attempt 1: 200 Attempt 2: 200 Attempt 3: 200 Attempt 4: 200 Attempt 5: 200 Attempt 6: 429
Explain command
| $(seq 1 6) | Generates sequence from 1 to 6 for loop iterations. |
| -sk | Silent mode and skip SSL certificate verification. |
| -X POST | Specifies HTTP POST as the request method. |
| http://$TARGET_IP:$PORT/login | Target URL using variable IP and port placeholders. |
| -d 'username=admin&password=wrongpass' | Sends URL-encoded POST body with credentials. |
| -o /dev/null | Discards response body by redirecting to null. |
| -w '%{http_code}' | Prints only the HTTP response status code. |
| sleep 1 | Pauses 1 second between each login attempt. |
A 429 or redirect to a CAPTCHA after several attempts means rate limiting is active. No change after many attempts means brute force is viable. A 302 to an account locked page means lockout is enforced — reduce attempts per account or switch to password spraying with a single password across many users.
Credential Spraying with hydra
When lockout behavior is confirmed and spraying is viable, use hydra against form-based login. Identify the correct parameter names from the form source first:
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allows insecure TLS connections by skipping certificate verification. |
| http://$TARGET_IP:$PORT/login | Target URL using variable host and port to fetch the login page. |
| -iE | Case-insensitive search using extended regular expressions. |
| 'input|form|action' | Regex pattern matching HTML form-related tags and attributes. |
| -20 | Limits output to the first 20 matching lines. |
Explain command
| -l admin | Sets a single username 'admin' for the attack. |
| -P /usr/share/wordlists/rockyou.txt | Specifies the password wordlist file to iterate through. |
| $TARGET_IP | Placeholder for the target host IP address. |
| http-post-form | Specifies the HTTP POST form attack module. |
| /login:username=^USER^&password=^PASS^:Invalid password | Defines login path, POST fields, and failure string to detect. |
| -t 10 | Sets the number of parallel connection threads to 10. |
Username Enumeration via Password Reset
When the login form returns a uniform error, the forgot-password and registration endpoints often do not. A reset request for an existing account commonly returns a different status code or body than one for an account that does not exist, for example 201 or 200 with a confirmation versus 404 or a validation error. Probe a known-bad username against a candidate and compare the status codes:
admin -> 201 random -> 404
Different codes confirm the endpoint discloses account existence. Drive a wordlist through it to collect valid accounts, then take them to password spraying. If the status codes match, compare response bodies and response times, since some apps leak existence through a slower path when they actually send mail:
References
-
Network login brute force tool supporting HTTP form-based and Basic auth
Was this helpful?
Your feedback helps improve this page.