Skip to content

MASTG-TECH-0011: Configurando um Proxy de Interceptação

Várias ferramentas suportam a análise de rede de aplicações que dependem do protocolo HTTP(S). As ferramentas mais importantes são os chamados proxies de interceptação; ZAP e Burp Suite são os mais famosos. Um proxy de interceptação oferece ao testador uma posição de Homem-no-Meio (MITM))). Essa posição é útil para ler e/ou modificar todas as requisições da aplicação e respostas do endpoint, que são usadas para testar Autorização, Gerenciamento de Sessão, etc.

Proxy de Interceptação para um Dispositivo Virtual

Configurando um Proxy Web em um Dispositivo Virtual Android (AVD)

O procedimento a seguir, que funciona no emulador Android que vem com o Android Studio 3.x, é para configurar um proxy HTTP no emulador:

  1. Configure seu proxy para escutar em localhost e, por exemplo, na porta 8080.
  2. Configure o proxy HTTP nas configurações do emulador:

    • Clique nos três pontos na barra de menu do emulador
    • Abra o menu Configurações
    • Clique na aba Proxy
    • Selecione Configuração manual de proxy
    • Digite "127.0.0.1" no campo Nome do Host e a porta do seu proxy no campo Número da porta (por exemplo, "8080")
    • Toque em Aplicar

As requisições HTTP e HTTPS agora devem ser roteadas através do proxy no computador host. Caso contrário, tente desligar e ligar o modo avião.

Um proxy para um AVD também pode ser configurado na linha de comando usando o comando emulator ao iniciar um AVD. O exemplo a seguir inicia o AVD Nexus_5X_API_23 e define um proxy para 127.0.0.1 na porta 8080.

emulator @Nexus_5X_API_23 -http-proxy 127.0.0.1:8080

Instalando um Certificado CA no Dispositivo Virtual

Uma maneira fácil de instalar um certificado CA é enviar o certificado para o dispositivo e adicioná-lo ao armazenamento de certificados através das Configurações de Segurança. Por exemplo, você pode instalar o certificado CA da PortSwigger (Burp) da seguinte forma:

  1. Inicie o Burp e use um navegador web no host para navegar até burp/, então faça o download de cacert.der clicando no botão "CA Certificate".
  2. Altere a extensão do arquivo de .der para .cer.
  3. Envie o arquivo para o emulador:

    adb push cacert.cer /sdcard/
    
  4. Navegue até Configurações -> Segurança -> Instalar a partir do cartão SD.

  5. Role para baixo e toque em cacert.cer.

Você então será solicitado a confirmar a instalação do certificado (também será solicitado que você defina um PIN do dispositivo se ainda não tiver feito isso).

Isso instala o certificado no armazenamento de certificados do usuário (testado na VM Genymotion). Para colocar o certificado no armazenamento raiz, você pode realizar os seguintes passos:

  1. Execute o adb como root com adb root e adb shell.
  2. Localize o certificado recém-instalado em /data/misc/user/0/cacerts-added/.
  3. Copie o certificado para a seguinte pasta /system/etc/security/cacerts/.
  4. Reinicie a VM Android.

Para Android 7.0 (nível de API 24) e superior, siga o mesmo procedimento descrito na seção "Contornando a Configuração de Segurança de Rede))".

Proxy de Interceptação para um Dispositivo Físico

As opções de configuração de rede disponíveis devem ser avaliadas primeiro. O dispositivo móvel usado para teste e o computador host executando o proxy de interceptação devem estar conectados à mesma rede Wi-Fi. Use um ponto de acesso (existente) ou crie uma rede wireless ad-hoc.

Uma vez que você tenha configurado a rede e estabelecido uma conexão entre o computador host de teste e o dispositivo móvel, vários passos ainda permanecem.

Após completar esses passos e iniciar a aplicação, as requisições devem aparecer no proxy de interceptação.

Um vídeo da configuração do ZAP com um dispositivo Android pode ser encontrado em secure.force.com.

Algumas outras diferenças: a partir do Android 8.0 (nível de API 26), o comportamento de rede da aplicação muda quando o tráfego HTTPS é tunelado através de outra conexão. E a partir do Android 9 (nível de API 28), o SSLSocket e SSLEngine se comportarão um pouco diferente em termos de tratamento de erros quando algo der errado durante os handshakes.

Como mencionado anteriormente, a partir do Android 7.0 (nível de API 24), o sistema operacional Android não confiará mais em certificados CA de usuário por padrão, a menos que especificado na aplicação. Na seção seguinte, explicamos dois métodos para contornar esse controle de segurança do Android.

Contornando a Configuração de Segurança de Rede

Nesta seção apresentaremos vários métodos para contornar a Configuração de Segurança de Rede do Android)).

Adicionando Certificados de Usuário Personalizados à Configuração de Segurança de Rede

Existem diferentes configurações disponíveis para a Configuração de Segurança de Rede para adicionar Autoridades Certificadoras não-sistema através do atributo src:

<certificates src=["system" | "user" | "raw resource"]
              overridePins=["true" | "false"] />

Cada certificado pode ser um dos seguintes:

  • "raw resource" é um ID apontando para um arquivo contendo certificados X.509
  • "system" para os certificados CA do sistema pré-instalados
  • "user" para certificados CA adicionados pelo usuário

Os certificados CA confiados pela aplicação podem ser um CA confiado pelo sistema, bem como um CA de usuário. Normalmente você já terá adicionado o certificado do seu proxy de interceptação como um CA adicional no Android. Portanto, focaremos na configuração "user", que permite forçar a aplicação Android a confiar nesse certificado com a seguinte Configuração de Segurança de Rede abaixo:

<network-security-config>
   <base-config>
      <trust-anchors>
          <certificates src="system" />
          <certificates src="user" />
      </trust-anchors>
   </base-config>
</network-security-config>

Para implementar essa nova configuração, você deve seguir os passos abaixo:

  • Descompile a aplicação usando uma ferramenta de descompilação como apktool:

    apktool d <filename>.apk
    
  • Faça a aplicação confiar em certificados de usuário criando uma Configuração de Segurança de Rede que inclua <certificates src="user" /> como explicado acima

  • Vá para o diretório criado pelo apktool ao descompilar a aplicação e reconstrua a aplicação usando apktool. O novo apk estará no diretório dist.

    apktool b
    
  • Você precisa reempacotar a aplicação, como explicado em " Reempacotamento de Apps". Para mais detalhes sobre o processo de reempacotamento, você também pode consultar a documentação do desenvolvedor Android, que explica o processo como um todo.

Note que, mesmo que este método seja bastante simples, sua maior desvantagem é que você tem que aplicar esta operação para cada aplicação que deseja avaliar, o que é sobrecarga adicional para os testes.

Tenha em mente que se a aplicação que você está testando tem medidas adicionais de proteção, como verificação da assinatura da aplicação, você pode não conseguir iniciar a aplicação mais. Como parte do reempacotamento, você assinará a aplicação com sua própria chave e, portanto, as mudanças na assinatura resultarão no acionamento de tais verificações que podem levar ao término imediato da aplicação. Você precisaria identificar e desativar tais verificações, seja patcheando-as durante o reempacotamento da aplicação ou por instrumentação dinâmica através do Frida.

Há um script Python disponível que automatiza os passos descritos acima chamado Android-CertKiller. Este script Python pode extrair o APK de uma aplicação Android instalada, descompilá-la, torná-la depurável, adicionar uma nova Configuração de Segurança de Rede que permite certificados de usuário, construir e assinar o novo APK e instalar o novo APK com o bypass SSL.

python main.py -w

***************************************
Android CertKiller (v0.1)
***************************************

CertKiller Wizard Mode
---------------------------------
Lista de dispositivos conectados
4200dc72f27bc44d    dispositivo

---------------------------------

Digite o Nome do Pacote da Aplicação: nsc.android.mstg.owasp.org.android_nsc

Pacote: /data/app/nsc.android.mstg.owasp.org.android_nsc-1/base.apk

I. Iniciando extração do APK do dispositivo
   completo
------------------------------
I. Descompilando
   completo
------------------------------
I. Aplicando bypass SSL
   completo
------------------------------
I. Construindo Novo APK
   completo
------------------------------
I. Assinando APK
   completo
------------------------------

Gostaria de instalar o APK no seu dispositivo (s/N): s
------------------------------------
 Instalando APK sem pinning
------------------------------
Finalizado

Adicionando o certificado do proxy entre os CAs confiados do sistema usando Magisk

Para evitar a obrigação de configurar a Configuração de Segurança de Rede para cada aplicação, devemos forçar o dispositivo a aceitar o certificado do proxy como um dos certificados confiados do sistema.

Há um módulo Magisk que automaticamente adicionará todos os certificados CA instalados pelo usuário à lista de certificados CA confiados do sistema.

Faça o download da versão mais recente do módulo na página de Releases do Github, envie o arquivo baixado para o dispositivo e importe-o na visualização "Módulo" do Magisk Manager clicando no botão +. Finalmente, é necessário reiniciar pelo Magisk Manager para que as alterações entrem em vigor.

A partir de agora, qualquer certificado CA que for instalado pelo usuário via "Configurações", "Segurança e localização", "Criptografia e credenciais", "Instalar a partir do armazenamento" (a localização pode variar) é automaticamente enviado para o armazenamento de confiança do sistema por este módulo Magisk. Reinicie e verifique se o certificado CA está listado em "Configurações", "Segurança e localização", "Criptografia e credenciais", "Credenciais confiáveis" (a localização pode variar).

Adicionando manualmente o certificado do proxy entre os CAs confiados do sistema

Alternativamente, você pode seguir os seguintes passos manualmente para alcançar o mesmo resultado:

  • Torne a partição /system gravável, o que só é possível em um dispositivo com root. Execute o comando 'mount' para ter certeza de que /system está gravável: mount -o rw,remount /system. Se este comando falhar, tente executar o seguinte comando mount -o rw,remount -t ext4 /system
  • Prepare os certificados CA do proxy para corresponder ao formato de certificados do sistema. Exporte os certificados do proxy no formato der (este é o formato padrão no Burp Suite) e então execute os seguintes comandos:

    $ openssl x509 -inform DER -in cacert.der -out cacert.pem
    $ openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1
    mv cacert.pem <hash>.0
    
  • Finalmente, copie o arquivo <hash>.0 para o diretório /system/etc/security/cacerts e então execute o seguinte comando:

    chmod 644 <hash>.0
    

Seguindo os passos descritos acima, você permite que qualquer aplicação confie no certificado do proxy, o que permite interceptar seu tráfego, a menos, é claro, que a aplicação use SSL pinning.

Obstáculos Potenciais

Aplicações frequentemente implementam controles de segurança que tornam mais difícil realizar uma revisão de segurança da aplicação, como detecção de root e certificate pinning. Idealmente, você adquiriria tanto uma versão da aplicação que tem esses controles habilitados, quanto uma onde os controles estão desabilitados. Isso permite analisar a implementação adequada dos controles, após o que você pode continuar com a versão menos segura para testes adicionais.

É claro, isso nem sempre é possível, e você pode precisar realizar uma avaliação de caixa-preta em uma aplicação onde todos os controles de segurança estão habilitados. A seção abaixo mostra como você pode contornar o certificate pinning para diferentes aplicações.

Isolamento de Cliente em Redes Sem Fio

Uma vez que você configurou um proxy de interceptação e tem uma posição MITM, você ainda pode não conseguir ver nada. Isso pode ser devido a restrições na aplicação (veja a próxima seção), mas também pode ser devido ao chamado isolamento de cliente no Wi-Fi ao qual você está conectado.

Isolamento de Cliente Sem Fio é um recurso de segurança que impede que clientes sem fio se comuniquem uns com os outros. Este recurso é útil para SSIDs de convidados e BYOD, adicionando um nível de segurança para limitar ataques e ameaças entre dispositivos conectados às redes sem fio.

O que fazer se o Wi-Fi que precisamos para teste tem isolamento de cliente?

Você pode configurar o proxy no seu dispositivo Android para apontar para 127.0.0.1:8080, conectar seu telefone via USB ao seu computador host e usar o adb para fazer um redirecionamento reverso de porta:

adb reverse tcp:8080 tcp:8080

Uma vez que você fez isso, todo o tráfego do proxy no seu telefone Android irá para a porta 8080 em 127.0.0.1 e será redirecionado via adb para 127.0.0.1:8080 no seu computador host e você verá agora o tráfego no seu Burp. Com este truque, você é capaz de testar e interceptar tráfego também em Wi-Fis que têm isolamento de cliente.

Aplicações Não Cientes de Proxy

Uma vez que você configurou um proxy de interceptação e tem uma posição MITM, você ainda pode não conseguir ver nada. Isso se deve principalmente às seguintes razões:

  • A aplicação está usando um framework como Xamarin que simplesmente não usa as configurações de proxy do Android OS ou
  • A aplicação que você está testando está verificando se um proxy está definido e não está permitindo nenhuma comunicação.

Em ambos os cenários, você precisaria de passos adicionais para finalmente conseguir ver o tráfego. Nas seções abaixo, descrevemos duas soluções diferentes, bettercap e iptables.

Você também poderia usar um ponto de acesso que está sob seu controle para redirecionar o tráfego, mas isso requer hardware adicional e focamos por agora em soluções de software.

Para ambas as soluções, você precisa ativar "Support invisible proxying" no Burp, na aba Proxy/Options/Edit Interface.

iptables

Você pode usar iptables no dispositivo Android para redirecionar todo o tráfego para seu proxy de interceptação. O seguinte comando redirecionaria a porta 80 para seu proxy executando na porta 8080

iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination <IP-do-Seu-Proxy>:8080

Verifique as configurações do iptables e confirme o IP e a porta.

$ iptables -t nat -L
Cadeia PREROUTING (política ACEITAR)
alvo     prot opt origem               destino

Cadeia INPUT (política ACEITAR)
alvo     prot opt origem               destino

Cadeia OUTPUT (política ACEITAR)
alvo     prot opt origem               destino
DNAT       tcp  --  qualquer lugar             qualquer lugar             tcp dpt:5288 para:<IP-do-Seu-Proxy>:8080

Cadeia POSTROUTING (política ACEITAR)
alvo     prot opt origem               destino

Cadeia natctrl_nat_POSTROUTING (0 referências)
alvo     prot opt origem               destino

Cadeia oem_nat_pre (0 referências)
alvo     prot opt origem               destino

Caso queira redefinir a configuração do iptables, você pode limpar as regras:

iptables -t nat -F

bettercap

Veja Conquistando uma Posição MITM via ARP Spoofing para mais preparação e instruções para executar o bettercap.

O computador host onde você executa seu proxy e o dispositivo Android devem estar conectados à mesma rede sem fio. Inicie o bettercap com o seguinte comando, substituindo o endereço IP abaixo (X.X.X.X) pelo endereço IP do seu dispositivo Android.

$ sudo bettercap -eval "set arp.spoof.targets X.X.X.X; arp.spoof on; set arp.spoof.internal true; set arp.spoof.fullduplex true;"
bettercap v2.22 (construído para darwin amd64 com go1.12.1) [digite 'help' para uma lista de comandos]

[19:21:39] [sys.log] [inf] arp.spoof ativando encaminhamento
[19:21:39] [sys.log] [inf] arp.spoof spoofing arp iniciado, sondando 1 alvos.

Detecção de Proxy

Algumas aplicações móveis tentam detectar se um proxy está configurado. Se for o caso, elas assumirão que isso é malicioso e não funcionarão adequadamente.

Para contornar tal mecanismo de proteção, você poderia configurar o bettercap ou configurar iptables que não precisam de uma configuração de proxy no seu telefone Android. Uma terceira opção que não mencionamos antes e que é aplicável neste cenário é usar Frida. É possível no Android detectar se um proxy do sistema está configurado consultando a classe ProxyInfo e verificando os métodos getHost() e getPort(). Pode haver vários outros métodos para alcançar a mesma tarefa e você precisaria descompilar o APK para identificar o nome real da classe e do método.

Abaixo você pode encontrar código boiler plate para um script Frida que o ajudará a sobrecarregar o método (neste caso chamado isProxySet) que está verificando se um proxy está configurado e sempre retornará falso. Mesmo que um proxy esteja configurado agora, a aplicação pensará que nenhum está configurado, já que a função retorna falso.

setTimeout(function(){
    Java.perform(function (){
        console.log("[*] Script carregado")

        var Proxy = Java.use("<nome-do-pacote>.<nome-da-classe>")

        Proxy.isProxySet.overload().implementation = function() {
            console.log("[*] Função isProxySet invocada")
            return false
        }
    });
});