[This lab](https://portswigger.net/web-security/authentication/password-based/lab-broken-bruteforce-protection-ip-block) demonstrates how **brute-force protections** can be rendered ineffective due to a logic flaw in the way the server tracks failed login attempts. Specifically, the server resets your failed login attempt counter when you **log in successfully** — even if you're alternating attempts for different users.
By cleverly interleaving valid login attempts for yourself between brute-force attempts on the victim account, you can avoid hitting the failure threshold and **bypass the IP block entirely**.
#### Step 1: Investigate Login Behavior
1. Log in at `/login` with incorrect credentials a few times.
2. After **3 failed attempts**, you’ll be blocked (IP-based).
✅ **Observation:** Logging in successfully (e.g., as `wiener`) **resets** the block.
---
#### Step 2: Build Interleaved Attack with Burp Intruder
1. Intercept a login POST request in **Burp**:
```http
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=carlos&password=wrongpass
```
2. Send it to **Burp Intruder**.
3. Choose **Attack type: Pitchfork**
4. Highlight **both** `username` and `password` fields as payload positions.
---
#### Step 3: Setup Payloads (Pitchfork)
**Position 1 (username):**
Use a list that alternates between your username and the target:
```
wiener
carlos
wiener
carlos
...
```
Ensure your own username appears **before every attempt** on `carlos`.
✅ Repeat pattern for ~100 lines.
---
**Position 2 (password):**
Alternate your own password (`peter`) with each candidate password:
```
peter
password1
peter
password2
...
```
✅ Each `wiener` attempt uses a correct password to reset the lockout.
✅ Each `carlos` attempt uses a password guess.
---
#### Step 4: Configure Throttling
1. Go to **Resource pool** tab.
2. Create a new resource pool with:
```
Max concurrent requests: 1
```
This ensures **sequential execution**, critical for bypassing timing-based rate limiting.
---
#### Step 5: Start the Attack
- Launch the Intruder attack
- Wait for results to complete
---
#### Step 6: Identify the Valid Password
- In the results window:
- **Filter out** all responses with status `200 OK`
- Sort by **username** and look for `carlos`
- Look for a response with `302 Found` or a different length/status
✅ This indicates a **successful login**.
- Make note of the corresponding **password**.
---
#### Step 7: Log in as Carlos
- Go to `/login`
- Enter:
```
Username: carlos
Password: [the successful password]
```
- Visit `/my-account` to solve the lab.
---
##### Why It Works
- The server tracks failed logins **per IP**, not per user
- A successful login (as `wiener`) **resets** the failed attempt counter for the IP
- By interleaving valid logins, you prevent the counter from reaching the block threshold — allowing **unlimited brute-force attempts** on `carlos`
---
##### Real-World Implications
- Apps that implement IP-based lockouts **must not allow resets based on other user activity**
- This logic flaw is often missed in custom auth workflows or legacy systems
- Brute-force protections must be **per user account**, not per IP alone