Diário de Um Pentester

Manipulação de curto tempo de expiração de tokens de autorização

Como não perder um tempo precioso ao testar um aplicativo web ou API’s com Burp Suite

Em meus poucos anos fazendo pentesting web/API, foi a primeira vez que tive que pensar em como automatizar o processo de renovação de um token de autorização durante um bruteforcing com o Burp’s Intruder e ao usar o Burp’s Repeater para que eu não tenha que fazê-lo manualmente a cada dez minutos, que era o tempo de validade para o token neste cenário.

Bem, já que não vi nenhum post sobre esse cenário específico, decidi escrever um. Talvez possa ajudar as pessoas que possam estar em dificuldades como eu estive recentemente. Eu estava fazendo um pentest em uma API e ele tinha dois endpoints principais: um para obter um novo token de autorização e o outro para solicitar alguns dados usando este token. Abaixo você pode ver ambas as solicitações para esses endpoints:

Requisição ao endpoint responsável pela geração de um novo token de acesso para a API
Requisição ao endpoint que usa o token de acesso

O PROBLEMA

Como você pode ver na primeira imagem acima, temos uma janela muito pequena para interagir com a API antes de precisarmos de outro token por causa da propriedade “expires_in” no corpo de resposta. Na verdade, quando tentei executar o Intruder por mais de dez minutos, comecei a obter o código de status 401 (não autorizado). Infelizmente, quando eu estava testando a API, eu não tinha nenhuma intenção de escrever uma postagem de blog sobre isso, então uma vez que eu descobri isso, eu simplesmente corri o ataque novamente e todas as requisições que resultam em 401 foram reeditados. Sem printscreens aqui, desculpe…

A PRIMEIRA PARTE DA SOLUÇÃO

Assim que percebi que tinha que lidar com esse curto período de tempo antes de ter que solicitar um novo token, comecei a fazer o que todo bom pentester faz: implorar de joelhos para que o Google me trouxesse uma solução.

Brincadeiras à parte, eu sabia que o Burp tinha algo para lidar com sessões, mas eu nunca tinha usado antes, nem sabia onde essas opções estavam. Mesmo assim, não foi difícil encontrá-los:

Localização de “Regras  de Tratamento de Sessão” e “Macros” dentro da Burp Suite

Como podemos ver, as descrições são auto explicativas: as regras de manipulação de sessão definem, bem, regras. Eles são aplicados toda vez que uma requisição dentro do escopo dessa regra está sendo emitida. Vamos detalhar um pouco mais essa área:

REGRAS DE MANIPULAÇÃO DE SESSÕES

Esta área permite criar regras com escopo pré definido e elas serão executadas antes de cada solicitação que esteja no mesmo escopo. Ele pode ser usado para verificar a validade de uma sessão, adicionar cookies à requisição, realizar login. É importante notar que todas as regras são aplicadas na mesma ordem em que estão listadas, respeitando seus escopos, ou seja, se uma regra não estiver no escopo de uma determinada requisição, ela não será aplicada a essa requisição específica.

MACROS

Citando a descrição muito bem colocada:

Uma macro é uma sequência de uma ou mais requisições HTTP. Você pode usar macros dentro das regras de manipulação de sessão para executar tarefas como fazer login no aplicativo, obter tokens anti-CSRF, etc.

CONSTRUINDO A REGRA DE MANIPULAÇÃO DA SESSÃO

Sabendo como esses dois recursos funcionam, agora podemos começar a construir uma regra de sessão e uma macro para renovar nosso token de acesso. Primeiro vamos adicionar uma nova regra:

Adicionando uma nova regra de manipulação de sessão

Na imagem acima podemos ver uma área com uma breve descrição e quais ações ela executará uma vez chamada. Existe também a guia de escopo, como visto abaixo:

Definição de escopo para uma nova regra de sessão

Esta guia permite que você escolha em quais partes do Burp Suite esta regra será usada, para quais URLs eles podem ser aplicados, bem como restringir a regra apenas para solicitações que contenham parâmetros personalizados.

ADICIONANDO UMA AÇÃO DE REGRA

Uma vez definido o escopo de regra, vamos adicionar uma ação a ser executada quando esta for executada. Nós nomeamos a ação “A sessão de verificação é válida” e aqui é onde as coisas começam a ser reais:

Primeira parte do editor de ação para uma regra de manipulação de sessão

Vamos quebrar a explicação em duas partes:

Editor de ação de regras: primeira parte

  1. Primeiro, a ação precisa fazer uma requisição HTTP como o primeiro passo para validar a sessão. Aqui eu disse que quero emitir o mesmo pedido que está sendo validado, mas também poderia executar uma macro para fazer a mesma coisa se fosse o caso.
  2. Com que frequência, em termos de requisições, o Burp realizará a validação da sessão. Na imagem, podemos ver a cada 10 requisições, o que para este cenário é desnecessário, mas vamos manter assim de qualquer maneira.
  3. Onde inspecionar a resposta para verificar se a sessão é válida. Aqui podemos ver “cabeçalhos HTTP”, “Corpo de resposta” (nosso caso) e “URL do alvo de redirecionamento”.
  4. O que procurar ao inspecionar a resposta. No meu caso eu tive que procurar a string literal “401” no corpo de resposta, pois este era o comportamento que eu consegui quando o token expirou. Observe que também podemos procurar regex e case (in)sensitive.
  5. Por fim, para esta primeira parte, temos que indicar se uma correspondência significa que a sessão ainda é válida ou se é inválida. No meu caso, a sequência literal “401” significa que a sessão é inválida.

EDITOR DE AÇÃO DE REGRAS: SEGUNDA PARTE

Segunda parte do editor de ação para uma regra de manipulação de sessão

Esta segunda parte é dividida em duas:

  1. O que acontece se a sessão for válida/inválida: Se for válida, nenhuma outra regra ou ação será processada para essa solicitação. Se for inválida, escolhi executar uma macro, que veremos a seguir.
  2. Para a última parte, podemos atualizar a solicitação com parâmetros combinados a partir da resposta macro final e/ou atualizar a solicitação com cookies do frasco de cookies de manipulação de sessão.

A SEGUNDA PARTE DA SOLUÇÃO

Agora, note a última caixa de seleção na imagem acima. Eu posso, depois de executar a macro, invocar um manipulador de ação Burp Extension. O que o ID faz é passar os pedidos da macro para a extensão e ele vai fazer algo com eles.

Agora, você pode me dizer por que eu preciso de uma extensão para ser chamado em primeiro lugar se eu tenho todo um sistema para lidar com sessões? Bem, se você olhar de perto, nenhum dos pedidos realmente tem sessões porque eles não usam cookies de sessão para lidar com a autorização. Tudo o que temos é o cabeçalho Autorização: Bearer com um grande base64 depois dele, que é o token real.

Então, depois de toda essa viagem podemos ver que o Burp não tem (pelo menos ainda não) um processo embutido para lidar com esse tipo de necessidade: preciso do conteúdo de um cabeçalho da solicitação para ser substituído por parte do conteúdo da resposta da macro.  Ainda bem que o Burp tem essa incrível capacidade de integrar extensões para preencher essas lacunas.

Então, para esta necessidade específica, há uma extensão burp chamada “Custom Parameter Handler” ou CPH. O que ele faz é “modificar mensagens HTTP com precisão cirúrgica, mesmo quando se usa macros”. Mais precisamente para o meu cenário, permite, entre outras coisas, pesquisar e substituir pedidos e respostas internas.

Mas antes de mergulharmos nas configurações da extensão, temos que ver o que essa coisa macro faz, porque vamos precisar desse conhecimento em breve.

CONFIGURANDO UMA MACRO

Gravando macros em Burp Suite

Na imagem acima podemos ver a janela principal para gravar e configurar uma macro. Como eu disse anteriormente, uma macro é um grupo de pedidos que são emitidos em ordem. Além disso, podemos passar partes da resposta de uma solicitação para a próxima até termos uma resposta HTTP final. No meu caso, todos os pedidos aqui listados serão passados para a extensão cph.

Primeiro temos que gravar a macro, ou seja, selecionar na guia de histórico http proxy todas as solicitações que queremos que façam parte da macro. No meu caso, é apenas o que gera um novo token de acesso:

Gravando uma macro em Burp Suite

Poderíamos, se quiséssemos, configurar cada solicitação macro para obter todos os parâmetros necessários das respostas e passá-los para a próxima solicitação:

Configurando uma solicitação de macro para lidar com parâmetros e cookies

Embora eu não esteja indo muito fundo nesta parte, esta janela permite que você adicione e use cookies de cada resposta ao frasco de cookie de manipulação da sessão para que eles possam ser usados na próxima solicitação. Além disso, podemos especificar parâmetros com muita precisão. O Burp obterá os parâmetros configurados aqui e os passará para a próxima solicitação da macro.

Então, agora você pode ver que não temos nenhuma opção para substituir os valores do cabeçalho da resposta da macro em nossas solicitações reais. É por isso que precisamos usar a extensão CPH. Vamos finalmente ver a magia:

CONFIGURAÇÃO DA EXTENSÃO CPH

Vamos quebrar essa explicação em três partes. Este primeiro lidará com as opções de CPH:

Opções de CPH
  1. A guia CPH aparecerá assim que você instalar a extensão.
  2. Nele podemos ver a guia de opções. Lá podemos economizar/carregar ou importar/exportar uma configuração e também podemos definir as ferramentas burp com as qual a extensão funcionará.

A segunda parte trata da criação de guias:

Configurando uma nova guia CPH

Uma vez selecionado “Depois de executar a macro, invoque uma caixa de seção de extensão Burp” na última parte do editor de ação de manipulação da sessão, uma guia CPH é criada automaticamente para lidar com a solicitação da macro. A primeira parte da guia, vamos nomeá-la e definir o escopo de uso dentro das URL’s que estão no escopo do Burp.

A terceira parte é a magia:

Extraindo uma sequência de uma resposta e substituindo uma sequência da solicitação original com ela
  1. Aqui configuramos um regex para pesquisar a sequência para ser substituído na solicitação original. Observe que o regex começa com “ey”. Ele corresponderá exatamente ao token de acesso (um JWT) que expirou.
  2. A primeira sequência encontrada pelo regex em (1) será substituída pelo conteúdo de um segundo regex. Neste caso, “\g<jwt>” refere-se a um grupo chamado regex chamado “jwt”, que veremos em (4).
  3. Se eu verificar a caixa “O valor que eu preciso é dinâmico”, a opção número quatro fica disponível. Queremos usá-lo porque toda vez que emitimos o pedido, um novo token é gerado.
  4. Finalmente, quando a solicitação de macro é emitida, essa pesquisa regex é realizada para extrair o token de acesso recém-recebido. Note que eu começo o regex com (? P<jwt>[…] Aqui estou nomeando o grupo regex definido pelo par de parênteses, que neste caso correspondem a todo o token.

Assim, o valor extraído da resposta pela pesquisa regex (4) é usado para substituir o antigo token de acesso (2). Dessa forma, posso até emitir uma solicitação ao ponto final principal da API com um JWT inválido e a solicitação ainda funcionará porque em segundo plano essa extensão estará funcionando sua mágica.

CONCLUSÃO

A conclusão aqui é que o Burp Suite é muito mais poderoso do que você e eu podemos imaginar. E eu nem uso todo o seu poder. E só para ficar claro, este post não é patrocinado pela PortSwigger de forma alguma. Só estou dizendo um fato. Eles estão fazendo um bom trabalho com esta ferramenta.