
Framework de Fingerprinting de Ferramentas de Segurança Passivas
Você já quis uma maneira simples, fácil e furtiva de contornar múltiplas classes de produtos de segurança? O pstf^2 (pronuncia-se pstf-quadrado) é uma implementação de um servidor HTTP capaz de realizar fingerprinting passivo de navegadores – e pode ser exatamente o que você está procurando. Quando atacantes tentam entregar um payload pela internet, eles precisam superar múltiplas ferramentas capazes de escanear links recebidos. Filtros de e-mail, mecanismos de varredura e até mesmo submissão a sandbox via URL – todos podem ser contornados uma vez que o pstf2 os detecta de forma passiva. Uma vez detectado, a ferramenta permite diferenciar entre serviços de segurança e vítimas em potencial, entregando uma resposta maliciosa ou benigna.
Esta ferramenta foi lançada durante a BlackHat EU 2020: https://www.blackhat.com/eu-20/arsenal/schedule/#pstf2-link-scanners-evasion-made-easy-21763
Detalhes sobre a pesquisa estão disponíveis nesta postagem do blog: https://blogs.akamai.com/sitr/2020/12/evading-link-scanning-security-services-with-passive-fingerprinting.html
A verdadeira pergunta é: como funcionam os scanners de links? Inspecionar um link malicioso é uma ação que envolve um cliente web enviando uma requisição HTTP GET. Cada fornecedor usa uma implementação interna diferente – a maioria tenta imitar uma interação real de usuário até certo ponto. O pstf^2 é um servidor HTTP simples baseado em Python que aplica táticas bem conhecidas de detecção de bots para determinar se uma requisição recebida é de uma ferramenta de segurança automatizada. O operador do servidor pode personalizar as respostas, por exemplo – se um scanner for detectado, redirecionar para o Google; caso contrário, enviar conteúdo malicioso.
Abaixo estão as principais táticas implementadas como parte do pstf^2:
Ferramentas de segurança tentam se disfarçar como clientes legítimos, personificando navegadores reais, no entanto – geralmente não é esse o caso. É comum ver ferramentas que não são mantidas adequadamente usando cabeçalhos fake de user-agent para versões de navegador com uma década de idade. O pstf^2 permite definir um limite mínimo para o que você considera uma versão real não obsoleta.
Existem muitos tipos de implementações estranhas que a ferramenta é capaz de detectar. Alguns exemplos apresentados na palestra da BlackHat foram:
via: que revelava a natureza do host virtual usado para sandboxing.referer: que sugeria que o link foi acessado a partir do Google, por exemplo, referer: google.com/search?q=specific.site.com.
nos cenários que testamos, isso não fazia sentido, pois o produto escaneia e-mails e quando alguém clica em um e-mail (não de uma interface web) esse cabeçalho está ausente.Múltiplos parâmetros TCP podem indicar uma versão específica de SO ou um sabor específico. Alguns clientes falsificam o cabeçalho user-agent, mas estão rodando sobre um SO diferente do que declaram.
Clientes hospedados em redes de provedores de nuvem específicos têm MTU diferente do valor padrão de 1500 bytes.
Em alguns casos, a requisição é enviada de um ASN associado explicitamente a um fornecedor de segurança específico. Em outros, a origem da requisição é um provedor de hospedagem em nuvem, embora não incrimine um fornecedor específico, é improvável que seja um usuário típico.
Em casos raros, o endereço IP do cliente possui um registro PTR, associando-o a uma URL relacionada a um fornecedor de segurança.
Supondo que você já tenha o Docker instalado, é tão simples quanto:
docker-compose up
Caso prefira evitar o Docker, siga estes passos.
Execute:
pip install requirements.txt
Isso instalará todos os módulos Python externos necessários.
Antes de implantar o pstf^2, baixe e instale o p0f. Ele está atualmente disponível em:
https://lcamtuf.coredump.cx/p0f3/
Agora, configure corretamente lib/servers/server_config.yml para apontar para o caminho correto, ou seja:
p0f_config:
# change your username at the very least, remember to change in both paths
p0f_bin_path: '/Users/$seu_nome_de_usuario/$mais_pastas/web_fp/p0f-3.09b/p0f'
p0f_fp_path: '/Users/$seu_nome_de_usuario/$mais_pastas/web_fp/p0f-3.09b/p0f.fp'
iface: 'lo0'
p0f_named_socket: '/tmp/p0f_socket'
Além disso, verifique se iface é a mesma interface que está executando seu servidor HTTP Python. No exemplo acima, é a interface de loopback.
Uma vez que os requisitos sejam atendidos, execute:
python driver.py
Você pode usar qualquer uma das seguintes flags:
--p0f_bin_path P0F_BIN_PATH
--p0f_fp_path P0F_FP_PATH
--p0f_iface P0F_IFACE
Todas são usadas para ajustar parâmetros relacionados ao p0f: o binário em si, o arquivo de fingerprinting e a interface usada, que por padrão é eth0.
Você deve ver uma saída semelhante à seguinte:
2020-04-15 17:37:06,896 - pstf2_logger - INFO - Starting p0f...
2020-04-15 17:37:06,896 - pstf2_logger - INFO - Running command:
/Users/gbitensk/work/web_fp/p0f-3.09b/p0f -i lo0 -s /tmp/p0f_socket -f /Users/gbitensk/work/web_fp/p0f-3.09b/p0f.fp
2020-04-15 17:37:06,898 - pstf2_logger - INFO - p0f started!
2020-04-15 17:37:06,898 - pstf2_logger - INFO - Starting HTTP server...
2020-04-15 17:37:06,898 - pstf2_logger - INFO - HTTP server started!
2020-04-15 17:37:06,899 - pstf2_logger - INFO - If you wish to terminate the server press CTRL+C
Termine o servidor pressionando Ctrl+C; isso encerrará tanto a instância HTTP quanto a do p0f. Você deve ver algo semelhante a:
2020-04-15 17:37:48,263 - pstf2_logger - INFO - HTTP server stopped!
2020-04-15 17:37:48,263 - pstf2_logger - INFO - Killing p0f...
2020-04-15 17:37:48,263 - pstf2_logger - INFO - p0f killed!
2020-04-15 17:37:48,263 - pstf2_logger - INFO - exiting...
Observe que configurar um registro DNS apontando uma URL para seu servidor está além do escopo do pstf^2 e é de sua própria responsabilidade.
O pstf^2 tem payloads padrão que são definidos dentro de server_config.yml e podem ser personalizados com facilidade.
Existem dois modos, alternados alterando a variável rickroll_mode para YES ou NO.
Se estiver ativado, a ferramenta de segurança será redirecionada para uma página do YouTube com o famoso vídeo Rickrolling; caso contrário, servirá uma string definida no mesmo arquivo YAML.
Por padrão – a resposta "maliciosa" foi definida como a string de teste padrão do EICAR.
Optei por lançar publicamente esta ferramenta como um projeto de código aberto porque:
Como parte da construção da ferramenta, ela foi testada contra 15 produtos diferentes; todos falharam. Embora eu tenha divulgado de forma responsável detalhes sobre o ataque, ainda temos um longo caminho a percorrer e minha expectativa é que, ao tornar a ferramenta pública, aumentaremos a conscientização sobre essas táticas que já estão sendo abusadas pelos "bandidos".
@Den1al por fornecer conselhos ao construir esta ferramenta especificamente, e escrever Python corretamente em geral, além de ajudar a criá-la como uma imagem Docker.