Skip to main content

Low entropy of password reset token leads to account takeover

Illustration of Low entropy of password reset token leads to account takeover
Kamil Szczurowski

Introduction

During a recent security audit, something related to password reset functionality caught my attention. It appealed that password reset tokens generated for a given account in the same second were always the same. Such behaviour suggested that password reset token is generated from a few factors, but only one of them – time wasn’t static.

Discovery and verification

The first sign of weak password reset token entropy was the fact that tokens generated for the same user during the same second were the same. That meant that time was the only factor that changed in the token itself. Other factors were always the same and either static or related to a given user. With that discovery, I began investigating further how the token could be constructed.

The first step was to obtain a valid timestamp that was used by the web server. In order to do that, I sent the following HTTP request that requested password reset action:

Password reset request

Server confirmed that password reset token was sent and returned date in its header:

Server response

The date returned by the server will be used in further steps – it would be the one used in the process of generating the password reset token.

The reset token received in the e-mail was:

Reset token

The reset token was a result of a MD5 hashing function, so the first thing that I’ve checked was conjunctions of timestamp/date with just an e-mail address. Results unluckily weren’t positive – generated token must’ve had at least a third factor. An example of some tried conjunctions are shown below:

Tried conjunctions

Knowing that there’s a third unknown factor, we’ll use “advanced password recovery” software, which is hashcat. Provided that we know part of the original string, we’ll use a combinatory attack mode that will combine two dictionaries – the first dictionary will consist of known permutations of date and e-mail address, the second will be just a standard dictionary used to break hashes (in this example rockyou.txt). The final command is presented below:

Hashcat command

After running the command, I noticed that hashcat successfully broke the hash:

Hashcat success

It’s visible that third factor was just a word secret.

The tested application creates a token from three factors – user’s e-mail address, time of password reset request response and pepper (which is a secret added to an input during hashing with a cryptographic hash function). In this case, developers choose secret to be a dictionary word, which is fairly easy to crack.

In order to verify that the vulnerability was identified correctly and identified password reset token structure is correct, I tried to exploit the whole process and gain access to my test account, by generating new password reset token and creating it from scratch.

First, I issued a standard password reset request:

Password reset request

Then I copied the date from the response and transformed it into timestamp:

Timestamp conversion

After that, I created my own token and used MD5 hash function:

Token creation

The next step was verifying whether I will be able to successfully reset password with created token: Server responded with confirmation of password reset – confirming that vulnerability was properly identified and can be easily exploited:

Password reset confirmation

Server responded with confirmation of password reset – confirming that vulnerability was properly identified and can be easily exploited:

Password reset success

The last step was doing the same thing, but with the admin’s account. I requested password reset for an application admin account and was able to successfully reset its password – gaining the highest possible privileges in the application from an unauthorized user.

Recommendations

When generating password reset token ensure that generated tokens or codes are:

  • Randomly generated using a cryptographically safe algorithm
  • Sufficiently long to protect against brute-force attacks
  • Stored securely
  • Single use and expire after an appropriate period.

Other Insights

Illustration of Zero Auth to Admin: Exploiting Known Vulnerabilites in Real World Pen Tetsts

Zero Auth to Admin: Exploiting Known Vulnerabilites in Real World Pen Tetsts

Krystian Działowy

During an internal penetration test, I identified an unpatched MikroTik RouterOS device vulnerable to CVE-2018-14847. By exploiting this flaw in the Winbox service, I was able to extract administrator credentials without authentication and subsequently gained full read/write access via FTP and Winbox GUI. This vulnerability is particularly dangerous due to its low complexity and high impact - it allows complete device takeover with just network access to the Winbox service.

READ article
Illustration of Filter Injection via Microsoft Graph API in a Custom Application: From Verbose Errors to Account Takeover

Filter Injection via Microsoft Graph API in a Custom Application: From Verbose Errors to Account Takeover

Grzegorz Bronka

During a recent security assessment, it was identified that a client web application integrating Microsoft Entra through the Microsoft Graph API was vulnerable to a novel form of filter injection. This flaw originated in the password reset functionality, where user-supplied input was incorporated directly into Graph API queries without adequate sanitization or validation. Exploiting this weakness allowed bypassing password reset token validation, ultimately enabling unauthorized password resets for arbitrary user accounts. This article details the discovery process and demonstrates practical payloads used to exploit the issue.

READ article
Illustration of Using Malicious Discord Apps to Access User Data Through OAuth2 Permission Grants

Using Malicious Discord Apps to Access User Data Through OAuth2 Permission Grants

Martin Matyja

During a recent red team campaign, we discovered an unusual method of tricking users into potentially malicious activity. One of our client's domains had been forgotten and was still pointing to an IP address owned by a VPS provider. Someone else gained control of that IP by deploying their own VPS instance. As a result, they were able to perform a classic subdomain takeover attack and host their own content on the client's subdomain.

READ article
A professional cybersecurity consultant ready to assist with your inquiry.

Any questions?

Happy to get a call or email
and help!