Mitmproxy
Mitmproxy
documentos do mitmproxy
Versão 1.0.1
27 de dezembro de 2016
Machine Translated by Google
Machine Translated by Google
Ferramentas
1. Introdução 3
2 Instalação 5
3 Sobre certificados 9
5 Modos de Operação 19
6 mitmproxy 25
7 mitmdump 33
8 mitmweb 35
9 Configuração 37
10 Anticache 39
11 Expressões de filtro 41
12 Substituições 43
15 Definir cabeçalhos 49
16 Ignorar domínios 51
17 Autenticação de proxy 53
18 Proxy Reverso 55
19 Transmissão de respostas 57
Modo 20 MEIAS 59
61i
Machine Translated by Google
22 Proxy TCP 63
24 Certificados Upstream 67
25 Proxy Transparente 69
26 Linux 71
27 OSX 73
28 Visão geral 75
29 eventos 79
30 API 83
37 pathod.test 113
38 Arquitetura 115
39 Teste 117
ii
Machine Translated by Google
mitmproxy é um proxy man-in-the-middle interativo para HTTP e HTTPS com uma interface de console.
Documentação, tutoriais e pacotes de distribuição podem ser encontrados no site do mitmproxy: mitmproxy.org
Recursos
Ferramentas 1
Machine Translated by Google
2 Ferramentas
Machine Translated by Google
CAPÍTULO 1
Introdução
mitmproxy é um proxy man-in-the-middle interativo para HTTP e HTTPS com uma interface de console.
Documentação, tutoriais e pacotes de distribuição podem ser encontrados no site do mitmproxy: mitmproxy.org
Recursos
3
Machine Translated by Google
4 Capítulo 1 Introdução
Machine Translated by Google
CAPÍTULO 2
Instalação
Quando a instalação estiver concluída, você pode executar mitmproxy, mitmdump ou mitmweb a partir de um terminal.
A maneira recomendada de instalar o mitmproxy no Windows é usar o instalador fornecido em mitmproxy.org. Após a instalação, você encontrará
atalhos para mitmweb (a interface baseada na web) e mitmdump no menu Iniciar. Ambos os exe cutables são adicionados ao seu PATH e podem
ser invocados a partir da linha de comando.
Nota: a interface do console do mitmproxy não é suportada no Windows, mas você pode usar mitmweb (a interface baseada na web) e mitmdump.
A maneira recomendada de executar o mitmproxy no Linux é usar os binários pré-criados fornecidos em mitmproxy.org.
Nossos binários pré-criados fornecem a versão mais recente do mitmproxy, um ambiente Python 3.5 independente e uma versão recente do
OpenSSL que suporta HTTP/2. Claro, você também pode instalar o mitmproxy da fonte se preferir (veja Instalação avançada).
5
Machine Translated by Google
Você também pode usar as imagens oficiais do mitmproxy do DockerHub. Dito isto, nossos binários portáteis são tão fáceis de instalar
e ainda mais fáceis de usar.
Ubuntu vem com Python mas precisamos instalar pip3, python3-dev e várias bibliotecas. Isso foi testado em uma instalação totalmente
corrigida do Ubuntu 16.04.
sudo apt-get install python3-pip python3-dev libffi-dev libssl-dev libtiff5-dev libjpeg8-dev zlib1g- sudo pip3 install mitmproxy # ou pip3 install --user mitmproxy
Em versões mais antigas do Ubuntu, por exemplo, 12.04 e 14.04, pode ser necessário instalar uma versão mais recente do Python.
mitmproxy requer Python 3.5 ou superior. Por favor, dê uma olhada em pyenv. Certifique-se de ter uma versão atualizada do pip
executando pip3 install -U pip.
O Fedora vem com Python, mas precisamos instalar pip3, python3-dev e várias bibliotecas. Isso foi testado em uma instalação totalmente
corrigida do Fedora 24.
sudo dnf install make gcc redhat-rpm-config python3-pip python3-devel libffi-devel openssl-devel lib sudo pip3 install mitmproxy # ou pip3 install --user mitmproxy
Certifique-se de ter uma versão atualizada do pip executando pip3 install -U pip.
Nota: a interface do console do mitmproxy não é suportada no Windows, mas você pode usar mitmweb (a interface baseada na web)
e mitmdump.
Primeiro, instale a versão mais recente do Python 3.5 ou posterior no site do Python. Durante a instalação, certifique-se de selecionar
Adicionar Python ao PATH.
6 Capítulo 2. Instalação
Machine Translated by Google
Se você deseja instalar o mitmproxy diretamente do branch master no GitHub ou gostaria de se preparar para contribuir com o
projeto, instale as dependências como faria para uma instalação regular da fonte. Então veja o Hacking seção do README no
GitHub. Você pode verificar as informações do seu sistema executando: mitmproxy --sysinfo
8 Capítulo 2. Instalação
Machine Translated by Google
CAPÍTULO 3
Sobre certificados
3.1 Introdução
O Mitmproxy pode descriptografar o tráfego criptografado em tempo real, desde que o cliente confie em sua autoridade de certificação integrada.
Normalmente, isso significa que os certificados de CA mitmproxy devem ser instalados no dispositivo cliente.
De longe, a maneira mais fácil de instalar os certificados mitmproxy é usar o aplicativo de instalação de certificados integrado. Para fazer isso,
basta iniciar o mitmproxy e configurar seu dispositivo de destino com as configurações de proxy corretas. Agora inicie um navegador no dispositivo
e visite o domínio mágico mitm.it. Você deve ver algo assim:
Clique no ícone relevante, siga as instruções de configuração para a plataforma em que você está e pronto.
Às vezes, usar o aplicativo de instalação rápida não é uma opção - Java ou o iOS Simulator vem à mente - ou você só precisa fazê-lo manualmente
por algum outro motivo. Abaixo está uma lista de ponteiros para a documentação de instalação manual do certificado para algumas plataformas
comuns.
O certificado de CA mitmproxy está localizado em ~/.mitmproxy após ter sido gerado na primeira inicialização do mitmproxy.
9
Machine Translated by Google
3.3.1 iOS
http://kb.mit.edu/confluence/pages/viewpage.action?pageId=152600377
Veja https://github.com/ADVTOOLS/ADVTrustStore#how-to-use-advtruststore
3.3.3 Java
Consulte http://docs.oracle.com/cd/E19906-01/820-4916/geygn/index.html
Consulte http://wiki.cacert.org/FAQ/ImportRootCert#Android_Phones_.26_Tablets
3.3.5 Janelas
Consulte http://windows.microsoft.com/en-ca/windows/import-export-certificates-private-keys#1TC=windows-7
3.3.7 Mac OS X
Consulte https://support.apple.com/kb/PH7297?locale=en_US
3.3.8 Ubuntu/Debian
Veja http://askubuntu.com/questions/73287/how-do-i-install-a-root-certificate/94861#94861
Veja https://wiki.mozilla.org/MozillaRootCertificate#Mozilla_Firefox
Consulte https://code.google.com/p/chromium/wiki/LinuxCertManagement
A primeira vez que mitmproxy ou mitmdump é executado, a Autoridade de Certificação (CA) mitmproxy é criada no diretório de
configuração (~/.mitmproxy por padrão). Essa CA é usada para geração dinâmica de certificados fictícios para cada um dos sites SSL
que seu cliente visita. Como seu navegador não confiará na CA do mitmproxy, você verá um aviso de certificado SSL toda vez que
visitar um novo domínio SSL por meio do mitmproxy. Quando você está testando um único site por meio de um navegador, apenas
aceitar o certificado SSL falso manualmente não é muito problemático, mas há muitas circunstâncias em que você deseja configurar
seu sistema de teste ou navegador para confiar na CA mitmproxy como uma raiz de assinatura autoridade. Por motivos de segurança,
a CA mitmproxy é gerada exclusivamente na primeira inicialização e não é compartilhada entre instalações mitmproxy em dispositivos
diferentes.
Alguns aplicativos empregam a fixação de certificados para evitar ataques man-in-the-middle. Isso significa que os certificados do
mitmproxy e do mitmdump não serão aceitos por esses aplicativos sem modificá-los. Recomenda-se usar o recurso Ignorar
Domínios para evitar que mitmproxy e mitmdump interceptem tráfego para esses domínios específicos. Se você deseja interceptar
as conexões fixadas, você precisa corrigir o aplicativo manualmente. Para dispositivos Android e iOS (com jailbreak), existem várias
ferramentas para fazer isso.
Você pode usar seu próprio certificado passando a opção --cert [domain=]path_to_certificate para mitm proxy. O Mitmproxy usa o
certificado fornecido para interceptação do domínio especificado em vez de gerar um certificado assinado por sua própria CA.
Espera-se que o arquivo de certificado esteja no formato PEM. Você pode incluir certificados intermediários logo abaixo do seu
certificado de folha, para que seu arquivo PEM fique mais ou menos assim:
Por exemplo, você pode gerar um certificado neste formato usando estas instruções:
>>> openssl genrsa -out cert.key 2048 >>> openssl req -new
-x509 -key cert.key -out cert.crt
Observação: *.example.com é para todos os subdomínios. Você também pode usar www.example.com para um subdo main específico.
Por padrão, o mitmproxy usará ~/.mitmproxy/mitmproxy-ca.pem como autoridade de certificação para gerar certificados para todos os
domínios para os quais nenhum certificado personalizado é fornecido (veja acima). Você pode usar sua própria autoridade de certificado
passando a opção --cadir DIRECTORY para mitmproxy. O Mitmproxy procurará então por mitmproxy-ca.pem no diretório especificado. Se
esse arquivo não existir, ele será gerado automaticamente.
Você pode usar um certificado de cliente passando a opção --client-certs DIRECTORY|FILE para mitmproxy. O uso de um diretório permite
que os certificados sejam selecionados com base no nome do host, enquanto o uso de um nome de arquivo permite que um único certificado
específico seja usado para todas as conexões SSL. Os arquivos de certificado devem estar no formato PEM e devem conter a chave privada
não criptografada e o certificado.
Se você visitar example.org, o mitmproxy procurará um arquivo chamado example.org.pem no diretório especificado e o usará como o
certificado do cliente.
CAPÍTULO 4
Mitmproxy é uma ferramenta extremamente flexível. Saber exatamente como o processo de proxy funciona ajudará você a implantá-
lo de forma criativa e a levar em consideração suas suposições fundamentais e como contorná-las. Este documento explica o
mecanismo de proxy do mitmproxy em detalhes, começando com o proxy explícito não criptografado mais simples e trabalhando
1 de Indicação de Nome de Servidor .
até a interação mais complicada - proxy transparente de tráfego protegido por TLS na presença
Configurar o cliente para usar mitmproxy como um proxy explícito é a maneira mais simples e confiável de interceptar o tráfego.
O protocolo proxy é codificado no HTTP RFC, portanto, o comportamento do cliente e do servidor é bem definido e geralmente
confiável. Na interação mais simples possível com o mitmproxy, um cliente se conecta diretamente ao proxy e faz uma solicitação
parecida com esta:
Esta é uma solicitação GET de proxy - uma forma estendida da solicitação HTTP GET vanilla que inclui um esquema e uma
especificação de host, e inclui todas as informações que o mitmproxy precisa para prosseguir.
1 O uso de “TLS” refere-se a SSL (desatualizado e inseguro) e TLS (1.0 e superior) no sentido genérico, a menos que especificado de outra forma.
13
Machine Translated by Google
O processo para uma conexão HTTPS explicitamente proxy é bem diferente. O cliente se conecta ao proxy e faz uma solicitação
parecida com esta:
Um proxy convencional não pode visualizar nem manipular um fluxo de dados criptografado por TLS, portanto, uma solicitação
CONNECT simplesmente solicita que o proxy abra um canal entre o cliente e o servidor. O proxy aqui é apenas um facilitador - ele
encaminha dados cegamente em ambas as direções sem saber nada sobre o conteúdo. A negociação da conexão TLS acontece por
esse pipe, e o fluxo subsequente de solicitações e respostas é completamente opaco para o proxy.
É aqui que entra em jogo o truque fundamental do mitmproxy. O MITM em seu nome significa Man-In-The-Middle - uma referência ao
processo que usamos para interceptar e interferir nesses fluxos de dados teoricamente opacos. A ideia básica é fingir ser o servidor
para o cliente e fingir ser o cliente para o servidor, enquanto nos sentamos no meio, decodificando o tráfego de ambos os lados. A parte
complicada é que a Autoridade de Certificação O sistema foi projetado para evitar exatamente esse ataque, permitindo que um terceiro
confiável assine criptograficamente os certificados de um servidor para verificar se eles são legítimos. Se essa assinatura não
corresponder ou for de uma parte não confiável, um cliente seguro simplesmente interromperá a conexão e se recusará a prosseguir.
Apesar das muitas deficiências do sistema CA como existe hoje, isso geralmente é fatal para tentativas de MITM uma conexão TLS
para análise. Nossa resposta a esse enigma é nos tornarmos uma Autoridade de Certificação confiável. O Mitmproxy inclui uma
implementação completa de CA que gera certificados de interceptação em tempo real. Para que o cliente confie nesses certificados,
registramos mitmproxy como uma CA confiável com o dispositivo manualmente.
Para prosseguir com este plano, precisamos saber o nome de domínio a ser usado no certificado de interceptação - o cliente verificará
se o certificado é para o domínio ao qual está se conectando e abortará se não for o caso. À primeira vista, parece que a solicitação
CONNECT acima nos fornece tudo o que precisamos - neste exemplo, ambos os valores são "example.com". Mas e se o cliente tivesse
iniciado a conexão da seguinte forma:
Usar o endereço IP é perfeitamente legítimo porque nos fornece informações suficientes para iniciar o pipe, mesmo que não revele o
nome do host remoto.
O Mitmproxy possui um mecanismo astuto que suaviza esse sniffing de certificados acima do upstream. Assim que vemos a solicitação
CONNECT, pausamos a parte do cliente da conversa e iniciamos uma conexão simultânea com o servidor.
Concluímos o handshake TLS com o servidor e inspecionamos os certificados usados. Agora, usamos o nome comum nos certificados
upstream para gerar o certificado fictício para o cliente. Pronto, temos o nome de host correto para apresentar ao cliente, mesmo que
nunca tenha sido especificado.
Digite a próxima complicação. Às vezes, o nome comum do certificado não é, na verdade, o nome do host ao qual o cliente está se
conectando. Isso ocorre por causa do nome alternativo do assunto opcional campo no certificado que permite que um número arbitrário
de domínios alternativos seja especificado. Se o domínio esperado corresponder a qualquer um deles, o cliente prosseguirá, mesmo
que o domínio não corresponda ao CN do certificado. A resposta aqui é simples: quando extraímos o CN do certificado upstream,
também extraímos as SANs e as adicionamos ao certificado fictício gerado.
Uma das grandes limitações do TLS vanilla é que cada certificado requer seu próprio endereço IP. Isso significa que você não pode
fazer hospedagem virtual onde vários domínios com certificados independentes compartilham o mesmo endereço IP. Em um mundo
com um pool de endereços IPv4 cada vez menor, isso é um problema, e temos uma solução na forma de Indicação de Nome de
Servidor extensão aos protocolos TLS. Isso permite que o cliente especifique o nome do servidor remoto no início do handshake TLS,
o que permite que o servidor selecione o certificado correto para concluir o processo.
O SNI interrompe nosso processo de detecção de certificados upstream, porque quando nos conectamos sem usar o SNI, recebemos
um certificado padrão que pode não ter nada a ver com o certificado esperado pelo cliente. A solução é outra complicação complicada
para o processo de conexão do cliente. Depois que o cliente se conecta, permitimos que o handshake TLS continue até que o valor
SNI tenha sido passado para nós. Agora podemos pausar a conversa e iniciar uma conexão upstream usando o valor SNI correto, que
então nos fornece o certificado upstream correto, do qual podemos extrair o CN e SANs esperados.
Vamos juntar tudo isso no fluxo HTTPS com proxy explícito completo.
1. O cliente faz uma conexão com mitmproxy e emite uma solicitação HTTP CONNECT.
2. O Mitmproxy responde com um 200 Connection Established, como se tivesse configurado o pipe CONNECT.
3. O cliente acredita que está falando com o servidor remoto e inicia a conexão TLS. Ele usa SNI para indicar o
nome do host ao qual ele está se conectando.
4. O Mitmproxy se conecta ao servidor e estabelece uma conexão TLS usando o nome de host SNI indicado pelo
cliente.
5. O servidor responde com o certificado correspondente, que contém os valores CN e SAN necessários para gerar o certificado de
interceptação.
6. O Mitmproxy gera o certificado de interceptação e continua o handshake TLS do cliente pausado na etapa 3.
8. O Mitmproxy passa a solicitação para o servidor pela conexão TLS iniciada na etapa 4.
Para conseguir isso, precisamos introduzir dois componentes extras. O primeiro é um mecanismo de redirecionamento que redireciona
de forma transparente uma conexão TCP destinada a um servidor na Internet para um servidor proxy de escuta. Isso geralmente
assume a forma de um firewall no mesmo host que o servidor proxy - iptables no Linux ou pf no OSX. Uma vez que o cliente iniciou a
conexão, ele faz uma solicitação HTTP vanilla, que pode ser algo assim:
Observe que essa solicitação difere da variação de proxy explícita, pois omite o esquema e o nome do host. Como, então, sabemos
para qual host upstream encaminhar a solicitação? O mecanismo de roteamento que executou o redirecionamento
mantém o controle do destino original para nós. Cada mecanismo de roteamento tem uma maneira diferente de expor esses dados, então isso
introduz o segundo componente necessário para trabalhar com proxy transparente: um módulo host que sabe como recuperar o endereço de
destino original do roteador. No mitmproxy, isso assume a forma de um conjunto embutido de módulos que sabem falar com o mecanismo de
redirecionamento de cada plataforma. Uma vez que temos essas informações, o processo é bastante simples.
2. O roteador redireciona a conexão para mitmproxy, que normalmente está escutando em uma porta local do mesmo host.
O Mitmproxy então consulta o mecanismo de roteamento para estabelecer qual era o destino original.
A partir daqui, o processo é uma fusão dos métodos que descrevemos para proxy transparente de HTTP e HTTPS explicitamente. Usamos o
mecanismo de roteamento para estabelecer o endereço do servidor upstream e, em seguida, procedemos como para conexões HTTPS explícitas
para estabelecer o CN e as SANs e lidar com o SNI.
2. O roteador redireciona a conexão para mitmproxy, que normalmente está escutando em uma porta local do mesmo host.
O Mitmproxy então consulta o mecanismo de roteamento para estabelecer qual era o destino original.
3. O cliente acredita que está falando com o servidor remoto e inicia a conexão TLS. Ele usa SNI para indicar o
nome do host ao qual ele está se conectando.
4. O Mitmproxy se conecta ao servidor e estabelece uma conexão TLS usando o nome de host SNI indicado pelo
cliente.
5. O servidor responde com o certificado correspondente, que contém os valores CN e SAN necessários para gerar o certificado de
interceptação.
6. O Mitmproxy gera o certificado de interceptação e continua o handshake TLS do cliente pausado na etapa 3.
8. O Mitmproxy passa a solicitação para o servidor pela conexão TLS iniciada na etapa 4.
CAPÍTULO 5
Modos de operação
O Mitmproxy possui quatro modos de operação que permitem usar o mitmproxy em vários cenários:
• Regular (o padrão)
• Transparente
• Proxy reverso
• Proxy Upstream
1. Inicie o mitmproxy.
2. Configure seu cliente para usar mitmproxy configurando explicitamente um proxy HTTP.
19
Machine Translated by Google
3. Verificação Rápida: Você já deve conseguir visitar um site HTTP não criptografado por meio do proxy.
Nota: Infelizmente, alguns aplicativos ignoram as configurações de proxy HTTP do sistema - os aplicativos Android são um exemplo
comum. Nesses casos, você precisa usar o modo transparente do mitmproxy.
Se você estiver fazendo proxy de um dispositivo externo, sua rede provavelmente ficará assim:
Os colchetes significam os endereços IP de origem e destino. Seu cliente se conecta explicitamente ao mitmproxy e o mitmproxy se
conecta explicitamente ao servidor de destino.
No modo transparente, o tráfego é direcionado para um proxy na camada de rede, sem necessidade de configuração de cliente.
Isso torna o proxy transparente ideal para situações em que você não pode alterar o comportamento do cliente. No gráfico abaixo, uma
máquina rodando mitmproxy foi inserida entre o roteador e a internet:
Os colchetes significam os endereços IP de origem e destino. Os colchetes marcam o próximo salto na camada de enlace de rede/dados
Ether. Essa distinção é importante: quando o pacote chega à máquina mitmproxy, ele ainda deve ser endereçado ao servidor de destino.
Isso significa que a tradução de endereço de rede não deve ser aplicada antes que o tráfego atinja mitmproxy, pois isso removeria as
informações de destino, deixando o mitmproxy incapaz de determinar o destino real.
Há muitas maneiras de configurar sua rede para proxy transparente. Veremos dois cenários comuns:
Na maioria dos casos, a primeira opção é recomendada devido à sua facilidade de uso.
Uma maneira simples de obter tráfego para a máquina mitmproxy com o IP de destino intacto é simplesmente configurar o cliente
com a caixa mitmproxy como o gateway padrão.
1. Configure a máquina proxy para o modo transparente. Você pode encontrar instruções no Transparent Proxying
seção.
3. Verificação rápida: neste ponto, você já deve poder visitar um site HTTP não criptografado pelo proxy.
A configuração do gateway personalizado nos clientes pode ser automatizada fornecendo as configurações aos clientes por DHCP. Isso permite
configurar uma rede de interceptação onde todos os clientes são proxy automaticamente, o que pode economizar tempo e esforço.
As configurações incorretas do modo transparente são uma fonte frequente de erro. Se não funcionar para você, tente as seguintes coisas:
• Abra o log de eventos do mitmproxy (pressione e) - você vê as mensagens do clientconnect? Caso contrário, os pacotes não estão chegando ao
proxy. Uma causa comum é a ocorrência de redirecionamentos ICMP, o que significa que sua máquina está informando ao cliente que há uma
maneira mais rápida de acessar a Internet entrando em contato diretamente com seu roteador (consulte a seção Proxy Transparente sobre como
desativá-los). Em caso de dúvida, o Wireshark pode ajudá-lo a ver se algo chega à sua máquina ou não.
• Certifique-se de não ter configurado explicitamente um proxy HTTP no cliente. Isso não é necessário em transparente
modo.
• Verifique novamente as instruções na seção Transparent Proxying . Alguma coisa que você perdeu?
Se você encontrar quaisquer outras armadilhas que devam ser listadas aqui, por favor nos avise!
Em alguns casos, você pode precisar de um controle mais refinado de qual tráfego atinge a instância mitmproxy e qual não. Você pode, por exemplo,
optar apenas por desviar o tráfego de alguns hosts para o proxy transparente. Há um grande número de maneiras de fazer isso, e muito dependerá do
roteador ou filtro de pacotes que você está usando. Na maioria dos casos, a configuração ficará assim:
• Digamos que você tenha uma API interna em execução em http://example.local/. Agora você pode configurar o mitmproxy no modo
de proxy reverso em http://debug.example.local/ e aponte dinamicamente os clientes para esse novo endpoint de API, que fornece
a eles os mesmos dados e a você informações de depuração. Da mesma forma, você pode mover seu servidor real para um IP/
porta diferente e configurar o mitmproxy no local original para depurar e/ou redirecionar todas as sessões.
• Digamos que você seja um desenvolvedor da Web trabalhando em http://example.com/ (com uma versão de desenvolvimento
rodando em http://localhost:8000/). Você pode modificar seu arquivo hosts para que example.com aponte para 127.0.0.1 e, em
seguida, execute mitmproxy no modo de proxy reverso na porta 80. Você pode testar seu aplicativo no domínio example.com e
obter todas as solicitações registradas em mitmproxy.
• Digamos que você tenha algum projeto de brinquedo que deveria receber suporte SSL. Basta configurar o mitmproxy como um proxy
reverso na porta 443 e pronto (mitmdump -p 443 -R http://localhost:80/). O Mitmproxy detecta automaticamente o tráfego TLS e o
intercepta dinamicamente. Existem ferramentas melhores para essa tarefa específica, mas o mitmproxy é uma maneira muito rápida
e simples de configurar um servidor que fala SSL.
• Deseja adicionar um proxy de compactação não compatível com SSL na frente de seu servidor? Você pode até gerar uma instância
mitmproxy que encerra SSL (-R http://...), apontá-la para o proxy de compactação e deixar o proxy de compactação apontar para
um mitmproxy inicializador de SSL (-R https://... ), que então aponta para o servidor real. Como você vê, é uma coisa bastante
flexível.
O modo de proxy reverso geralmente não é suficiente para criar uma cópia de um site interativo em um URL diferente. O HTML servido ao
cliente permanece inalterado - assim que o usuário clica em um URL não relativo (ou baixa um recurso de imagem não relativo), o tráfego
não passa mais pelo mitmproxy.
mitmproxy oferece suporte a HTTP explícito e HTTPS explícito no modo de proxy upstream. Você poderia, em teoria, encadear
várias instâncias de mitmproxy seguidas, mas isso não faz sentido na prática (ou seja, fora de nossos testes).
CAPÍTULO 6
mitmproxy
mitmproxy é uma ferramenta de console que permite exame interativo e modificação do tráfego HTTP. Ele difere do mitmdump,
pois todos os fluxos são mantidos na memória, o que significa que se destina a coletar e manipular amostras pequenas. Use o ?
tecla de atalho para visualizar, documentação sensível ao contexto de qualquer tela mitmproxy .
25
Machine Translated by Google
• 3: Um pedido repetido.
• 4: Os fluxos interceptados são indicados com texto laranja. O usuário pode editar esses fluxos e aceitá-los (usando
a tecla a) para continuar. Nesse caso, a solicitação foi interceptada no caminho para o servidor.
• 6: O log de eventos pode ser ativado e desativado usando a tecla de atalho e. Este painel mostra eventos e erros que podem não resultar
em um fluxo que aparece no painel de fluxo.
• 7: Contagem de fluxo.
• 8: Várias informações sobre o estado do mitmproxy. Nesse caso, temos um padrão de interceptação definido como .*.
• 9: Indicador de endereço de ligação - mitmproxy está escutando na porta 8080 de todas as interfaces.
• 1: Resumo do fluxo.
26 Capítulo 6. mitmproxy
Machine Translated by Google
• 2: As guias Solicitação/Resposta, mostrando qual parte do fluxo você está visualizando no momento. No exemplo
acima, estamos visualizando a resposta. Clique na guia para alternar entre a resposta e a solicitação.
• 3: Cabeçalhos.
• 4: Corpo.
• 5: Indicador do modo de visualização. Nesse caso, estamos vendo o corpo no modo hexadecimal . Os outros modos disponíveis são
bonitos, que usam uma série de heurísticas para mostrar uma visão amigável de vários tipos de conteúdo, e brutos, que mostram
exatamente o que está lá sem nenhuma alteração. Você pode alterar os modos usando a tecla m.
Muitos dos dados com os quais gostaríamos de interagir no mitmproxy são estruturados. Por exemplo, cabeçalhos, consultas e dados de
formulário podem ser vistos como uma lista de pares chave/valor. O Mitmproxy possui um editor embutido que coloca esse tipo de dados em
uma grade para facilitar a manipulação.
• Edição de cabeçalhos de solicitação ou resposta (e para edição, depois h para cabeçalhos na visualização de fluxo)
• Editando uma string de consulta (e para edição, depois q para consulta na visualização de fluxo)
• Editar um formulário codificado por URL (e para edição, depois f para formulário na visualização de fluxo)
Se não houver dados, um editor vazio será iniciado para permitir que você adicione alguns. Aqui está o editor mostrando os cabeçalhos de uma
solicitação:
Para editar, navegue até a chave ou valor que deseja modificar usando as teclas de seta ou de navegação vi e pressione enter. A cor de
fundo mudará para mostrar que você está no modo de edição para o campo especificado:
Modifique o campo conforme desejado e pressione escape para sair do modo de edição quando terminar. Você também pode adicionar uma linha (uma
chave), excluir uma linha (tecla d), gerar um editor externo em um campo (tecla e). Certifique-se de consultar a ajuda sensível ao contexto (tecla ?) para obter
mais informações.
A funcionalidade de interceptação do mitmproxy permite pausar uma solicitação ou resposta HTTP, inspecioná-la e modificá-la e, em
seguida, aceitá-la para enviá-la ao servidor ou cliente.
28 Capítulo 6. mitmproxy
Machine Translated by Google
Pressionamos i para definir um padrão de interceptação. Nesse caso, o padrão de filtro ~q informa ao mitmproxy para interceptar todas as solicitações.
Para obter a sintaxe de filtro completa, consulte a seção Expressões de filtro da documentação ou a função de ajuda integrada em mitmproxy.
30 Capítulo 6. mitmproxy
Machine Translated by Google
Nesse caso, visualizamos a solicitação selecionando-a, pressionamos e para “editar” e m para “método” para alterar o método de
solicitação HTTP.
Por fim, pressionamos a para aceitar a solicitação modificada, que é então enviada ao servidor. Nesse caso, alteramos a solicitação de
HTTP GET para OPTIONS e o servidor do Google respondeu com um 405 “Método não permitido”.
32 Capítulo 6. mitmproxy
Machine Translated by Google
CAPÍTULO 7
mitmdump
mitmdump é o companheiro de linha de comando para mitmproxy. Ele fornece funcionalidade semelhante ao tcpdump para permitir que você visualize, grave e
transforme programaticamente o tráfego HTTP. Veja a saída do sinalizador --help para obter a documentação completa.
7.1 Exemplos
7.1.1 Economizando tráfego
Inicie o mitmdump sem vincular-se à porta do proxy (-n), leia todos os fluxos de infile, aplique a expressão de filtro especificada (corresponda apenas a POSTs) e
grave em outfile.
Inicie o mitmdump sem vincular-se à porta do proxy (-n) e, em seguida, reproduza todas as solicitações de outfile (-c filename). Os sinalizadores combinam de
maneira óbvia, para que você possa reproduzir solicitações de um arquivo e gravar os fluxos resultantes em outro:
Isso executa o script de exemplo add_header.py , que simplesmente adiciona um novo cabeçalho a todas as respostas.
33
Machine Translated by Google
Este comando carrega os fluxos do srcfile, transforma-o de acordo com o script especificado e, em seguida, grava-o de volta no dstfile.
34 Capítulo 7. mitmdump
Machine Translated by Google
CAPÍTULO 8
mitmweb
mitmweb é a interface de usuário baseada na web do mitmproxy que permite exame interativo e modificação do tráfego HTTP. Assim
como o mitmproxy, ele difere do mitmdump porque todos os fluxos são mantidos na memória, o que significa que ele se destina a coletar
e manipular amostras pequenas.
Aviso: Mitmweb está atualmente em beta. Consideramos estável para todos os recursos atualmente expostos na interface do
usuário, mas ainda falta muitos recursos do mitmproxy.
35
Machine Translated by Google
36 Capítulo 8. mitmweb
Machine Translated by Google
CAPÍTULO 9
Configuração
Mitmproxy está configurado com um YAML arquivo, localizado em ~/.mitmproxy/config.yaml. Teremos documentação
completa para todas as opções suportadas na próxima versão enquanto isso, consulte a fonte para obter uma lista
completa de opções e tipos.
37
Machine Translated by Google
38 Capítulo 9. Configuração
Machine Translated by Google
CAPÍTULO 10
Anticache
Quando a opção --anticache é passada para mitmproxy, ela remove os cabeçalhos (if-none-match e if-modified-since) que podem
gerar uma resposta 304 não modificada do servidor. Isso é útil quando você deseja ter certeza de capturar uma troca HTTP em
sua totalidade. Também é frequentemente usado durante a reprodução do lado do cliente, quando você deseja garantir que o
servidor responda com dados completos.
atalho mitmproxy - prevê que
39
Machine Translated by Google
CAPÍTULO 11
Filtrar expressões
Muitos comandos em mitmproxy e mitmdump usam uma expressão de filtro. As expressões de filtro consistem no seguinte
operadores:
Descrição da expressão
~a Ativo de correspondência em resposta: CSS, Javascript, Flash, imagens.
~b regex Corpo
~bq regex Corpo da solicitação
~e Erro de correspondência
~h regex Cabeçalho
~m regex Método
~marcado Corresponder fluxos marcados
unário não
& e
ou
| (...) agrupamento
• A correspondência de cabeçalho (~h, ~hq, ~hs) é contra uma string no formato “nome: valor”.
41
Machine Translated by Google
11.1 Exemplos
google\.com
~q ~b teste
CAPÍTULO 12
Substituições
O Mitmproxy permite especificar um número arbitrário de padrões que definem substituições de texto nos fluxos. Cada padrão tem 3 componentes:
um filtro que define a quais fluxos uma substituição se aplica, uma expressão regular que define o que é substituído e um valor de destino que
define o que é substituído.
Os ganchos de substituição são acionados quando uma solicitação do cliente ou uma resposta do servidor é recebida. Apenas o componente de
fluxo correspondente é afetado: assim, por exemplo, se um gancho de substituição for acionado na resposta do servidor, a substituição será
executada apenas no objeto Resposta, deixando a Solicitação intacta. Você controla se o gancho é acionado na solicitação, na resposta ou em
ambos usando o padrão de filtro. Se você precisar de um controle mais refinado do que isso, é simples criar um script usando a API de substituição
nos componentes do Flow.
Ganchos de substituição são extremamente úteis em testes interativos de aplicativos. Por exemplo, você pode usar um gancho de substituição
para substituir o texto “XSS” por uma exploração XSS complicada e, em seguida, “injetar” a exploração simplesmente interagindo com o aplicativo
através do navegador. Quando usado com ferramentas como o Firebug e as habilidades de interceptação do próprio mitmproxy, os ganchos de
substituição podem ser um recurso incrivelmente flexível e poderoso.
As opções de linha de comando do gancho de substituição usam uma sintaxe compacta para facilitar a especificação de todos os três
componentes de uma só vez. A forma geral é a seguinte:
/patt/regex/substituição
Aqui, patt é uma expressão de filtro mitmproxy, regex é uma expressão regular Python válida e a substituição é uma string literal. O primeiro
caractere na expressão (/ neste caso) define qual é o caractere de separação. Aqui está um exemplo de uma expressão válida que substitui “foo”
por “bar” em todas as solicitações:
:~q:foo:bar
Na prática, é bastante comum que o literal de substituição seja longo e complexo. Por exemplo, pode ser um exploit XSS que pesa centenas ou
milhares de caracteres. Para lidar com isso, há uma variação do especificador de gancho de substituição que permite carregar o texto de
substituição de um arquivo. Então, você pode iniciar o mitmdump da seguinte forma:
43
Machine Translated by Google
12.2 Interativamente
A tecla de atalho R no menu de opções do mitmproxy (o) permite adicionar e editar ganchos de substituição usando um editor embutido.
A ajuda sensível ao contexto (?) tem informações de uso completas.
CAPÍTULO 13
A repetição do lado do cliente faz o que diz na lata: você fornece uma conversa HTTP salva anteriormente e o mitmproxy reproduz
as solicitações do cliente uma a uma. Observe que mitmproxy serializa as solicitações, aguardando uma resposta do servidor
antes de iniciar a próxima solicitação. Isso pode ser diferente da conversa gravada, em que as solicitações podem ter sido feitas
simultaneamente.
Você pode querer usar a repetição do lado do cliente em conjunto com a opção Anticache , para garantir que o servidor responda
com dados completos.
linha de comando -c caminho
mitmproxy atalho R então c
45
Machine Translated by Google
CAPÍTULO 14
A repetição do lado do servidor nos permite reproduzir as respostas do servidor de uma conversa HTTP salva.
Por padrão, mitmproxy exclui cabeçalhos de solicitação ao corresponder solicitações recebidas com respostas do arquivo de repetição. Isso funciona na
maioria das circunstâncias e torna possível reproduzir as respostas do servidor em situações em que os cabeçalhos das solicitações variam naturalmente,
por exemplo, usando um agente de usuário diferente. A opção de linha de comando --rheader headername permite que você substitua esse comportamento
especificando cabeçalhos individuais que devem ser incluídos na correspondência.
A simples repetição das respostas do servidor sem modificação geralmente resultará em um comportamento inesperado. Por exemplo, os tempos limite de
cookies que estavam no futuro no momento em que uma conversa foi gravada podem estar no passado no momento em que ela é reproduzida.
Por padrão, o mitmproxy atualiza as respostas do servidor antes de enviá-las ao cliente. A data, expira e os cabeçalhos da última modificação são
todos atualizados para ter o mesmo deslocamento de tempo relativo que tinham no momento da gravação. Então, se eles estavam no passado no momento
da gravação, eles estarão no passado no momento do replay, e vice-versa. Os tempos de expiração dos cookies são atualizados de maneira semelhante.
Você pode desativar a atualização de resposta usando o argumento --norefresh ou usando o atalho de opções o no mitmproxy.
47
Machine Translated by Google
CAPÍTULO 15
Definir cabeçalhos
Esse recurso permite especificar um conjunto de cabeçalhos a serem adicionados a solicitações ou respostas, com base em um padrão
de filtro. Você pode especificá-los na linha de comando ou por meio de um editor interativo no mitmproxy.
49
Machine Translated by Google
CAPÍTULO 16
Ignorar domínios
Existem duas razões principais pelas quais você pode querer isentar algum tráfego do mecanismo de interceptação do mitmproxy:
• Fixação de certificado: parte do tráfego é protegido usando Fixação de certificado e a interceptação do mitmproxy leva a erros.
Por exemplo, o aplicativo do Twitter, o Windows Update ou a Apple App Store não funcionam se o mitmproxy estiver ativo.
• Conveniência: Você realmente não se importa com algumas partes do tráfego e só quer que elas desapareçam. Observe que a
opção “Limit” do mitmproxy geralmente é a melhor alternativa aqui, pois não é afetada pelas limitações listadas abaixo.
Se você quiser espiar conexões não HTTP (protegidas por SSL), confira o recurso Proxy TCP . Se você quiser ignorar o tráfego do
processamento do mitmproxy devido a grandes corpos de resposta, dê uma olhada no recurso Response Streaming .
mitmproxy permite que você especifique um regex que seja comparado com uma string host:port (por exemplo, “example.com:443”)
para determinar os hosts que devem ser excluídos.
16.2 Limitações
• No modo transparente, o padrão de ignorar é comparado com o IP e o host ClientHello SNI. Embora geralmente inferamos
o nome do host a partir do cabeçalho Host se o argumento --host for passado para mitmproxy, não temos acesso a essas
informações antes do handshake SSL. No entanto, se o cliente usa SNI, tratamos o host SNI como um destino ignorado.
• No modo regular, solicitações HTTP explícitas nunca são ignoradas. 1 O padrão de ignorar é aplicado em CONNECT
1 Isso decorre de uma limitação do proxy HTTP explícito: uma única conexão pode ser reutilizada para vários domínios de destino - uma
solicitação GET http://example.com/ pode ser seguida por uma solicitação GET http://evil.com/ em a mesma ligação. Se começarmos a
ignorar a conexão após o primeiro pedido, perderemos o segundo relevante.
51
Machine Translated by Google
16.3 Tutorial
Se você quiser apenas ignorar um domínio específico, geralmente há um método à prova de balas para fazer isso:
1. Execute mitmproxy ou mitmdump no modo detalhado (-v) e observe as informações de host:port nas mensagens de conexão do servidor.
mitmproxy irá filtrar estes.
2. Pegue a string host:port, envolva-a com ^ e $, escape de todos os pontos (. se torna \.) e use isso como seu ignore
padronizar:
>>> mitmdump -v
127.0.0.1:50588: clientconnect
127.0.0.1:50588: solicitação
-> CONNECT example.com:443 HTTP/1.1
127.0.0.1:50588: Definir novo endereço do servidor: example.com:443 127.0.0.1:50588:
serverconnect
-> exemplo.com:443 ^C
# Isento de tráfego da iOS App Store (o regex é frouxo, mas normalmente funciona): --ignore apple.com:443 # Versão "correta"
sem falsos positivos: --ignore '^(.+\.)? apple\.com:443$'
Veja também:
• Proxy TCP
• Transmissão de respostas
CAPÍTULO 17
Autenticação de proxy
Solicita a autenticação do usuário antes que ele tenha permissão para usar o proxy. Os cabeçalhos de autenticação são removidos dos
fluxos, portanto, não são passados para servidores upstream. Por enquanto, apenas a autenticação HTTP Basic é suportada. As opções
de autenticação de proxy não são compatíveis com o modo de proxy transparente, meias ou reverso.
53
Machine Translated by Google
CAPÍTULO 18
Proxy reverso
No modo de proxy reverso, o mitmproxy aceita solicitações HTTP(S) padrão e as encaminha para o servidor upstream especificado. Isso
contrasta com o modo de proxy upstream, no qual o mitmproxy encaminha solicitações de proxy HTTP(S) para um servidor proxy upstream.
Aqui, http[s] significa se o proxy deve usar TLS para se conectar ao servidor. O mitmproxy sempre aceita solicitações criptografadas e não
criptografadas e as transforma no que o servidor espera.
No modo de proxy reverso, o mitmproxy reescreve automaticamente o cabeçalho do Host para corresponder ao servidor upstream.
Isso permite que o mitmproxy se conecte facilmente a endpoints existentes na web aberta (por exemplo, mitmproxy -R https://example.com).
No entanto, lembre-se de que URLs absolutos no documento retornado ou redirecionamentos HTTP NÃO serão reescritos pelo mitmproxy.
Isso significa que, se você clicar em um link para “http://example.com” na página da Web retornada, será direcionado diretamente para esse
URL, ignorando o mitmproxy.
Uma maneira possível de resolver isso é modificar o arquivo hosts do seu sistema operacional para que “example.com” resolva para o IP do
seu proxy e, em seguida, acesse o proxy indo diretamente para example.com. Certifique-se de que seu proxy ainda possa resolver o IP
original ou especifique um IP em mitmproxy.
55
Machine Translated by Google
CAPÍTULO 19
Transmissão de respostas
Usando o recurso de streaming do mitmproxy, o conteúdo da resposta pode ser passado para o cliente de forma incremental antes de ser totalmente
recebido pelo proxy. Isso é especialmente útil para arquivos binários grandes, como vídeos, onde o buffer de todo o arquivo torna o navegador do
cliente mais lento.
Por padrão, o mitmproxy lerá a resposta inteira, realizará as manipulações indicadas nela e enviará a resposta (possivelmente modificada) ao cliente.
Em alguns casos, isso é indesejável e você pode querer “transmitir” a resposta de volta para o cliente. Quando o streaming está habilitado, a resposta
não é armazenada em buffer no proxy, mas enviada diretamente de volta ao cliente.
O streaming pode ser ativado na linha de comando para todos os corpos de resposta que excedem um determinado tamanho. O argumento SIZE
entende sufixos k/m/g, por exemplo, 3m para 3 megabytes.
Aviso: quando o streaming de resposta estiver ativado, o conteúdo de resposta transmitido não será gravado ou preservado de forma
alguma.
Nota: Quando a transmissão de resposta está habilitada, o corpo da resposta não pode ser modificado pelos meios usuais.
Você também pode usar um script para personalizar exatamente quais respostas são transmitidas.
Respostas que devem ser marcadas para streaming definindo seu atributo .stream como True:
def responseheaders(fluxo):
"""
Ativa o streaming para todas as respostas.
Isso é equivalente a passar `--stream 0` para mitmproxy.
"""
flow.response.stream = Verdadeiro
57
Machine Translated by Google
Quando o streaming de resposta estiver habilitado, as partes do código que, de outra forma, teriam realizado alterações no corpo
da resposta verão um corpo de resposta vazio. Qualquer modificação será ignorada.
As respostas transmitidas geralmente são enviadas em blocos de 4.096 bytes. Se a resposta for enviada com um cabeçalho
Transfer-Encoding: chunked, a resposta será transmitida um chunk por vez.
Se o atributo .stream puder ser chamado, .stream envolverá o gerador que produz todos os fragmentos.
chunks é um gerador que pode ser usado para iterar sobre todos os chunks.
"""
para pedaço em pedaços:
def responseheaders(fluxo):
flow.response.stream = modificar
Veja também:
• Ignorar domínios
CAPÍTULO 20
Modo MEIAS
59
Machine Translated by Google
CAPÍTULO 21
Quando a opção de cookie fixo é definida, __mitmproxy__ adicionará o cookie definido mais recentemente pelo servidor a qualquer
solicitação sem cookies. Considere um serviço que define um cookie para rastrear a sessão após a autenticação. Usando cookies
pegajosos, você pode ativar o mitmproxy e autenticar em um serviço como faria normalmente usando um navegador. Após a autenticação,
você pode solicitar recursos autenticados por meio do mitmproxy como se não fossem autenticados, pois o mitmproxy adicionará
automaticamente o cookie de rastreamento de sessão às solicitações. Entre outras coisas, isso permite interações de script com recursos
autenticados (usando ferramentas como wget ou curl) sem ter que se preocupar com autenticação.
Sticky cookies são especialmente poderosos quando usados em conjunto com a repetição do lado do cliente - você pode gravar o
processo de autenticação uma vez e simplesmente reproduzi-lo na inicialização sempre que precisar interagir com os recursos protegidos.
A opção sticky auth é análoga à opção sticky cookie, pois os cabeçalhos de autorização HTTP são simplesmente reproduzidos no
servidor depois de vistos. Isso é suficiente para permitir que você acesse um recurso de servidor usando a autenticação HTTP básica por
meio do proxy. Observe que o mitmproxy (ainda) não suporta a reprodução da autenticação HTTP Digest.
61
Machine Translated by Google
CAPÍTULO 22
Proxy TCP
Caso o mitmproxy não lide com um protocolo específico, você pode isentar os nomes de host do processamento, para que o mitmproxy atue como
um encaminhador TCP genérico. Esse recurso está intimamente relacionado à funcionalidade Ignorar Domínios , mas difere em dois aspectos
importantes:
Observe que a interceptação ou modificação de mensagens ainda não é possível. Se você não estiver interessado nas mensagens TCP brutas,
use o recurso de ignorar domínios.
o então T
Para uma descrição detalhada de como o padrão de nome de host funciona, consulte o recurso Ignorar Domínios .
Veja também:
• Ignorar domínios
• Transmissão de respostas
63
Machine Translated by Google
CAPÍTULO 23
Nesse modo, o mitmproxy aceita solicitações de proxy e encaminha incondicionalmente todas as solicitações para um servidor
proxy upstream especificado. Isso contrasta com o Reverse Proxy, no qual o mitmproxy encaminha solicitações HTTP comuns para
um servidor upstream.
65
Machine Translated by Google
CAPÍTULO 24
Certificados a montante
Quando o mitmproxy recebe uma conexão destinada a um serviço protegido por SSL, ele congela a conexão antes de ler seus dados de
solicitação e faz uma conexão com o servidor upstream para “cheirar” o conteúdo de seu certificado SSL. As informações obtidas - o nome
comum e os nomes alternativos do assunto - são então usadas para gerar o certificado de interceptação, que é enviado ao cliente para
que a conexão possa continuar.
Essa pequena dança bastante intrincada nos permite gerar certificados corretos perfeitamente, mesmo que o cliente tenha especificado
apenas um endereço IP em vez do nome do host. Isso também significa que não precisamos farejar dados adicionais para gerar certificados
no modo transparente.
O sniffing de certificados upstream está ativado por padrão e, opcionalmente, pode ser desativado.
67
Machine Translated by Google
CAPÍTULO 25
Proxy transparente
Quando um proxy transparente é usado, o tráfego é redirecionado para um proxy na camada de rede, sem que seja necessária qualquer
configuração do cliente. Isso torna o proxy transparente ideal para aquelas situações em que você não pode alterar o comportamento do
cliente - aplicativos Android que ignoram o proxy são um exemplo comum.
Para configurar o proxy transparente, precisamos de dois novos componentes. O primeiro é um mecanismo de redirecionamento que
redireciona de forma transparente uma conexão TCP destinada a um servidor na Internet para um servidor proxy de escuta. Isso
geralmente assume a forma de um firewall no mesmo host que o servidor proxy - iptables no Linux ou pf no OSX. Quando o proxy recebe
uma conexão redirecionada, ele vê uma solicitação HTTP vanilla, sem uma especificação de host. É aqui que entra o segundo novo
componente - um módulo host que nos permite consultar o redirecionador para o destino original da conexão TCP.
No momento, o mitmproxy oferece suporte a proxy transparente no OSX Lion e superior, e em todas as versões atuais do Linux.
Por padrão, o mitmproxy usará seu próprio endereço IP local para suas conexões do lado do servidor. Caso isso não seja desejado, o
argumento –spoof-source-address pode ser usado para usar o endereço IP do cliente para conexões do lado do servidor. A seguinte
configuração é necessária para que este modo funcione:
regra de ip adicionar fwmark $MARK lookup $TABLE_ID rota de ip adicionar local $CLIENT_NET dev lo table $TA
BLE_ID
Este modo requer privilégios de root. Há um wrapper no diretório de exemplos chamado 'mitm proxy_shim.c', que permitirá que você use
este modo com privilégios eliminados. Pode ser usado da seguinte forma:
gcc exemplos/mitmproxy_shim.c -o mitmproxy_shim -lcap sudo chown root:root mitmproxy_shim sudo chmod u+s
mitmproxy_shim ./mitmproxy_shim $(which mitmproxy) -T –spoof-source-address
69
Machine Translated by Google
CAPÍTULO 26
Linux
No Linux, o mitmproxy se integra ao mecanismo de redirecionamento iptables para obter o modo transparente.
3. Se sua máquina de destino estiver na mesma rede física e você a configurou para usar um gateway personalizado, desative
Redirecionamentos ICMP:
Você também pode considerar habilitar isso permanentemente em /etc/sysctl.conf como demonstrado aqui.
4. Crie um conjunto de regras iptables que redirecione o tráfego desejado para a porta mitmproxy. Os detalhes serão diferentes de acordo com
sua configuração, mas o conjunto de regras deve ser algo assim:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080 iptables -t nat -A PREROUTING -i eth0 -p
tcp --dport 443 -j REDIRECT --to- porta 8080
O sinalizador -T ativa o modo transparente e o argumento --host informa ao mitmproxy para usar o valor do cabeçalho Host para exibição
de URL.
6. Por fim, configure seu dispositivo de teste para usar o host no qual o mitmproxy está sendo executado como o gateway padrão.
Para obter um passo a passo detalhado, dê uma olhada no tutorial Transparently proxy virtual machines .
71
Machine Translated by Google
CAPÍTULO 27
OSX
OSX Lion integrou o pf filtro de pacotes do projeto OpenBSD, que o mitmproxy usa para implementar o modo transparente no OSX. Observe que isso
significa que não oferecemos suporte ao modo transparente para versões anteriores do OSX.
rdr em en2 inet proto tcp para qualquer porta 80 -> 127.0.0.1 porta 8080 rdr em en2 inet proto tcp
para qualquer porta 443 -> 127.0.0.1 porta 8080
Essas regras dizem ao pf para redirecionar todo o tráfego destinado à porta 80 ou 443 para a instância mitmproxy local em execução na porta
8080. Você deve substituir en2 pela interface na qual seu dispositivo de teste aparecerá.
5. E agora habilite-o:
6. Configure sudoers para permitir que mitmproxy acesse pfctl. Edite o arquivo /etc/sudoers em seu sistema como root. Adicionar
a seguinte linha no final do arquivo:
Observe que isso permite que qualquer usuário no sistema execute o comando /sbin/pfctl -s state como root sem uma senha. Isso permite
apenas a inspeção da tabela de estados, portanto, não deve ser um risco de segurança indevido. Se você for especial, sinta-se à vontade para
apertar a restrição até o usuário que está executando o mitmproxy.
O sinalizador -T ativa o modo transparente e o argumento --host informa ao mitmproxy para usar o valor do cabeçalho Host para exibição de
URL.
8. Por fim, configure seu dispositivo de teste para usar o host no qual o mitmproxy está sendo executado como o gateway padrão.
Nota: Observe que as regras rdr no pf.conf fornecidas acima só se aplicam ao tráfego de entrada. Isso significa que eles NÃO redirecionarão o
tráfego vindo da própria caixa em execução. Não podemos distinguir entre uma conexão de saída
73
Machine Translated by Google
de um aplicativo não-mitmproxy e uma conexão de saída do próprio mitmproxy - se você deseja interceptar seu tráfego OSX, deve
usar um host externo para executar o mitmproxy. No entanto, o pf é flexível para atender a uma variedade de possibilidades
criativas, como interceptar tráfego proveniente de VMs. Veja a página man do pf.conf para mais.
CAPÍTULO 28
Visão geral
O Mitmproxy possui uma API de script poderosa que permite controlar praticamente qualquer aspecto do tráfego que está sendo proxy. Na
verdade, grande parte da funcionalidade principal do mitmproxy é implementada usando exatamente a mesma API exposta aos scripters
(consulte mitmproxy/addons).
O script é orientado a eventos, com manipuladores nomeados no objeto script chamados em pontos apropriados da operação do mitmproxy.
Aqui está um script mitmproxy completo que adiciona um novo cabeçalho a cada resposta HTTP antes de ser retornado ao cliente:
def resposta(fluxo):
flow.response.headers["newheader"] = "foo"
Todos os eventos que lidam com uma solicitação HTTP obtêm uma instância de HTTPFlow, que podemos usar para manipular a própria
resposta. Agora podemos executar este script usando mitmdump, e o novo cabeçalho será adicionado a todas as respostas que passam
pelo proxy:
No exemplo acima, o objeto de script é o próprio módulo add_header. Ou seja, os manipuladores são declarados no nível global do script.
Isso é ótimo para hacks rápidos, mas logo se torna limitante à medida que os scripts se tornam mais sofisticados.
Quando um script é inicializado pela primeira vez, o evento start é chamado antes que qualquer outra coisa aconteça. Você pode substituir o
objeto de script atual retornando-o desse manipulador. Veja como isso fica quando aplicado ao exemplo acima:
class AddHeader:
def response(self, flow):
flow.response.headers["newheader"] = "foo"
75
Machine Translated by Google
Então, aqui, estamos usando um script de nível de módulo para “inicializar” em uma instância de classe. Deste ponto em diante, o script de nível de
módulo é removido da cadeia do manipulador e é substituído pela instância da classe.
Os scripts podem lidar com seus próprios argumentos de linha de comando, assim como qualquer outro programa Python. Vamos construir no
exemplo acima para fazer algo um pouco mais sofisticado - substituir um valor por outro em todas as respostas. Os objetos HTTPRequest e
HTTPResponse do Mitmproxy têm um método de substituição útil que cuida de todos os detalhes para nós.
importar argparse
Substituidor de classe :
def __init__(self, src, dst):
self.src, self.dst = src, dst
def start():
parser = argparse.ArgumentParser() parser.add_argument("src",
type=str) parser.add_argument("dst", type=str) args =
parser.parse_args() return Replacer(args.src, args.dst)
Sempre que um manipulador é chamado, mitpmroxy reescreve o ambiente de script para que ele veja seus próprios argumentos como se tivesse
sido invocado a partir da linha de comando.
Os scripts não devem sair diretamente para stderr ou stdout. Em vez disso, o objeto de log no módulo de contexto ctx deve ser usado, para que o
programa host mitmproxy possa manipular a saída adequadamente. Assim, o mitmdump pode imprimir a saída do script colorido para o terminal, e
o console do mitmproxy pode colocar a saída do script no buffer de eventos.
def start():
ctx.log.info("Este é um texto informativo.") ctx.log.error("Este é um erro.")
O módulo ctx também expõe o objeto master mitmproxy em ctx.master para uso avançado.
Quando um fluxo é carregado do disco, a sequência de eventos pela qual o fluxo teria passado no fio é parcialmente reproduzida. Assim,
por exemplo, um fluxo HTTP carregado do disco acionará requestheaders, request, responseheaders e response em ordem. Podemos
usar esse comportamento para transformar o tráfego salvo usando scripts. Por exemplo, podemos invocar o script substituto acima no
tráfego salvo da seguinte maneira:
Este comando inicia o script de argumentos, lê todos os fluxos salvos transformando-os no processo, então grava todos eles para
alterados.
A ferramenta de console mitmproxy fornece maneiras interativas de executar scripts de transformação em fluxos - por exemplo, você pode
executar um script one-shot em um único fluxo através do | (pipe) atalho.
28.6 Simultaneidade
O mecanismo de script mitmproxy é de encadeamento único e o proxy é bloqueado enquanto os manipuladores de script são executados.
Isso simplifica enormemente o caso mais comum, em que os manipuladores são leves e o bloqueio não afeta o desempenho.
É possível implementar um mecanismo simultâneo em cima da estrutura de bloqueio e o mitmproxy inclui um exemplo prático disso que
é adequado para a maioria dos propósitos. Você pode usá-lo da seguinte forma:
tempo de importação
28.7 Teste
O Mitmproxy inclui vários auxiliares para testar complementos. O módulo mitmproxy.test.taddons contém um auxiliar de contexto que
cuida da configuração e desmontagem do contexto do evento do complemento. o
O módulo mitmproxy.test.tflow contém auxiliares para criar fluxos de teste rapidamente. Pydoc é a referência canônica para
esses módulos, e o próprio conjunto de testes do mitmproxy é uma excelente fonte de exemplos de uso. Aqui, por exemplo, estão
os testes de unidade mitmproxy para a opção anticache, demonstrando uma boa seção transversal dos auxiliares de teste:
classe TestAntiCache:
def test_simple(self): sa =
anticache.AntiCache()
com taddons.context() como tctx:
f = tflow.tflow(resp=True) f.request.headers["if-
modified-since"] = "teste" f.request.headers["if-none-match"] = "teste"
sa.request(f) afirma
"if-modified-since" em f.request.headers afirma "if-none-match" em
f.request.headers
O Mitmproxy monitora scripts para modificações e os recarrega na mudança. Quando isso acontece, o script é encerrado (o
evento done é chamado) e a nova instância é iniciada como se o script tivesse acabado de ser carregado (os eventos start e
configure são chamados).
CAPÍTULO 29
Eventos
29.1 Geral
79
Machine Translated by Google
29.2 Conexão
Esses eventos são chamados somente após uma conexão fazer uma atualização HTTP com “101 Switching Protocols”. Nenhum outro
evento relacionado a HTTP após o handshake ser emitido, apenas novas mensagens WebSocket são chamadas.
Esses eventos são chamados apenas se a conexão estiver no modo TCP. Assim, por exemplo, eventos TCP não são chamados para
conexões HTTP/S comuns.
CAPÍTULO 30
API
• Erros
– mitmproxy.flow.Error
• HTTP
– mitmproxy.http.HTTPRequest
– mitmproxy.http.HTTPResponse
– mitmproxy.http.HTTPFlow
• Registro
– mitmproxy.log.Log
– mitmproxy.log.LogEntry
30.1 Erros
Isso é diferente de uma resposta de erro de protocolo (digamos, um código HTTP 500), que é representado por um objeto
HTTPResponse normal. Esta classe é responsável por indicar erros que estão fora das comunicações normais de protocolo, como
conexões interrompidas, timeouts, erros de protocolo.
get_state()
Recupere o estado do objeto.
set_state(estado)
Carregar o estado do objeto dos dados retornados por uma chamada get_state.
30.2 HTTP
class mitmproxy.http.HTTPRequest(first_line_format, method, scheme, host, port, path, http_version, headers, content,
timestamp_start=Nenhum, timestamp_end=Nenhum, is_replay=False)
83
Machine Translated by Google
classmethod wrap(request)
Encapsula um mitmproxy.net.http.Request existente.
anti-cache()
Modifica esta solicitação para remover cabeçalhos que podem produzir uma resposta em cache. Ou seja, removemos os cabeçalhos
ETags e If-Modified-Since.
anticomp()
Modifica esta solicitação para remover cabeçalhos que compactarão os dados do recurso.
constrain_encoding()
Limita os valores permitidos de codificação de aceitação, com base no que podemos decodificar adequadamente.
contente
O corpo da mensagem HTTP decodificado com o cabeçalho de codificação de conteúdo (por exemplo, gzip)
biscoitos
Os cookies de solicitação.
decodificar(estrito=verdadeiro)
Decodifica o corpo com base no cabeçalho Content-Encoding atual e, em seguida, remove o cabeçalho. Se não houver cabeçalho
Content-Encoding, nenhuma ação será executada.
codificar(e)
Codifica o corpo com a codificação e, onde e é “gzip”, “deflate”, “identity” ou “br”. Quaisquer codificações de conteúdo existentes são
substituídas, o conteúdo não é decodificado previamente.
first_line_format Formulário
de solicitação HTTP conforme definido no RFC7230.
cabeçalhos
Retorna mitmproxy.net.http.Headers
hospedeiro
Anfitrião de destino. Isso pode ser analisado a partir da solicitação bruta (por exemplo, de uma linha de solicitação GET http://
example.com/HTTP/1.1) ou inferida do modo proxy (por exemplo, um IP em modo transparente).
http_version String
de versão, por exemplo, “HTTP/1.1”
método
Método de solicitação HTTP, por exemplo, “GET”.
multipart_form Os
dados do formulário multipart como um objeto MultiDictView. Um multidict.MultiDictView vazio se o tipo de conteúdo indicar
dados que não são de formulário ou se o conteúdo não puder ser analisado.
caminho Caminho da solicitação HTTP, por exemplo, “/index.html”. Garantido para começar com uma barra, exceto para solicitações
OPTIONS, que podem ser apenas “*”.
path_components Os
componentes do caminho da URL como uma tupla de strings. Os componentes não são citados.
porta
Porta de destino
anfitrião_bonito
Semelhante ao host, mas usando os cabeçalhos do Host como uma fonte de dados preferencial adicional. Isso é útil no modo
transparente, onde o host é apenas um endereço IP, mas pode não refletir o destino real, pois o cabeçalho do Host pode ser
falsificado.
bonita_url
Como url, mas usando pretty_host em vez de host.
inquerir
A string de consulta de solicitação como um objeto MultiDictView.
raw_content
O corpo da mensagem HTTP bruto (codificado)
esquema
Esquema de solicitação HTTP, que deve ser “http” ou “https”.
texto
O corpo da mensagem HTTP decodificado com o cabeçalho de codificação de conteúdo (por exemplo, gzip) e o conjunto de caracteres do cabeçalho do tipo
de conteúdo.
timestamp_end
Data e hora do último byte
timestamp_start
Data e hora do primeiro byte
30.2. HTTP 85
Machine Translated by Google
URL
A string de URL, construída a partir dos componentes de URL da solicitação
urlencoded_form Os
dados de formulário codificados por URL como um objeto MultiDictView. Um multidict.MultiDictView vazio se o tipo de conteúdo
indicar dados que não são de formulário ou se o conteúdo não puder ser analisado.
classmethod wrap(resposta)
Encapsula um mitmproxy.net.http.Response existente.
contente
O corpo da mensagem HTTP decodificado com o cabeçalho de codificação de conteúdo (por exemplo, gzip)
cookies Os
cookies de resposta. Um MultiDictView possivelmente vazio, onde as chaves são strings de nomes de cookies e os valores são
tuplas (valor, attr). Value é uma string e attr é um MultiDictView contendo atributos de cookie.
Dentro de attrs, atributos unários (por exemplo, HTTPOnly) são indicados por um valor Null.
decodificar(estrito=verdadeiro)
Decodifica o corpo com base no cabeçalho Content-Encoding atual e, em seguida, remove o cabeçalho. Se não houver
cabeçalho Content-Encoding, nenhuma ação será executada.
codificar(e)
Codifica o corpo com a codificação e, onde e é “gzip”, “deflate”, “identity” ou “br”. Quaisquer codificações de conteúdo
existentes são substituídas, o conteúdo não é decodificado previamente.
cabeçalhos
Retorna mitmproxy.net.http.Headers
http_version String
de versão, por exemplo, “HTTP/1.1”
raw_content
O corpo da mensagem HTTP bruto (codificado)
razão
Frase de Razão HTTP, por exemplo, “Não encontrado”. Isso é sempre Nenhum para solicitações HTTP2, porque as respostas
HTTP2 não contêm uma frase de razão.
atualizar(agora=Nenhum)
Essa função bastante complexa e heurística atualiza uma resposta do servidor para reprodução.
status_code
Código de status HTTP, por exemplo, 200.
texto
O corpo da mensagem HTTP decodificado com o cabeçalho de codificação de conteúdo (por exemplo, gzip) e o conjunto de caracteres do cabeçalho do tipo
de conteúdo.
timestamp_end
Data e hora do último byte
timestamp_start
Data e hora do primeiro byte
pedido = Nenhum
Objeto HTTPRequest
resposta = Nenhuma
Objeto HTTPResponse
erro = Nenhum
Objeto de erro
Observe que é possível que um Flow tenha uma resposta e um objeto de erro. Isso pode acontecer, por exemplo, quando uma
resposta foi recebida do servidor, mas ocorreu um erro ao enviá-la de volta ao cliente.
server_conn = Nenhum
Objeto ServerConnection
client_conn = Nenhum
Objeto ClientConnection
30.2. HTTP 87
Machine Translated by Google
interceptado = Nenhum
Este fluxo está sendo interceptado no momento?
modo = Nenhum
Em que modo estava a camada proxy ao receber esta solicitação?
backup(force=Falso)
Salve um backup deste fluxo, que pode ser revertido usando uma chamada para .revert().
interceptar()
Interceptar este fluxo. O processamento será interrompido até que o resumo seja chamado.
matar()
Mate este pedido.
modificado()
Este fluxo foi modificado?
retomar()
Continue com o fluxo - chamado após um intercept().
reverter()
Reverta para o último estado de backup.
30.3 Registro
classe mitmproxy.log.Log(master)
O registrador central, exposto a scripts como mitmproxy.ctx.log.
depurar(txt)
Log com depuração de nível.
info(txt)
Log com informações de nível.
avisar(txt)
Log com aviso de nível.
erro(txt)
Log com erro de nível.
CAPÍTULO 31
Meu café local é servido por uma rede sem fio frágil e não confiável, generosamente patrocinada com o dinheiro dos contribuintes pelo conselho
municipal. Após a conexão, você é redirecionado para uma página protegida por SSL que solicita um nome de usuário e uma senha. Depois de
inserir seus dados, você pode aproveitar as desistências intermitentes, as velocidades semelhantes a melado e o proxy transparente configurado
incorretamente.
Eu tendo a automatizar esse tipo de coisa na primeira oportunidade, na teoria de que o tempo gasto agora será mais do que compensado a
longo prazo. Neste caso, eu poderia usar o Firebug para descobrir os parâmetros de postagem do formulário e o URL de destino, depois acione
um editor para escrever um pequeno script usando o urllib do Python para simular uma submissão. Isso é um monte de futzing sobre. Com o
mitmproxy podemos fazer o trabalho em literalmente 30 segundos, sem ter que se preocupar com nenhum detalhe. Aqui está como.
Eu uso um pequeno complemento do Firefox chamado Toggle Proxy para alternar rapidamente de e para mitmproxy. Estou assumindo que
você já configurou seu navegador com a autoridade de certificação SSL do mitmproxy.
E é isso! Agora você tem uma versão serializada do processo de login no arquivo wireless-login e pode reproduzi-lo a qualquer momento assim:
31.4 Enfeites
Nós realmente terminamos neste ponto, mas há alguns enfeites que poderíamos fazer se quiséssemos. eu uso widd para ingressar
automaticamente em redes sem fio que frequento, e isso me permite especificar um comando a ser executado após a conexão. Eu usei o
comando de repetição do cliente acima e voila! - inicialização de rede sem fio totalmente mãos-livres.
89
Machine Translated by Google
Também podemos querer remover solicitações que baixam CSS, JS, imagens e assim por diante. Eles adicionam apenas alguns momentos ao
tempo que leva para reproduzir, mas eles não são realmente necessários e de alguma forma me sinto compelido a apará-los de qualquer maneira.
Então, acionamos a ferramenta de console mitmproxy em nossa conversa serializada, assim:
Agora podemos percorrer e excluir manualmente (usando o atalho de teclado d) tudo o que queremos cortar. Quando terminamos, usamos w para
salvar a conversa de volta no arquivo.
CAPÍTULO 32
32.1 A configuração
Neste tutorial, mostrarei como é simples interferir criativamente no tráfego do Apple Game Center usando mitmproxy. Para
configurar as coisas, instale o certificado raiz mitmproxy. Em seguida, inicie o mitmproxy em sua área de trabalho e configure
o iPhone para usá-lo como proxy.
Vamos dar uma primeira olhada no tráfego do Game Center. O jogo que vou usar neste tutorial é o Super Mega Worm - um
ótimo sidecroll retro-apocalíptico para o iPhone:
Depois de terminar um jogo (não tenha pressa), observe o tráfego fluindo pelo mitmproxy:
91
Machine Translated by Google
Vemos um monte de coisas que poderíamos esperar - inicialização, recuperação de tabelas de classificação e assim por diante. Então, bem
no final, há um POST para esta URL tentadora:
https://service.gc.apple.com/WebObjects/GKGameStatsService.woa/wa/submitScore
<array>
<dict>
<key>categoria</key>
<string>SMW_Adv_USA1</string> <key>contexto</
key> <integer>0</integer> <key>score-value</
key> <integer>55</integer> <key>timestamp</key>
<integer>1363515361321</integer> </dict> </
array> </dict> </plist> <!--(end)-->
Esta é uma lista de propriedades, contendo um identificador para o jogo, uma pontuação (55, neste caso) e um carimbo de data/hora. Parece
bem simples de mexer.
Permite editar o envio de pontuação. Primeiro, selecione-o no mitmproxy e pressione enter para visualizá-lo. Verifique se você está
visualizando a solicitação, não a resposta - você pode usar a guia para alternar entre os dois. Agora pressione e para editar. Você será
solicitado a informar a parte da solicitação que deseja alterar - pressione r para obter o corpo bruto. Seu editor preferido (retirado da
variável de ambiente EDITOR) agora será acionado. Vamos aumentar a pontuação para algo um pouco mais ambicioso:
<!--(block|syntax("xml"))--> <plist
version="1.0"> <dict>
<key>pontuações</key>
<array> <dict>
<key>categoria</key>
<string>SMW_Adv_USA1</string>
<key>contexto</key> <integer>0</integer>
<key>score-value</key> <integer>2200272667</
integer> <key>timestamp</key>
<integer>1363515361321</integer> </dict>
</array> </dict> </plist> <!--(end)-->
A etapa final é reproduzir essa solicitação modificada. Basta pressionar r para repetir.
E é isso - de acordo com os registros, eu sou o maior jogador de Super Mega Worm de todos os tempos.
Há um adendo curioso a este conto. Quando escrevi este tutorial, todas as pontuações dos principais competidores eram as mesmas:
2.147.483.647 (isso não é mais o caso, porque agora existem muitos trapaceiros usando este tutorial). Se você acha que esse número
parece familiar, você está certo: é 2^31-1, o valor máximo que você pode ajustar em um inteiro de 32 bits assinado.
Agora, deixe-me dizer outra coisa peculiar sobre o Super Mega Worm - no final de cada jogo, ele envia sua pontuação anterior mais
alta para o Game Center, não sua pontuação atual. Isso significa que ele armazena seu recorde em algum lugar, e acho que ele lê
essa pontuação armazenada de volta em um número inteiro assinado. Então, se você _fosse_ trapacear pelos meios relativamente
simples de modificar a pontuação salva em seu telefone desbloqueado, então 2^31-1 poderia ser a pontuação máxima que você
poderia obter. Então, novamente, se o próprio jogo armazenar sua pontuação em um int de 32 bits assinado, você poderá obter a
mesma pontuação através de um jogo perfeito, efetivamente vencendo o jogo. Então, qual é neste caso? Vou deixar isso para você decidir.
CAPÍTULO 33
Este passo a passo ilustra como configurar o proxy transparente com mitmproxy. Usamos VMs do VirtualBox com uma
máquina proxy Ubuntu neste exemplo, mas a configuração geral da Internet <–> Proxy VM <–> (Virtual) Internal Network
pode ser aplicada a outras configurações.
Na máquina proxy, eth0 está conectado à internet. eth1 está conectado à rede interna que será proxy e configurada para
usar um ip estático (192.168.3.1).
97
Machine Translated by Google
Usamos dnsmasq para fornecer DHCP e DNS em nossa rede interna. O Dnsmasq é um servidor leve projetado para fornecer serviços DNS (e
opcionalmente DHCP e TFTP) a uma rede de pequena escala.
• Antes de chegarmos a isso, precisamos corrigir algumas peculiaridades do Ubuntu: o Ubuntu >12.04 executa uma instância dnsmasq interna
(ouvindo apenas em loopback) por padrão [1]. Para nosso caso de uso, isso precisa ser desabilitado alterando dns=dnsmasq para
#dns=dnsmasq em /etc/NetworkManager/NetworkManager.conf e
mais tarde.
Aplicar mudanças:
Sua máquina com proxy na rede virtual interna agora deve receber um endereço IP via DHCP:
Para redirecionar o tráfego para o mitmproxy, precisamos adicionar duas regras de iptables:
sudo iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 8080 sudo iptables -t nat -A PREROUTING -i eth1 -p
tcp --dport 443 -j REDIRECT -- para porta 8080
>>> mitmproxy -T
A máquina com proxy não pode vazar nenhum dado fora das solicitações HTTP ou DNS. Se necessário, agora você pode instalar os certificados mitmproxy na
máquina com proxy.
CAPÍTULO 34
Patologia 101
34.1 caminho
Pathod é um daemon HTTP patológico projetado para permitir que você crie quase qualquer resposta HTTP concebível, incluindo aquelas que
violam criativamente os padrões. As respostas HTTP são especificadas usando uma linguagem pequena e concisa que pathod compartilha com
seu pathoc gêmeo maligno. Para começar a jogar com pathod, inicie o daemon:
>>> caminho
Por padrão, o serviço escuta na porta 9999 do host local e o ponto de ancoragem de criação padrão é o caminho /p/. Qualquer coisa após esse
prefixo de URL é tratada como um especificador de resposta. Portanto, acessar o seguinte URL gerará uma resposta HTTP 200 com 100 bytes
de dados aleatórios:
http://localhost:9999/p/200:b@100
Veja a documentação do idioma para ficar (muito) mais sofisticado. O daemon pathod também aceita uma variedade de opções de configuração.
Para visualizá-los, use a ajuda da linha de comando:
O Pathod responde automaticamente a solicitações diretas de HTTP e proxy. Para solicitações de proxy, o host upstream é ignorado e a parte
do caminho da URL é usada para corresponder às âncoras. Isso permite testar o software que oferece suporte a uma configuração de proxy
falsificando respostas de servidores upstream.
Por padrão, tratamos todas as solicitações de proxy CONNECT como tráfego HTTPS, servindo a resposta usando os certificados internos do
pathod ou o par cert/key especificado pelo usuário. Você pode substituir esse comportamento se estiver testando um cliente que faz uma
solicitação CONNECT não SSL usando a opção de linha de comando -C .
34.1.2 Âncoras
As âncoras fornecem uma alternativa para especificar a resposta na URL. Em vez disso, você anexa uma resposta a um ponto de ancoragem
pré-configurado, especificado com um regex. Quando uma URL correspondente ao regex é solicitada, a resposta especificada é exibida.
Aqui, “/foo” é o regex que especifica o caminho da âncora e a parte após o “=” é um especificador de resposta.
103
Machine Translated by Google
Existem dois operadores na linguagem que carregam o conteúdo do arquivo - o operador + para carregar uma especificação de solicitação inteira do arquivo
e o especificador de valor > . No pathod, esses dois operadores são restritos a um diretório especificado na inicialização ou desabilitados se nenhum diretório
for especificado:
O Pathod usa o código de resposta 800 fora do padrão para indicar erros internos, para distingui-los das respostas criadas.
Por exemplo, uma solicitação para:
http://localhost:9999/p/foo
... retornará uma resposta 800 porque “foo” não é um especificador de página válido.
34.2 pathoc
Pathoc é um daemon HTTP perverso projetado para permitir que você crie quase qualquer solicitação HTTP concebível, incluindo aquelas que violam os
padrões de forma criativa. As solicitações HTTP são especificadas usando uma linguagem pequena e concisa, que o pathod compartilha com seu caminho
gêmeo do lado do servidor. Para visualizar a gama completa de opções do pathoc, use a ajuda da linha de comando:
34.2.1 Iniciando
Ou seja, especificamos o nome do host ao qual se conectar, seguido por uma ou mais solicitações. Vamos começar com um exemplo simples:
Aqui, fazemos uma solicitação GET para o caminho / na porta 80 de google.com. A saída do Pathoc nos diz que o servidor respondeu com um redirecionamento
302. Podemos dizer ao pathoc para se conectar usando SSL, caso em que a porta padrão é alterada para 443 (você pode substituir a porta padrão com a
opção de linha de comando -p ):
Existem duas maneiras de dizer ao pathoc para emitir várias solicitações. A primeira é especificá-los na linha de comando, assim:
Nesse caso, o pathoc emite as solicitações especificadas pela mesma conexão TCP - portanto, no exemplo acima, apenas uma conexão
é feita para google.com
A saída é idêntica, mas duas conexões TCP separadas são feitas para o servidor upstream. Esses dois estilos de especificação podem
ser combinados:
Aqui, duas conexões TCP distintas são feitas, com duas solicitações emitidas sobre cada uma.
A combinação da poderosa linguagem de especificação de solicitação do pathoc e algumas de suas opções de linha de comando cria um
fuzzer básico bastante poderoso. Aqui está um exemplo:
A solicitação especificada aqui é um GET válido com um corpo composto por 10 bytes aleatórios, mas com 1 byte aleatório inserido em
um local aleatório. Isso pode estar nos cabeçalhos, na linha de solicitação inicial ou no próprio corpo. Há algumas coisas a serem
observadas aqui:
• Corromper a solicitação dessa maneira geralmente fará com que o servidor entre em um estado em que está aguardando mais
entradas do cliente. É aqui que entra a opção -t , que define um tempo limite que faz com que o pathoc se desconecte após dois
segundos.
• A opção -I diz ao pathoc para ignorar os códigos de resposta HTTP 200. Você pode usar isso para ajustar qual pathoc
considera ser uma condição excepcional e, portanto, digna de registro.
• A opção -e diz ao pathoc para imprimir uma explicação de cada solicitação registrada, na forma de uma especificação de pathoc
expandida com todas as porções aleatórias e adições automáticas de cabeçalho resolvidas. Isso permite reproduzir com precisão
uma solicitação que acionou um erro.
O Pathoc possui um conjunto razoavelmente sofisticado de recursos para interagir com proxies. A sintaxe de solicitação de proxy se
assemelha muito à do HTTP direto, o que significa que é possível fazer solicitações no estilo proxy usando pathoc sem qualquer sintaxe
adicional, simplesmente especificando uma URL completa em vez de um caminho simples:
Outro caso de uso comum é usar uma solicitação HTTP CONNECT para sondar servidores remotos por meio de um proxy. Isso é feito
com a opção de linha de comando -c , que permite especificar um host remoto e um par de portas:
Observe que o pathoc não negocia SSL sem ser explicitamente instruído a fazê-lo. Se você estiver fazendo uma solicitação CONNECT
para um recurso protegido por SSL, também deverá passar o sinalizador -s :
Um recurso interessante da linguagem de especificação de solicitação é que você pode incorporar uma especificação de resposta nela,
que é então adicionado ao caminho da solicitação. Aqui está um exemplo:
Isso cria uma solicitação que se conecta ao servidor pathod e que cria uma resposta que gera um 401, com um
byte aleatório incorporado em um ponto aleatório. A especificação de resposta é analisada e expandida pelo pathoc, então você vê
erros de sintaxe imediatamente. Isso realmente se torna útil quando combinado com o sinalizador -e para mostrar a solicitação expandida:
Observe que a resposta incorporada foi resolvida antes de ser enviada ao servidor, de modo que “ir,@1” (incorpore um
byte em um local aleatório) tornou-se “i15,'o”' (incorpore o caractere “o” no deslocamento 15). Agora você tem uma solicitação pathoc
especificação que é reproduzível com precisão, mesmo com componentes aleatórios. Este recurso é muito útil quando
testando um proxy, já que agora você pode direcionar a resposta do servidor completamente do cliente e ter um log completo de
reprodutíveis para analisar posteriormente.
serventes de mesa;”
200:b@100:dr Solte a conexão aleatoriamente
200:b@100,ascii:ir,@1 100 bytes ASCII como o corpo e injetar aleatoriamente um byte aleatório
200:b@1k:c”text/json” 1k de bytes aleatórios, com um tipo de conteúdo text/json
200:b@1k:p50,120 1k de bytes aleatórios, pausa de 120 segundos após 50 bytes
200:b@1k:pr,f 200:b@100:h@ 1k de bytes aleatórios, mas trava para sempre em um local aleatório
1k,ascii_letters='foo'100 bytes ASCII como o corpo, gerado aleatoriamente 100k nome do cabeçalho, com o
valor 'foo'.
CAPÍTULO 35
especificação de idioma
107
Machine Translated by Google
bVALUE Defina a carga útil do quadro. Se uma chave de mascaramento estiver presente, o valor será codificado automaticamente.
cINTEIRO Defina o código de operação. Isso pode ser um número inteiro de 0 a 15 ou um dos seguintes opcode
nomes: texto (o padrão), continue, binário, fechar, ping, pong.
dOFFSET Desconecta após bytes OFFSET
35.4.1 INTEIRO
35.4.2 COMPENSAÇÃO
Os deslocamentos são calculados em relação à mensagem base, antes que quaisquer injeções ou outras transformações sejam aplicadas. Eles têm
3 sabores:
35.4.3 VALOR
Literais
"foi"
As aspas simples ou duplas são aceitas e as aspas podem ser escapadas com barras invertidas dentro da string:
'fo\'o'
Os valores literais podem conter sequências de escape de barra invertida no estilo Python:
'foo\r\nbar'
Gerado
Uma entrada de símbolo @ especifica que os dados gerados devem ser usados. Existem dois componentes para uma especificação de gerador -
um tamanho e um tipo de dados. Por padrão pathod assume um tipo de dados de “bytes”.
@100
Você pode usar sufixos padrão para indicar valores maiores. Aqui, por exemplo, está um especificador para gerar 100 megabytes:
@100m
Os dados são gerados e servidos de forma eficiente - se você realmente deseja enviar um terabyte de dados para um cliente, o pathod pode fazê-
lo. Os sufixos suportados são:
Os tipos de dados são separados da especificação de tamanho por uma vírgula. Esta especificação gera 100mb de ASCII:
@100m,ascii
dígitos 0-9
hexdigits 0-f
octdigits 0-7
arquivos
Você pode carregar um valor de um caminho de arquivo especificado. Para fazer isso, você deve especificar uma opção _staticdir_ para pathod no
linha de comando, assim:
Todos os caminhos são caminhos relativos neste diretório. As cargas de arquivo são indicadas iniciando o especificador de valor com a esquerda
suporte angular:
<meu/caminho
O valor do caminho também pode ser uma string entre aspas, com a mesma sintaxe dos literais:
<"meu/caminho"
CAPÍTULO 36
biblioteca de caminhos
Por trás das ferramentas de linha de comando pathod e pathoc esconde-se a biblioteca pathod , uma maneira poderosa de
manipular e atender solicitações e respostas HTTP do código. A documentação canônica da biblioteca está no código e pode
ser acessada usando pydoc.
111
Machine Translated by Google
CAPÍTULO 37
pathod.test
O módulo pathod.test é uma camada de teste leve e flexível para clientes HTTP. Ele funciona acionando uma instância do Pathod em um thread
separado, permitindo que você use todas as habilidades do Pathod para gerar respostas e, em seguida, consulte os logs internos do Pathod para
estabelecer o que aconteceu. Todos os mecanismos de inicialização, desligamento, localização de portas livres e assim por diante são resolvidos
para você.
O restante desta página demonstra alguns padrões de interação comuns usando o Nose. Esses exemplos também são aplicáveis apenas com
pequenas modificações nos mecanismos de teste Python mais usados.
pedidos de importação
do teste de importação de caminho
def teste_simples():
"""
113
Machine Translated by Google
pedidos de importação
do teste de importação de caminho
teste de classe :
"""
def teardown(self):
self.d.shutdown()
CAPÍTULO 38
Arquitetura
Para lhe dar uma melhor compreensão de como o mitmproxy funciona, a arquitetura de alto nível do mitmproxy é detalhada
no gráfico a seguir:
arquitetura.pdf
Não deixe de fazer mais perguntas na lista de e-mails, no canal do Slack ou no rastreador de problemas do GitHub.
115
Machine Translated by Google
CAPÍTULO 39
Teste
Todos os projetos mitmproxy se esforçam para manter 100% de cobertura de código. Em geral, patches e pull requests serão
recusados, a menos que sejam acompanhados por uma extensão adequada para o conjunto de testes.
Nossos testes são escritos para o py.test ou nariz estruturas de teste. No ponto em que você envia sua solicitação pull, um comando
assim:
Existem exceções ao requisito de cobertura - por exemplo, grande parte do código da interface do console não pode sensatamente
ser testado na unidade. Essas partes são excluídas da análise de cobertura no arquivo .coveragerc ou usando #pragma
diretivas sem cobertura . Para manter nossa análise de cobertura relevante, usamos essas medidas com a maior parcimônia possível.
117
Machine Translated by Google
CAPÍTULO 40
As chaves mestras SSL podem ser registradas pelo mitmproxy para que programas externos possam descriptografar conexões TLS de e para
o proxy. O log de chaves é ativado configurando a variável de ambiente SSLKEYLOGFILE para que aponte para um arquivo de texto gravável.
Versões recentes do WireShark podem usar esses arquivos de log para descriptografar pacotes. Você pode especificar o caminho do arquivo
de chave no WireShark via
Editar -> Preferências -> Protocolos -> SSL -> (Pré)-Mestre-Segredo nome do arquivo de log.
Observe que SSLKEYLOGFILE também é respeitado por outros programas, por exemplo, Firefox e Chrome. Se isso criar algum problema,
você pode definir MITMPROXY_SSLKEYLOGFILE alternativamente.
119
Machine Translated by Google
Índice
UMA G
anticache() (método mitmproxy.http.HTTPRequest), 84 get_content() (método mitmproxy.http.HTTPRequest),
anticomp() (método mitmproxy.http.HTTPRequest), 84 84
get_content() (método mitmproxy.http.HTTPResponse),
B
backup() (método mitmproxy.http.HTTPFlow), 88 86 get_state() (método mitmproxy.flow.Error), 83
get_text() (método mitmproxy.http.HTTPRequest), 84
C get_text() (método mitmproxy.http.HTTPResponse), 86
client_conn (atributo mitmproxy.http.HTTPFlow), 87
clientconnect() (função integrada), 80 clientdisconnect()
H
(função integrada), 80 configure() (função integrada), 79 cabeçalhos (atributo mitmproxy.http.HTTPRequest), 84
constrain_encoding() (mitmproxy. método cabeçalhos (atributo mitmproxy.http.HTTPResponse), 86
http.HTTPRequest), 84 conteúdo
mitmproxy.http.HTTPRequest),
(atributo host (atributo mitmproxy.http.HTTPRequest), 84
http_connect() (função integrada), 81 http_version
84 conteúdo (atributo mitmproxy.http.HTTPResponse),
86 cookies (atributo mitmproxy.http.HTTPRequest), 84 (mitmproxy.http. atributo HTTPRequest), 85 http_version
cookies (atributo mitmproxy.http.HTTPResponse), 86 (atributo mitmproxy.http.HTTPResponse),
M
make() (método mitmproxy.http.HTTPResponse),
F método 86 (atributo mitmproxy.http.HTTPRequest), 85
first_line_format (mitmproxy.http.HTTPRequest no tributo), MITMPROXY_SSLKEYLOGFILE, modo 119 (atributo
84 mitmproxy.http.HTTPFlow), 88 modificado() (método
mitmproxy.http.HTTPFlow), 88
121
Machine Translated by Google
Dentro
Consulta Q (atributo mitmproxy.http.HTTPRequest), 85
warning() (método mitmproxy.log.Log), 88
R websocket_end() (função integrada), 82
websocket_error() (função integrada), 82
raw_content (atributo mitmproxy.http.HTTPRequest), 85
websocket_handshake() (função integrada), 82
raw_content (atributo mitmproxy.http.HTTPResponse),
87 websocket_message() ( função incorporada), 82
websocket_start() (função incorporada), 82 wrap()
motivo (atributo mitmproxy.http.HTTPResponse), 87 refresh()
(método de classe mitmproxy.http.HTTPRequest), 83 wrap()
(método mitmproxy.http.HTTPResponse), 87 replace()
(método de classe mitmproxy.http.HTTPResponse),
(método mitmproxy.http.HTTPFlow), 88 replace() (método
86
mitmproxy.http.HTTPRequest), 85 replace() (método
mitmproxy.http.HTTPResponse), 87 request (atributo
mitmproxy.http.HTTPFlow), 87 request() (função integrada),
81 requestheaders() (função integrada), 81 response
(mitmproxy. atributo http.HTTPFlow), 87 response() (função
integrada), 81 responseheaders() (função integrada), 81
resume() (método mitmproxy.http.HTTPFlow), 88 revert()
(mitmproxy.http. método HTTPFlow), 88
S
esquema (atributo mitmproxy.http.HTTPRequest), 85
server_conn (atributo mitmproxy.http.HTTPFlow), 87
serverconnect() (função integrada), 80 serverdisconnect()
(função integrada), 80 set_state() (mitmproxy. flow.Error), 83
SSLKEYLOGFILE, 119 start() (função integrada), 79
status_code (atributo mitmproxy.http.HTTPResponse),
87
T
tcp_end() (função incorporada), 82
tcp_error() (função incorporada), 82
tcp_message() (função incorporada), 82
tcp_start() (função incorporada), 82 text
(mitmproxy.http. Atributo HTTPRequest), 85 texto
(atributo mitmproxy.http.HTTPResponse), 87
122 Índice