[This lab requires](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-subtly-different-responses) using subtle variations in server responses to: 1. **Identify a valid username** 2. **Brute-force the correct password for that user** 3. **Log in and access the account** ### Capture and Prepare the Login Request - Start Burp and intercept a failed login attempt (e.g., `carlos:not-important-rigt-now`). - Go to `Proxy > HTTP history` → locate the `POST /login` request - Right-click the **username** field → **Send to Intruder**. ![[CleanShot 2025-03-25 at 23.36.50.png]] ### Set Up Username Enumeration - In **Intruder**, confirm that the username is marked as a payload position (`§username§`). - Go to the **Payloads** tab: - Select **Payload type: Simple list** - Paste in your **[candidate usernames](https://portswigger.net/web-security/authentication/auth-lab-usernames)** ![[CleanShot 2025-03-25 at 23.37.46.png]] ### Add Response Extraction to Spot the Subtle Difference - Go to the **Settings** tab → open **Grep - Extract** - Click **Add** and highlight the text `"Invalid username or password."` in the response body - Burp will auto-fill the offset and context - Click **OK** ![[CleanShot 2025-03-25 at 23.38.48.png]] ### Launch the Attack and Analyze the Results - Start the attack. - When complete, an **extracted column** will show the matched message. - Sort by this column. - Look for **a subtle difference** — in this lab, it’s a **trailing space instead of a period** in the error message: ``` Invalid username or password ``` This indicates a **valid username** but an **invalid password**. ![[CleanShot 2025-03-25 at 23.39.53.png]] --- ### Target the Password Parameter - Back in Intruder: - Replace the payload position: ```http username=valid-user&password=§password§ ``` - Go to **Payloads** tab: - Replace the list with your **[password list](https://portswigger.net/web-security/authentication/auth-lab-passwords)** - Launch the attack. ![[CleanShot 2025-03-25 at 23.46.32.png]] ### Identify the Valid Password - Watch for the **HTTP 302 Redirect** response — this usually indicates a successful login. - Note the password associated with that 302 response. ![[CleanShot 2025-03-25 at 23.47.25.png]] ### Final Step: Log In Use the credentials: ``` Username: [identified valid user] Password: [identified valid password] ``` Log in to the application and verify by accessing the user account page. ![[CleanShot 2025-03-25 at 23.48.22.png]] ### Insights - **Use Grep - Extract instead of just status codes.** Subtle changes in content are often more reliable than status code differences in real-world apps. - **Always sort and scan response lengths and extracted values.** These fields often reveal logic discrepancies even when error messages are the same. - **Reduce noise.** This two-phase attack (enumerate first, brute-force second) minimizes login attempts and is far less likely to trigger lockouts or alert detection systems. - **Understand error normalization.** Many applications return identical messages intentionally—so even slight differences (timing, formatting, punctuation) matter.