hacktricks/pentesting-web/oauth-to-account-takeover.md

20 KiB

OAuth to Account takeover

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

{% embed url="https://websec.nl/" %}

Informações Básicas

OAuth oferece várias versões, com insights fundamentais acessíveis em OAuth 2.0 documentation. Esta discussão centra-se principalmente no amplamente utilizado OAuth 2.0 authorization code grant type, fornecendo uma estrutura de autorização que permite a um aplicativo acessar ou realizar 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 nas redes sociais, incluindo as privadas. Para conseguir isso, é empregado o OAuth 2.0. https://example.com solicitará sua permissão para acessar suas postagens nas redes sociais. Consequentemente, uma tela de consentimento aparecerá em https://socialmedia.com, detalhando as permissões solicitadas e o desenvolvedor que está fazendo 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 da estrutura do OAuth 2.0:

  • resource owner: Você, como usuário/entidade, autoriza o acesso ao seu recurso, como as postagens da sua conta de rede social.
  • resource server: O servidor que gerencia as solicitações autenticadas após o aplicativo ter garantido um access token em nome do resource owner, por exemplo, https://socialmedia.com.
  • client application: O aplicativo que busca autorização do resource owner, como https://example.com.
  • authorization server: O servidor que emite access tokens para o client application após a autenticação bem-sucedida do resource owner e a obtenção da 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 especificando o tipo de token solicitado, como code.
  • scope: O nível de acesso que o client application está solicitando do resource owner.
  • redirect_uri: A URL para a qual o usuário é redirecionado após a autorização. Esta geralmente deve alinhar-se com a URL de redirecionamento pré-registrada.
  • state: Um parâmetro para manter dados durante o redirecionamento do usuário para e do servidor de autorização. Sua singularidade é crítica para servir como um mecanismo de proteção contra CSRF.
  • grant_type: Um parâmetro indicando o tipo de concessão e o tipo de token a ser retornado.
  • code: O código de autorização do authorization server, usado em conjunto com client_id e client_secret pelo client application para adquirir um access_token.
  • access_token: O token que o client application usa para solicitações de API em nome do resource owner.
  • refresh_token: Permite que o aplicativo obtenha um novo access_token sem solicitar novamente ao usuário.

Fluxo

O fluxo real do OAuth procede da seguinte forma:

  1. Você navega para https://example.com e seleciona o botão “Integrar com Redes Sociais”.
  2. 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:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
  1. Você é então apresentado a uma página de consentimento.
  2. 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?code=uniqueCode123&state=randomString123
  1. https://example.com utiliza este code, junto 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 acesso às permissões às quais você consentiu:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
  1. Finalmente, o processo conclui quando https://example.com emprega seu access_token para fazer uma chamada de API para Social Media para acessar

Vulnerabilidades

Open redirect_uri

O redirect_uri é crucial para a segurança em implementações OAuth e OpenID, pois direciona 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 a 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 de redirect_uri, outros parâmetros 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 servidores.

Para aqueles que visam um servidor OpenID, o endpoint de descoberta (**.well-known/openid-configuration**) frequentemente lista detalhes valiosos de configuração 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.

XSS na implementação de redirecionamento

Como mencionado neste relatório de bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html pode ser possível que o URL de redirecionamento esteja sendo refletido na resposta do servidor após a autenticação do usuário, sendo vulnerável a XSS. Possível payload para testar:

https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>

CSRF - Improper handling of state parameter

Em implementações OAuth, o uso indevido ou a omissão do parâmetro state pode aumentar significativamente o risco de ataques de Cross-Site Request Forgery (CSRF). Essa vulnerabilidade surge quando o parâmetro state é não utilizado, usado como um valor estático ou não validado corretamente, permitindo que atacantes contornem as proteções CSRF.

Os atacantes podem explorar isso interceptando o processo de autorização para vincular sua conta à conta da vítima, levando a potenciais sequestros de conta. Isso é especialmente crítico em aplicações onde o OAuth é usado para fins de autenticação.

Exemplos reais dessa vulnerabilidade foram documentados em vários desafios CTF e plataformas de hacking, 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 parâmetro state são cruciais para proteger contra CSRF e garantir a segurança do fluxo OAuth.

Pre Account Takeover

  1. Sem Verificação de Email na Criação de Conta: Atacantes podem criar uma conta antecipadamente usando o email da vítima. Se a vítima posteriormente usar um serviço de terceiros para login, a aplicação pode inadvertidamente vincular essa conta de terceiros à conta pré-criada pelo atacante, levando a acesso não autorizado.
  2. Explorando Verificação de Email Laxa do OAuth: Atacantes podem explorar serviços 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 apresenta riscos semelhantes de acesso não autorizado, semelhante ao primeiro cenário, mas através de um vetor de ataque diferente.

Disclosure of Secrets

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 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 OAuth, explorando ainda mais o status confiável da aplicação.

Client Secret Bruteforce

Você pode tentar bruteforce do client_secret de um provedor de serviços com o provedor de identidade para tentar roubar contas.
A solicitação para BF pode ser semelhante a:

POST /token HTTP/1.1
content-type: application/x-www-form-urlencoded
host: 10.10.10.10:3000
content-length: 135
Connection: close

code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]

Referer Header vazando Code + State

Uma vez que o cliente tenha o code e state, se eles forem refletidos dentro do cabeçalho Referer quando ele navega para uma página diferente, então está vulnerável.

Access Token Armazenado no Histórico do Navegador

Vá para o histórico do navegador e verifique se o access token está salvo lá.

Everlasting Authorization Code

O authorization code deve viver apenas por algum tempo para limitar a janela de tempo onde um atacante pode roubá-lo e usá-lo.

Authorization/Refresh Token não vinculado ao cliente

Se você conseguir o authorization code e usá-lo com um cliente diferente, então você pode tomar conta de outras contas.

Happy Paths, XSS, Iframes & Post Messages para vazar valores de code & state

Confira este post

AWS Cognito

Neste relatório de bug bounty: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ você pode ver que o token que o AWS Cognito retorna para o usuário pode ter permissões suficientes para sobrescrever os dados do usuário. Portanto, se você puder alterar o email do usuário para um email de outro usuário, você pode ser capaz de tomar conta de outras contas.

# Read info of the user
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]

# Change email address
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
{
"CodeDeliveryDetailsList": [
{
"Destination": "i***@f***.com",
"DeliveryMedium": "EMAIL",
"AttributeName": "email"
}
]
}

Para mais informações detalhadas sobre como abusar do AWS cognito, confira:

{% embed url="https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum" %}

Abusando de tokens de outros Apps

Como mencionado neste artigo, fluxos OAuth que esperam receber o token (e não um código) podem ser vulneráveis se não verificarem que o token pertence ao aplicativo.

Isso ocorre porque um atacante poderia criar uma aplicação suportando OAuth e fazer login com Facebook (por exemplo) em sua própria aplicação. Então, uma vez que uma vítima faça login com Facebook na aplicação do atacante, o atacante poderia obter o token OAuth do usuário dado à sua aplicação e usá-lo para fazer login na aplicação OAuth da vítima usando o token do usuário da vítima.

{% hint style="danger" %} Portanto, se o atacante conseguir que o usuário acesse sua própria aplicação OAuth, ele será capaz de tomar conta da conta da vítima em aplicações que esperam um token e não verificam se o token foi concedido ao ID do aplicativo deles. {% endhint %}

De acordo com este artigo, era possível fazer uma vítima abrir uma página com um returnUrl apontando para o host do atacante. Esta informação seria armazenada em um cookie (RU) e em um passo posterior o prompt perguntaria ao usuário se ele deseja dar acesso a esse host do atacante.

Para contornar este prompt, era possível abrir uma aba para iniciar o fluxo OAuth que definiria este cookie RU usando o returnUrl, fechar a aba antes que o prompt fosse mostrado, e abrir uma nova aba sem esse valor. Então, o prompt não informaria sobre o host do atacante, mas o cookie estaria definido para ele, então o token seria enviado para o host do atacante na redireção.

Bypass de Interação de Prompt

Como explicado neste vídeo, algumas implementações OAuth permitem indicar o parâmetro GET prompt como None (&prompt=none) para evitar que os usuários sejam solicitados a confirmar o acesso dado em um prompt na web se já estiverem logados na plataforma.

response_mode

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...

Parâmetros SSRFs

Confira esta pesquisa para mais detalhes desta técnica.

O Registro Dinâmico de Cliente 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:

  • Registro Dinâmico de Cliente é frequentemente mapeado para /register e aceita detalhes como client_name, client_secret, redirect_uris e URLs para logos ou Conjuntos de Chaves JSON Web (JWKs) via requisições POST.
  • Este recurso adere às especificações estabelecidas no 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 logo do aplicativo cliente que pode ser buscada pelo servidor, desencadeando SSRF ou levando a XSS se a URL for mal manipulada.
  • jwks_uri: Uma URL para o documento JWK do cliente, que se maliciosamente elaborada, pode fazer com que o servidor faça requisições externas para um servidor controlado pelo atacante.
  • sector_identifier_uri: Refere-se a um array JSON de redirect_uris, que o servidor pode buscar, criando uma oportunidade de SSRF.
  • request_uris: Lista URIs de requisiçã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 desencadeada registrando um novo cliente com URLs maliciosas em parâmetros como logo_uri, jwks_uri ou sector_identifier_uri.
  • Enquanto a exploração direta via request_uris pode 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.

Condições de Corrida de Provedores OAuth

Se a plataforma que você está testando é um provedor OAuth leia isto para testar possíveis Condições de Corrida.

Referências

{% embed url="https://websec.nl/" %}

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks: