OAuth to Account takeover
Last updated
Last updated
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
OAuth oferece várias versões, com insights fundamentais acessíveis na documentação do OAuth 2.0. Esta discussão centra-se principalmente no amplamente utilizado tipo de concessão de código de autorização do OAuth 2.0, fornecendo um quadro de autorização que permite que um aplicativo acesse ou execute ações na conta de um usuário em outro aplicativo (o servidor de autorização).
Considere um site hipotético https://example.com, projetado para exibir todas as suas postagens em redes sociais, incluindo as privadas. Para alcançar isso, o OAuth 2.0 é empregado. https://example.com solicitará sua permissão para acessar suas postagens em redes sociais. Consequentemente, uma tela de consentimento aparecerá em https://socialmedia.com, delineando as permissões solicitadas e o desenvolvedor que faz a solicitação. Após sua autorização, https://example.com ganha a capacidade de acessar suas postagens em seu nome.
É essencial compreender os seguintes componentes dentro do quadro do OAuth 2.0:
proprietário do recurso: Você, como o usuário/entidade, autoriza o acesso ao seu recurso, como suas postagens em redes sociais.
servidor de recursos: O servidor que gerencia solicitações autenticadas após o aplicativo ter obtido um access token
em nome do proprietário do recurso
, por exemplo, https://socialmedia.com.
aplicativo cliente: O aplicativo que busca autorização do proprietário do recurso
, como https://example.com.
servidor de autorização: O servidor que emite access tokens
para o aplicativo cliente
após a autenticação bem-sucedida do proprietário do recurso
e a obtenção de autorização, por exemplo, https://socialmedia.com.
client_id: Um identificador público e único para o aplicativo.
client_secret: Uma chave confidencial, conhecida apenas pelo aplicativo e pelo servidor de autorização, usada para gerar access_tokens
.
response_type: Um valor que especifica o tipo de token solicitado, como code
.
scope: O nível de acesso que o aplicativo cliente
está solicitando do proprietário do recurso
.
redirect_uri: A URL para a qual o usuário é redirecionado após a autorização. Isso geralmente deve estar alinhado com a URL de redirecionamento pré-registrada.
state: Um parâmetro para manter dados durante a redireção do usuário para e do servidor de autorização. Sua singularidade é crítica para servir como um mecanismo de proteção CSRF.
grant_type: Um parâmetro que indica o tipo de concessão e o tipo de token a ser retornado.
code: O código de autorização do servidor de autorização
, usado em conjunto com client_id
e client_secret
pelo aplicativo cliente para adquirir um access_token
.
access_token: O token que o aplicativo cliente usa para solicitações de API em nome do proprietário do recurso
.
refresh_token: Permite que o aplicativo obtenha um novo access_token
sem solicitar novamente ao usuário.
O fluxo real do OAuth prossegue da seguinte forma:
Você navega até https://example.com e seleciona o botão “Integrar com Redes Sociais”.
O site então envia uma solicitação para https://socialmedia.com pedindo sua autorização para permitir que o aplicativo de https://example.com acesse suas postagens. A solicitação é estruturada como:
Você é então apresentado a uma página de consentimento.
Após sua aprovação, a Social Media envia uma resposta para o redirect_uri
com os parâmetros code
e state
:
https://example.com utiliza este code
, juntamente com seu client_id
e client_secret
, para fazer uma solicitação do lado do servidor para obter um access_token
em seu nome, permitindo o acesso às permissões que você consentiu:
Finalmente, o processo conclui-se quando https://example.com utiliza seu access_token
para fazer uma chamada de API para a Rede Social para acessar
O redirect_uri
é crucial para a segurança em implementações de OAuth e OpenID, pois direciona para onde dados sensíveis, como códigos de autorização, são enviados após a autorização. Se mal configurado, pode permitir que atacantes redirecionem essas solicitações para servidores maliciosos, possibilitando a tomada de conta.
As técnicas de exploração variam com base na lógica de validação do servidor de autorização. Elas podem variar desde correspondência estrita de caminho até aceitar qualquer URL dentro do domínio ou subdiretório especificado. Métodos comuns de exploração incluem redirecionamentos abertos, travessia de caminho, exploração de regex fracas e injeção de HTML para roubo de token.
Além do redirect_uri
, outros parâmetros de OAuth e OpenID, como client_uri
, policy_uri
, tos_uri
e initiate_login_uri
, também são suscetíveis a ataques de redirecionamento. Esses parâmetros são opcionais e seu suporte varia entre os servidores.
Para aqueles que visam um servidor OpenID, o endpoint de descoberta (**.well-known/openid-configuration**
) frequentemente lista detalhes de configuração valiosos, como registration_endpoint
, request_uri_parameter_supported
e "require_request_uri_registration
. Esses detalhes podem ajudar a identificar o endpoint de registro e outras especificidades de configuração do servidor.
Como mencionado neste relatório de bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html, pode ser possível que a URL de redirecionamento esteja sendo refletida na resposta do servidor após o usuário se autenticar, sendo vulnerável a XSS. Payload possível para testar:
Em implementações de OAuth, o uso indevido ou a omissão do state
parameter pode aumentar significativamente o risco de ataques de Cross-Site Request Forgery (CSRF). Essa vulnerabilidade surge quando o parâmetro state
é não utilizado, utilizado como um valor estático ou não validado corretamente, permitindo que atacantes contornem as proteções contra CSRF.
Os atacantes podem explorar isso interceptando o processo de autorização para vincular sua conta à conta de uma vítima, levando a possíveis account takeovers. Isso é especialmente crítico em aplicações onde o OAuth é usado para propósitos de autenticação.
Exemplos do mundo real dessa vulnerabilidade foram documentados em vários CTF challenges e hacking platforms, destacando suas implicações práticas. O problema também se estende a integrações com serviços de terceiros como Slack, Stripe e PayPal, onde os atacantes podem redirecionar notificações ou pagamentos para suas contas.
O manuseio e a validação adequados do state
parameter são cruciais para proteger contra CSRF e garantir o fluxo do OAuth.
Sem Verificação de Email na Criação da Conta: Os atacantes podem criar proativamente uma conta usando o email da vítima. Se a vítima usar posteriormente um serviço de terceiros para login, a aplicação pode inadvertidamente vincular essa conta de terceiros à conta pré-criada do atacante, levando ao acesso não autorizado.
Explorando a Verificação de Email Laxa do OAuth: Os atacantes podem explorar serviços de OAuth que não verificam emails registrando-se com seu serviço e, em seguida, alterando o email da conta para o da vítima. Esse método também arrisca o acesso não autorizado à conta, semelhante ao primeiro cenário, mas através de um vetor de ataque diferente.
Identificar e proteger parâmetros secretos do OAuth é crucial. Enquanto o client_id
pode ser divulgado com segurança, revelar o client_secret
apresenta riscos significativos. Se o client_secret
for comprometido, os atacantes podem explorar a identidade e a confiança da aplicação para roubar access_tokens
de usuários e informações privadas.
Uma vulnerabilidade comum surge quando as aplicações lidam erroneamente com a troca do code
de autorização por um access_token
no lado do cliente em vez do lado do servidor. Esse erro leva à exposição do client_secret
, permitindo que os atacantes gerem access_tokens
sob a aparência da aplicação. Além disso, através de engenharia social, os atacantes poderiam escalar privilégios adicionando escopos adicionais à autorização do OAuth, explorando ainda mais o status de confiança da aplicação.
Você pode tentar bruteforce o client_secret de um provedor de serviços com o provedor de identidade para tentar roubar contas. A solicitação para BF pode parecer semelhante a:
Uma vez que o cliente tenha o code e state, se eles forem refletidos dentro do cabeçalho Referer quando ele navegar para uma página diferente, então está vulnerável.
Vá para o histórico do navegador e verifique se o access token está salvo lá.
O authorization code deve viver apenas por algum tempo para limitar a janela de tempo onde um atacante pode roubá-lo e usá-lo.
Se você conseguir o authorization code e usá-lo com um cliente diferente, então você pode assumir outras contas.
Neste relatório de bug bounty: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ você pode ver que o token que AWS Cognito devolve ao usuário pode ter permissões suficientes para sobrescrever os dados do usuário. Portanto, se você puder mudar o email do usuário para um email de usuário diferente, você pode ser capaz de assumir outras contas.
Para mais informações detalhadas sobre como abusar do AWS cognito, consulte:
Como mencionado neste artigo, fluxos de OAuth que esperam receber o token (e não um código) podem ser vulneráveis se não verificarem se o token pertence ao aplicativo.
Isso ocorre porque um atacante poderia criar um aplicativo que suporta OAuth e faz login com o Facebook (por exemplo) em seu próprio aplicativo. Então, uma vez que uma vítima faça login com o Facebook no aplicativo do atacante, o atacante poderia obter o token OAuth do usuário dado ao seu aplicativo e usá-lo para fazer login no aplicativo OAuth da vítima usando o token do usuário da vítima.
Portanto, se o atacante conseguir fazer com que o usuário acesse seu próprio aplicativo OAuth, ele poderá assumir a conta da vítima em aplicativos que esperam um token e não estão verificando se o token foi concedido ao ID do seu aplicativo.
De acordo com este artigo, foi possível fazer com que uma vítima abrisse uma página com um returnUrl apontando para o host do atacante. Essa informação seria armazenada em um cookie (RU) e em um passo posterior o prompt perguntaria ao usuário se ele deseja conceder acesso ao host do atacante.
Para contornar esse prompt, foi possível abrir uma aba para iniciar o fluxo Oauth que definiria esse cookie RU usando o returnUrl, fechar a aba antes que o prompt fosse exibido e abrir uma nova aba sem esse valor. Assim, o prompt não informará sobre o host do atacante, mas o cookie seria definido para ele, então o token será enviado para o host do atacante na redireção.
Como explicado em este vídeo, algumas implementações de OAuth permitem indicar o parâmetro prompt
GET como None (&prompt=none
) para evitar que os usuários sejam solicitados a confirmar o acesso concedido em um prompt na web se já estiverem logados na plataforma.
Como explicado neste vídeo, pode ser possível indicar o parâmetro response_mode
para indicar onde você deseja que o código seja fornecido na URL final:
response_mode=query
-> O código é fornecido dentro de um parâmetro GET: ?code=2397rf3gu93f
response_mode=fragment
-> O código é fornecido dentro do parâmetro de fragmento da URL #code=2397rf3gu93f
response_mode=form_post
-> O código é fornecido dentro de um formulário POST com um input chamado code
e o valor
response_mode=web_message
-> O código é enviado em uma mensagem post: window.opener.postMessage({"code": "asdasdasd...
De acordo com este post de blog, este é um fluxo OAuth que permite fazer login no OAuth via nome de usuário e senha. Se durante esse fluxo simples um token com acesso a todas as ações que o usuário pode realizar for retornado, então é possível contornar a 2FA usando esse token.
Este post de blog comenta como foi possível abusar de um redirecionamento aberto para o valor do referenciador para abusar do OAuth para ATO. O ataque foi:
A vítima acessa a página da web do atacante
A vítima abre o link malicioso e um opener inicia o fluxo OAuth do Google com response_type=id_token,code&prompt=none
como parâmetros adicionais usando como referenciador o site do atacante.
No opener, após o provedor autorizar a vítima, ele os envia de volta para o valor do parâmetro redirect_uri
(web da vítima) com código 30X que ainda mantém o site do atacante no referer.
O site da vítima aciona o redirecionamento aberto com base no referenciador, redirecionando o usuário da vítima para o site do atacante, como o respose_type
era id_token,code
, o código será enviado de volta ao atacante no fragmento da URL, permitindo que ele assuma a conta do usuário via Google no site da vítima.
Verifique esta pesquisa Para mais detalhes sobre esta técnica.
O Registro Dinâmico de Clientes no OAuth serve como um vetor menos óbvio, mas crítico para vulnerabilidades de segurança, especificamente para ataques de Server-Side Request Forgery (SSRF). Este endpoint permite que servidores OAuth recebam detalhes sobre aplicativos clientes, incluindo URLs sensíveis que podem ser exploradas.
Pontos-chave:
O Registro Dinâmico de Clientes é frequentemente mapeado para /register
e aceita detalhes como client_name
, client_secret
, redirect_uris
e URLs para logotipos ou Conjuntos de Chaves Web JSON (JWKs) via solicitações POST.
Este recurso adere às especificações estabelecidas em RFC7591 e OpenID Connect Registration 1.0, que incluem parâmetros potencialmente vulneráveis a SSRF.
O processo de registro pode inadvertidamente expor servidores a SSRF de várias maneiras:
logo_uri
: Uma URL para o logotipo do aplicativo cliente que pode ser buscada pelo servidor, acionando SSRF ou levando a XSS se a URL for mal manipulada.
jwks_uri
: Uma URL para o documento JWK do cliente, que se for maliciosamente elaborado, pode fazer com que o servidor faça solicitações externas para um servidor controlado pelo atacante.
sector_identifier_uri
: Referencia um array JSON de redirect_uris
, que o servidor pode buscar, criando uma oportunidade de SSRF.
request_uris
: Lista as URIs de solicitação permitidas para o cliente, que podem ser exploradas se o servidor buscar essas URIs no início do processo de autorização.
Estratégia de Exploração:
SSRF pode ser acionado registrando um novo cliente com URLs maliciosas em parâmetros como logo_uri
, jwks_uri
ou sector_identifier_uri
.
Embora a exploração direta via request_uris
possa ser mitigada por controles de lista branca, fornecer um request_uri
pré-registrado e controlado pelo atacante pode facilitar SSRF durante a fase de autorização.
Se a plataforma que você está testando é um provedor OAuth leia isso para testar possíveis Condições de Corrida.
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)