• PT/BR
  • ENG/US
Alto Contraste + Aumentar fonte - Diminuir fonte

Nesse post iremos demonstrar a utilização da ferramenta open source frida para realizar o bypass do pinning, ato necessário para a resolução do CTF “Flick II” da Vulnhub.

Cenário: neste CTF temos como ponto de partida um aplicativo Android que se conecta a um servidor web. Por motivos de segurança este aplicativo possui pinning de certificado, isto é, o certificado do servidor está hardcoded no código do aplicativo. Por causa disto qualquer tentativa de fazer um ataque de man-in-the-middle na conexão https irá falhar, pois o certificado enviado para o aplicativo não será o do servidor.
Como nosso objetivo é atacar o servidor, existem diversas formas que podemos utilizar para bypassar esta proteção, como descompilar e recompilar o aplicativo removendo a checagem de pinning para poder analisar o tráfego com um proxy, ou mesmo analisar o código e montar as requests na mão. Ambas são válidas, porém neste write up proporemos uma solução diferente, utilizar a ferramenta frida para “hookar” o método que faz a validação do certificado, e garantir que este método aceite o certificado do nosso proxy, no caso o Burp.

Primeiro passo iremos descompilar o aplicativo e procurar a função que faz a validação do certificado, para esta etapa utilizamos a ferramenta jadx:

 

Felizmente os métodos não estão ofuscados e ficou fácil reconhecer que a função checkServerTrusted faz a validação do certificado, no caso ela não retorna nada (função void) se o certificado for válido, caso contrário ela causa uma exceção, que acaba por travar a execução do aplicativo.

A ideia então é bem simples, vamos garantir que este método retorne void, sem que este faça nenhuma verificação. Para isto iremos utilizar uma ferramenta de instrumentação chamada frida.

O primeiro passo é instalar a ferramenta, que pode ser realizado através do pip com o comando “pip install frida-tools”.

Agora, precisamos indicar ao frida qual pacote e qual classe ele irá hookar (permitindo assim que ele modifique o comportamento do método), para isso precisamos de 4 informações:

  • Nome do pacote
  • Nome da classe
  • Nome e quantidade de parâmetros da função

Temos essas 4 informações no código da imagem 1, de forma que podemos gerar o seguinte javascript (que iremos chamar de pinning.js) para ser utilizado com o frida:

Estamos avisando o frida para utilizar a classe PubKeyManager, para isso, passamos os parâmetros p1 e p2 (não importa o tipo deles, pois não iremos utilizá-los para nada). No caso o send é um método do frida usado para avisar que a função foi de fato chamada (facilitando assim o nosso debug), e por fim estamos fazendo ela retornar sem ter feito nenhuma checkagem.

 

Agora precisamos fazer com que o frida rode no Android, para isto temos duas opções, podemos adicionar a biblioteca do frida na própria aplicação, para tal seria necessários descompilar a aplicação, adicioná-la a biblioteca e por fim recompilar/reassinar o apk. É justamente este tipo de trabalho que estamos tentando evitar, por isso vamos optar pela segunda opção, que é simplesmente instalar o serviço do frida em um android rooteado.

No caso estamos utilizando um Android emulado que já está rooteado, faltando apenas encontrar a versão do frida que seja compatível com a nossa versão do Android.

Buscamos em: https://github.com/frida/frida/releases e encontramos a versão frida-server-12.7.4-android-arm64

Agora utilizaremos o adb para conectar com nosso android, enviar o arquivo e instalá-lo, de forma padrão os passos são sempre estes, mudando apenas o nome do arquivo:

Passo 1) Enviar o arquivo
root@localhost:~/Downloads# adb push frida-server-12.7.4-android-arm64 /data/local/tmp/frida-server

Passo 2) Acessamos o android (já estamos como root, caso não esteja executar “adb root” primeiro)
root@localhost:~/Downloads# adb shell

Passo 3) Damos permissão de execução para o Frida-server
dream2lte:/ # cd /data/local/tmp
dream2lte:/data/local/tmp # chmod 777 frida-server 

Passo 4) Executamos o Frida-server em modo Daemon
dream2lte:/data/local/tmp # frida-server -D

Por fim voltamos ao nosso terminal para executar o frida avisando qual pacote ele deve infiltrar e qual script ele deve executar

Sintaxe: frida –U –f NOME_DO_PACOTE –l NOME_DO_SCRIPT

 

 

Último passo é digitar %resume para finalmente rodar o script, e temos como saída a mensagem que criamos no script “Pinnning Bypassed =)”

A partir de agora podemos utilizar nosso Burp como se a aplicação não tivesse nenhuma proteção de pinning

Vantagens desse método de bypass:

  • Caso a aplicação seja atualizada com novas funcionalidades, mas o método de pinning não mude, você conseguirá bypassa-lo utilizando o mesmo script, evitando retrabalho
  • A função de bypass servirá para todas funções iguais, como muito código é copiado da internet e reutilizado, a função que você utiliza pode servir para diversos aplicativos
  • Continuando a ideia acima, se você criar a função para bypass de uma biblioteca que utiliza pinning (como do okhttp por exemplo), sua função de bypass funcionará para todos aplicativos que utilizem essa mesma biblioteca

 

Como extra: caso esteja encontrando dificuldades em continuar o CTF e executar os comandos no servidor (que são filtrados) uma maneira simples de bypass é simplesmente concatenar os comandos utilizando aspas simples, então um ls se torna l’s e será executado como ls no servidor.

Links das ferramentas utilizadas: 

CTF: https://www.vulnhub.com/entry/flick-2,122/
Frida: https://www.vulnhub.com/entry/flick-2,122/
Burp: https://portswigger.net/burp

Caso queira aprender mais sobre engenharia reversa utilizando o Frida e o badada (ferramenta excelente que facilita o uso do frida) recomendo fortemente a leitura do seguinte blog post: https://www.sidi.org.br/facilitando-a-engenharia-reversa-de-android-com-badada/

Agradecimentos a todos os responsáveis pelas tools e pelo CTF.

 

#SejaSiDier

Faça parte do nosso universo tecnológico
Trabalhe no SiDi
Top