Lab Covered
This write-up focuses on the following EXPERT-level labs from the PortSwigger Web Security Academy:
13 Broken brute-force protection, multiple credentials per request
This lab demonstrates how a flawed authentication mechanism allows multiple credential pairs to be submitted within a single HTTP request. The server processes each set independently, which enables attackers to bypass standard rate-limiting controls and perform large-scale brute-force attacks efficiently. The lab emphasizes the importance of validating and strictly controlling request formats during authentication.
14 2FA bypass using a brute-force attack
This lab demonstrates how insufficient brute-force protection on the second authentication factor (2FA) allows attackers to systematically guess 2FA codes once valid primary credentials have been compromised. The absence of proper rate-limiting or account lockout mechanisms on the 2FA step renders multi-factor authentication ineffective. The lab highlights the need for consistent protection across all stages of the authentication workflow.
LAB 13- Broken brute-force protection, multiple credentials per request
Lab Description :
Solution
The first step is to analyze the functionality of the lab, starting with the login feature.
I attempted to log in with invalid credentials and repeated the request multiple times using Burp Suite Intruder with Null payloads to observe the server’s response to repeated failed login attempts.
Analysis of Account Lockout Mechanism and JSON Request Data
I’ve observed that after three incorrect login attempts, an account lockout mechanism is triggered, preventing further attempts for one minute. Initially, the error message states “Invalid username or password,” but after the third attempt, it changes to “You have made too many incorrect login attempts. Please try again in 1 minute(s).”
This behavior indicates that the lockout is not based on specific usernames. Instead, it appears to identify and track the client making the repeated failed attempts. This identification could be based on the client’s IP address, or other unique characteristics used to distinguish one client from another.
To investigate whether the lockout was tied to HTTP headers, I performed an additional Burp Intruder run. During this run, I attempted to circumvent the lockout by:
- Modifying the
User-Agentheader for each request. - Utilizing the
X-Forwarded-Forheader to spoof the client’s IP address. - Removing or modifying existing cookie values.
However, none of these attempts were successful; the lockout consistently occurred after three failed attempts, regardless of the header manipulations. This suggests that the tracking mechanism is more sophisticated than a simple reliance on these common HTTP headers.
While subtle differences in error messages or response timings can sometimes reveal vulnerabilities, given that each lab is typically focused on a single, primary issue, I’ve opted to skip detailed analysis of such nuances to concentrate on more direct attack vectors.
A critical new observation, distinct from previous labs, is that the request data is not standard POST data but is formatted as a JSON structure. This is a significant detail as it implies the server processes login credentials from a structured JSON payload, which could influence how the lockout mechanism functions or how different attack techniques might be applied.
The response reveals two important things:
- The application encountered a case it does not handle properly, resulting in an error.
- Any scenario that triggers unhandled behavior can potentially serve as an attack vector.
Modifying the request
Sending 100 different password parameters results in a server error. So what happens if I supply a single password parameter that contains all the passwords in a list?( we can provide as many password as,I can in this case
Send the request. This will return a 302 response.
4 Right-click on this request and select Show Response in the browser. Copy the URL and load it in the browser. The page loads and you are logged in as carlos.
LAB 14 - 2FA bypass using a brute-force attack
Lab Description :
Solution
For this attack, I used Burp Suite’s Session Handling feature
Step 1:
- Log in using the given credentials while Burp is running.
-
When prompted for the 2FA code, enter random digits to intentionally fail the 2FA step.
Step 2: Configure Burp Session Handling with Macros
- Open Burp Suite.
- Go to Project Options → Sessions → Session Handling Rules.
- Click Add to create a new rule.
Macro Setup
- Create a Macro to automatically fetch fresh CSRF tokens and handle the login sequence:
GET /login— to retrieve the CSRF token.POST /login— to submit valid credentials.GET /login2— to prepare for the 2FA step (which will be brute-forced using Intruder later).
This macro ensures that every time Burp Intruder sends a request, it has a valid CSRF token and an active session to work with.
Important Configuration: Include URLs in Scope
In Burp Suite, make sure to add all relevant URLs to the scope.
Note: Including all URLs in scope ensures that the macro is executed for every request intercepted and sent by Burp Intruder. This guarantees that the CSRF token and session remain valid for each request during the brute-force attack.
Step 3: Recording Macros
The Macro Recorder in Burp Suite allows selecting requests directly from the Proxy history.
For this case, we select the following requests in sequence (using Ctrl + Left-click):
POST /login— for submitting credentials.POST /login2— for submitting the 2FA code.GET /login— to retrieve a fresh CSRF token if needed.
These requests are added to the macro, ensuring Burp has a valid session and CSRF token before every Intruder request.
This will , Retry to login after every try or we can say it will keep me logged in .
STEP 3
SEND POST /login2 to burp intruder , and add payload marker to 2FA parameter.
STEP 4 → Give conncurrent request according to your choice
Step 4: Intruder Configuration
-
Set Maximum Concurrent Requests to
1to ensure only one request is sent at a time. -
Under the Payloads tab:
- Select Numbers as the payload type.
- Set the range from
0000to9999. - Set the step to
1. - Set the minimum and maximum integer digits to
4(to ensure all 4-digit codes are generated). - Set maximum fraction digits to
0.
This configuration will generate every possible 4-digit code for brute-forcing the 2FA.
Step 5: Launching the Attack
- Start the Intruder attack.
- Monitor the responses and look for any request returning a 302 status code — this indicates a successful 2FA code.
Once a request with 302 Found status is identified:
- Right-click on that request → Show response in browser.
- The session will open in the browser, and you will be successfully logged into the target account.
Then:
- Click on My Account to fully solve the lab.
Note: You must send the request to the browser immediately after finding the
302response. If you delay, the CSRF token may expire, and you will get an “Invalid CSRF” error.