On this page
2FA Broken Logic
Lab
2FA broken logic · Apprentice
Solution
Given
This lab's two-factor authentication is vulnerable due to its flawed logic. To solve the lab, access Carlos's account page.
Your credentials: wiener:peter
Victim's username: carlos
You also have access to the email server to receive your 2FA verification code.
Analyzing the task
There is broken 2FA logic on the site, we have our own account where we can look at how the mechanism works. To solve the lab, we need to access user carlos's page.
Recon
Let's go through the 2FA flow as our own user.
POST /login, with username and password in the body. Response + redirect to/login2:Set-Cookie: verify=wiener; HttpOnly Set-Cookie: session=EBdAlyofdB1mRMdQSvTDuKzeWSgj9t64; Secure; HttpOnly; SameSite=None- On
GET /login2there's a 2FA code input form. We enter it from email.POST /login2, with codemfa-code=1507in the body, and the cookie is sent:Cookie: session=EBdAlyofdB1mRMdQSvTDuKzeWSgj9t64; verify=wiener
The response is 302 — successful login.
Interestingly, the verify cookie is set at the first step, then at the second step there's a redirect to the code input page. Essentially this cookie tells the server which user the request is for, and we can swap it. Let's try calling GET /login2 with verify=carlos and thereby trigger generation of a 2FA code for him. Then, using a call to POST /login2, try to perform a brute-force attack on the code — its length is only 4 characters.
- We send a code-generation request
GET /login2forcarlosby settingverify=carlos. - We get the code input form, click submit code.
- A
POST /login2request flies out — we drop it into Intruder. - We choose the "Brute forcer" payload, set 4 characters.
- We add a variable to the request body:
mfa-code=§pwd§. - We launch the attack.
We look for the 302 redirect. We got the code — 0314. We send the request:
POST /login2
Cookie: session=MAEXN9XadoWSU7iCsN4RFiE6GEQnk1hs; verify=carlos
mfa-code=0314
The response is 302 with a new cookie. We take the session cookie, swap it in our browser, refresh the page.
Lab solved!
More in this category
Arbitrary Object Injection in PHP (PortSwigger Lab)
Recovering leaked source code and injecting a serialized CustomTemplate object whose __destruct deletes an arbitrary file.
Using Application Functionality to Exploit Insecure Deserialization (PortSwigger Lab)
Tampering with the `avatar_link` field in the session object to delete an arbitrary file via the account-delete feature.
Modifying Serialized Data Types (PortSwigger Lab)
Abusing PHP loose comparison by changing the `access_token` type to integer `0` to bypass authentication.