Skip to main content

🗂️PortSwigger Lab Writeup: 2FA Broken Login

PortSwigger lab banner: Broken 2FA login relying on client-side verify cookie PortSwigger lab banner: Broken 2FA login relying on client-side verify cookie


🎯 Objective

The objective of this lab is to exploit an multi-factor authentication weakness where the app does not implement any brute-force protection on multi-factor authentication page. The goal is to bypass the authentication of carlos and log in to the account.

  • Lab URL: https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-broken-logic
  • Category: Authentication
  • Difficulty: Practitioner

🧪 Exploitation Steps

🕵️Step 1: Observe the Website

  • Firstly open the lab URL in your browser, and observe what it is about and how it works. Lab homepage screenshot showing site layout
    Login page screenshot for the vulnerable application
  • At first glance, the website seems to be a blogging website with a login page. In the lab description, it is mentioned that we need to bruteforce the password of user - carlos and log in to account.

📝Step 2: Log in as wiener

  • Now we will first observe how multi-factor authentication works by logging in as wiener for which we have access to mails.
  • Enter the credentials wiener:peter in login page and send the request. Login attempt for user wiener (wiener) captured in Burp
  • Now, we are being redirected to /login2 page for entering OTP sent on mail.
  • Open the Email client, to access the wiener mails and retrieve the OTP. Email client view showing OTP sent to wiener
  • Enter the OTP - 1660 on 2FA page to complete the login. Repeater response showing OTP verification entered (1660)
  • After login completion, we are redirected to the user account page - /my-account?id=wiener Account page after successful 2FA for wiener

🧑‍💼Step 3: Log in as carlos

  • Now send the GET /login2 request from HTTP history to Repeater through Ctrl + R Repeater capture of GET /login2 request from HTTP history
  • Change the cookie verify:wiener to verify:carlos and send the request to generate the 2FA code. Request with cookie changed from verify to verify in Repeater
  • Now send the POST /login2 request from HTTP history to Intruder through Ctrl + I Intruder capture of POST /login2 request ready for attack
  • Change the cookie verify:wiener to verify:carlos to crack the 2FA code for carlos
  • Add the marker on mfa-code value and set the attack type to Sniper. Intruder marker placed on mfa-code field (Sniper attack)
  • In payloads section, set the payload type to Brute forcer
  • Set the character set to 0123456789 and Min/Max length to 4 as mfa code is of 4 digit. Intruder brute-force settings: digits charset 0-9 and length 4
  • After configuring everything, start the attack. Intruder results highlighting 302 Found redirect for successful MFA code guess
  • In all the payloads, you will see a unique response 302 Found which means we have successfully cracked the MFA code for carlos
  • Enter the credentials carlos:montoya in login page and send the request. Login form filled with carlos credentials (carlos)
  • Now change the URL from /login2 to /myaccount?id=carlos
  • Hence, we are now successfully being logged in as carlos without completing 2FA.
  • Now, Right-click on this request and select Show response in browser. Copy the URL and load it in the browser. Browser view of account page after navigating to /myaccount?id=carlos without completing 2FA
  • And Finally, the Lab is solved.

🧠 Conclusion

  • This lab involves a broken 2FA implementation, where the verify:<username> cookie and OTP challenge handling are trusted client-side and the /login2 endpoint does not enforce server-side session binding or rate-limiting for MFA attempts.
  • Since the application accepts/relies on a client-supplied challenge identifier and lacks OTP brute-force protection, an attacker can tamper the cookie and repeatedly guess codes for another account.
  • By changing verify:wienerverify:carlos and using Intruder to brute-force the 4-digit OTP (detecting success via a 302 Found redirect), we bypassed 2FA and accessed carlos’s account.