> For the complete documentation index, see [llms.txt](https://ganesha-hk.gitbook.io/cybersecurity-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-authentication-labs/lab-8.md).

# lab-8

## 2FA Broken Logic

**Difficulty:** Practitioner

### Lab Description

This lab's two-factor authentication is vulnerable due to flawed logic. The server associates a 2FA code with a username parameter in the request rather than with the authenticated session.

**Your credentials:** `wiener:peter`\
**Victim's username:** `carlos`

**Objective:** Access Carlos's account page.

### Solution

**Step 1 — Map the authentication flow**

Log in as `wiener`, complete the 2FA step with the code from the email client, and capture all requests in Burp. The key endpoints are:

| Step                  | Endpoint       |
| --------------------- | -------------- |
| Password verification | `POST /login`  |
| 2FA code request      | `GET /login2`  |
| 2FA code submission   | `POST /login2` |
| Authenticated page    | `/my-account`  |

Send all three login-flow requests to Repeater.

**Step 2 — Force the server to generate a 2FA code for carlos**

In the `GET /login2` request (which triggers the server to generate and send a 2FA code), remove the session cookie and change the username parameter from `wiener` to `carlos`:

```
GET /login2
Cookie: verify=carlos
```

Send this request. The server generates a 2FA verification code and associates it with `carlos`, returning a `200` response. The session cookie here is not tied to authentication state — the `verify` parameter alone controls which account the code is generated for.

**Step 3 — Brute-force the 2FA code for carlos**

Now take the `POST /login2` request (the code submission), remove the session cookie, and change the username/verify parameter to `carlos`. Set the OTP value as the Intruder payload position:

```
POST /login2
Cookie: verify=carlos

mfa-code=§0000§
```

Configure Intruder with a **Sniper** attack. Set the payload to numbers from `0000` to `9999` (min/max integer digits: `4`, max fraction digits: `0`).

Start the attack. Sort by status code — a `302` redirect indicates the correct code was found.

**Step 4 — Open the session in the browser**

Right-click the `302` response in Intruder and select **Show response in browser**. Copy that URL and open it — Carlos's account page loads, completing the lab.

### Conclusion

The 2FA logic was flawed because the server used a user-controllable `verify` cookie to decide which account to generate and validate a code for, rather than tying this to a verified, server-side session. This allowed an attacker to generate a code for any username and then brute-force the short numeric code (only 10,000 possibilities) independently from a password.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-authentication-labs/lab-8.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
