Casos de ataques encontrados em logs de acesso
(nishtahir.com)- Nos logs de acesso de um IP público auto-hospedado por mais de 10 anos, aparecem tentativas de ataque que vão desde varredura de credenciais até injeção de comandos contra dispositivos IoT, mostrando o tipo de ataque que serviços expostos à internet recebem no dia a dia
- O padrão mais comum era a busca por arquivos e diretórios de configuração, vasculhando caminhos como
.env,.aws/credentials,.git/config,backup/etest/; algumas requisições usavam User-Agent com erro de digitação, comoMozlila/5.0 - As tentativas de Shellshock colocavam payloads em formato de função Bash no User-Agent para tentar ler
/etc/passwd, além de repetir palpites para vários caminhos CGI - Os ataques contra LuCI e Zyxel tentavam inserir comandos na interface web de roteadores e dispositivos embarcados para baixar e executar scripts remotos e binários para várias arquiteturas
- É preciso reduzir o que fica exposto na internet pública, aplicar autenticação e restrições por IP às ferramentas e diretórios necessários, e manter dispositivos IoT atualizados, separando-os da rede pública sempre que possível
Tráfego recebido por serviços expostos à internet pública
- Ao longo de mais de 10 anos de auto-hospedagem, a experiência foi manter a posse direta dos próprios dados e reduzir a dependência de plataformas além do host em nuvem
- Ao expor um IP à internet pública, logo chega muito tráfego malicioso; olhando os logs de acesso, dá para rastrear que tipo de ataque foi recebido recentemente
- Esta análise está mais próxima da observação de um desenvolvedor curioso do que de uma perícia feita por um especialista em segurança
- Os endereços IP dos atacantes e algumas expressões ofensivas usadas por eles foram ocultados por cautela
Busca por credenciais e arquivos de configuração
- O ataque mais comum era a tentativa de encontrar credenciais por meio de travessia de diretórios, com muitas requisições para arquivos
.env- Exemplos de caminhos solicitados:
/laravel/.env,/backend/.env,/api/.env,/.env,//.env .envnormalmente é tratado como um arquivo que guarda secrets da aplicação
- Exemplos de caminhos solicitados:
- Arquivos relacionados à AWS e configurações de repositórios Git também entravam na mira
- Exemplos:
/aws.yml,/.env.bak,/info.php,/.aws/credentials,/config/aws.yml,/.git/config
- Exemplos:
- Diretórios comuns que podem ter sido deixados por engano também eram requisitados repetidamente
- Exemplos:
/old/,/new/,/test/,/backup/,/temp/
- Exemplos:
- Alguns User-Agents continham
Mozlila/5.0, aparentemente um erro de digitação deMozilla/5.0- O resultado de uma busca no GitHub sugere que esse erro pode ter sido gerado por uma ferramenta comum e depois copiado e colado
- Também foram vistas requisições em busca de ferramentas de acesso remoto ou configuração
- Exemplos:
/actuator/gateway/routes,/hudson,/ui/login.action,/?XDEBUG_SESSION_START=phpstorm
- Exemplos:
- Na internet pública, o ideal é expor apenas o mínimo indispensável; se for preciso expor ferramentas ou diretórios, é necessário aplicar uma camada de autenticação e, quando possível, restrições a IPs específicos
Tentativas de Shellshock
- Várias requisições pareciam mirar a vulnerabilidade Shellshock
- Esse ataque busca executar comandos arbitrários em servidores web que rodam scripts CGI com versões vulneráveis do Bash
- Quando um programa CGI é iniciado, variáveis de ambiente são definidas com base no conteúdo da requisição, e
HTTP_USER_AGENTé uma delas - Se houver caracteres como
() { :; };, o Bash interpreta isso como uma função que deve executar
- Quando um programa CGI é iniciado, variáveis de ambiente são definidas com base no conteúdo da requisição, e
- Nos logs reais, o User-Agent continha payloads como os seguintes
() { ignored; }; echo Content-Type: text/html; echo ; /bin/cat /etc/passwd() { ignored; };é o formato de definição de uma função Bashecho Content-Type: text/html; echo ;imprime oContent-Typeda resposta HTTP e uma linha em branco/bin/cat /etc/passwdé o comando que tentaria exibir o conteúdo de/etc/passwd, onde ficam informações sobre contas de usuário
- Se o ataque tivesse sucesso, poderia levar ao acesso a credenciais de usuários e à execução de código arbitrário no servidor
- Assim como na travessia de diretórios, o atacante também tentava adivinhar caminhos comuns como
/cgi-bin/status,/cgi-bin/stats,/cgi-bin/test,/cgi-bin/status/status.cgi,/test.cgi,/debug.cgi,/cgi-bin/test-cgi
Injeção de comandos contra LuCI
- Uma das requisições parecia mirar o LuCI, a interface web para roteadores OpenWRT
- A URL do ataque inseria comandos no campo
countrypara baixar e executar o script de shell remototenda.sh- Após decodificar a URL, o comando seguia um fluxo de ir para
/tmp, apagar arquivos, baixar o script comwget, dar permissão de execução e executá-lo
- Após decodificar a URL, o comando seguia um fluxo de ir para
- O script baixado incluía instruções para baixar e executar binários adicionais
- Apareciam nomes que parecem arquiteturas-alvo, como
mips,mpsl,x86_64,arm,arm5,arm6,arm7,i586,i686,powerpc,sh4,m68k,sparc - Tentar binários para várias arquiteturas sugere uma forma de ampliar o alcance do ataque quando o invasor não sabe qual é a arquitetura do dispositivo-alvo
- Apareciam nomes que parecem arquiteturas-alvo, como
- Para investigar mais, foram baixados binários incompatíveis com o ambiente e analisados com Ghidra
- No início, havia apenas 3 funções e poucos dados de string
- Em uma grande área de dados, apareceram as strings
$Info: This file is packed with the UPX executable packereUPX 3.94
- Era um binário ELF compactado com UPX; se o cabeçalho do UPX ou o packed binary não tiver sido modificado, ele pode ser descompactado com
upx -d- De fato, após executar
upx -d mips, o tamanho do arquivo aumentou de34932para93732, permitindo ver mais strings
- De fato, após executar
- Entre as strings do binário descompactado havia
M-SEARCH * HTTP/1.1,ST: urn:dial-multiscreen-org:service:dial:1e um payload XML de atualização para dispositivos Huawei- Isso parece ser um comando UPnP para encontrar na rede dispositivos que suportam o protocolo DIAL
- O payload XML parecia configurado para escanear dispositivos Huawei vulneráveis a injeção de comandos
- Esse comportamento foi identificado como parte da botnet Mirai
- O arquivo referenciado
yeye.mipsnão estava mais disponível quando se tentou buscá-lo- Ao executar
nmapno servidor, só foram encontrados22/tcp sshe646/tcp filtered ldpcomo portas abertas
- Ao executar
Injeção de comandos contra Zyxel
- Outra requisição continha comandos de shell na URL GET, e fica mais fácil de ler ao remover a substituição de shell
${IFS}- O comando reorganizado seguia o fluxo de ir para
/tmp, apagar arquivos*mips*, baixarhuhu.mips, dar permissão de execução e executá-lo com o argumentozyxel.selfrep
- O comando reorganizado seguia o fluxo de ir para
- Esse ataque parecia mirar um exploit de
zhttpdem equipamentos Zyxel - Desta vez, o binário não estava compactado, então foi possível ver as strings diretamente no Ghidra
- Entre elas apareciam
M-SEARCH * HTTP/1.1, o cabeçalhoSTrelacionado a DIAL,skyljne.arm,skyljne.arm5,skyljne.arm6,skyljne.arm7,skyljne.mips,skyljne.mpsl,skyljne.x86_64,skyljne.sh4 - Também havia um payload XML voltado a dispositivos Huawei para baixar
huhu.mipse executá-lo comoselfrep.huawei
- Entre elas apareciam
- Outra string trazia um comando para enviar POST para
/goform/set_LimitClient_cfg- Junto do cabeçalho
Cookie: user=admin, ele tentava inserir comandos no parâmetromacpara baixarhuhu.mpsle executá-lo - Segundo um artigo da Akamai, essa vulnerabilidade afeta roteadores e pode ser explorada sem autenticação prévia, já que não faz verificações especiais de autenticação e autorização
- Junto do cabeçalho
- A conclusão mais provável é que esse binário seja um agente da botnet Mirai
- Algumas fontes também mencionam possível relação com o Linux Medusa
Resposta do ponto de vista operacional
- Os logs observados são apenas uma parte do total, e há muitos outros exploits sendo tentados todos os dias
- É importante manter os equipamentos, especialmente os dispositivos IoT, sempre atualizados
- Sempre que possível, dispositivos IoT não devem ser expostos diretamente à internet pública
- Se a exposição for inevitável, o ideal é isolá-los em uma VLAN separada
1 comentários
Comentários do Hacker News
Curiosamente, alguns atacantes parecem monitorar os logs de Certificate Transparency para procurar certificados recém-emitidos
Se você deixa um servidor novo no ar por mais de uma semana em um IP novo, os logs de acesso mostram só algumas sondagens aleatórias, mas cerca de uma hora depois de obter um certificado da Let’s Encrypt, já houve várias vezes em que centenas de requisições como as do artigo começaram a chegar de uma vez
A conclusão é que novos serviços precisam ser protegidos o quanto antes, idealmente antes mesmo de serem expostos à internet
Ou então usar uma autoridade certificadora própria e, até a virada, usar certificado autoassinado com mTLS
Por exemplo, se algum software expõe telas iniciais de instalação como criação de conta de administrador e conexão com banco de dados, isso fica mais arriscado do que definir tudo desde o começo com variáveis de ambiente, arquivos de configuração ou uma ferramenta dedicada de gestão de segredos
Por exemplo, pesquisar domínios dentro de um período específico
O Merkle Town[0] da Cloudflare é útil para ver uma visão geral, mas ainda não encontrei uma forma fácil de consultar logs de CT, e o ct-woodpecker[1] também parece promissor
[0] https://ct.cloudflare.com/
[1] https://github.com/letsencrypt/ct-woodpecker
Hoje em dia VPN está boa demais e me dá tranquilidade, e coisas como hospedagem de fotos ou backups são justamente o tipo de coisa que eu não quero expor publicamente
Quando comecei a administrar sites auto-hospedados, eu também olhava os logs de acesso e por um tempo até usei um sistema de detecção de intrusão que coletava dados e mostrava tentativas de ataque em andamento
No fim, parei tanto de revisar logs de forma proativa quanto de pagar pelo custo de um sistema de detecção de intrusão, porque era perda de tempo e distraía
É fácil encontrar material que resume bem vulnerabilidades e ataques comuns, então basta usar isso como padrão de administração do servidor. Há muitos guias de boas práticas para cada tecnologia comum de servidor web, e só de aplicar 100% disso você já fica muito à frente de quase todos os atacantes
Depois disso, a melhor forma de usar tempo e recursos é priorizar um ciclo de patching o mais rápido possível. A maioria dos ataques mira vulnerabilidades publicamente conhecidas
Os logs são especialmente úteis para diagnosticar depois que algo acontece. Um software de análise de logs já me ajudou 2 ou 3 vezes a armazenar e pesquisar dados para encontrar a causa raiz de ataques bem-sucedidos, e em todos os casos a causa foi uma vulnerabilidade conhecida corrigida tarde demais
A solução é defesa em profundidade, e ao hospedar serviços pessoais isso em geral é bem fácil de aplicar
Coloque um firewall na frente ou esconda atrás de VPN/Tailscale, e se esconder em uma subpasta como
/mawer/phpmyadmin/em vez de/phpmyadmin/, alvo comum de ataques automatizados, 99,9% deles nem vão encontrar. Isso é chamado de security by obscurity e não deve ser sua única proteção, mas como camada extra é muito útilColoque os apps em sandbox e isole o servidor para dificultar movimentação lateral mesmo em caso de invasão, e mantenha logs para verificar se houve ataque e se ele foi bem-sucedido
O ponto principal é que, seja patch, seja firewall, não dá para depender de uma única medida de defesa. Em algum momento alguma delas vai falhar
Hoje tento atualizar pacotes por trimestre[0], mas seria ótimo ter uma ferramenta que avisasse sobre vulnerabilidades conhecidas para permitir reação imediata
[0] Aqui, “tento” quer dizer que às vezes não dá para atualizar imediatamente por causa de incompatibilidades com a versão mais recente ou por ser um release X.0.0 em que ainda não confio
Como o autor disse que não é especialista em segurança, só para corrigir um detalhe: o exemplo do começo é varredura de credenciais/configuração, não travessia de diretórios
Entendo travessia de diretórios como o termo usado para técnicas em que o atacante “escapa” da raiz web ou engana o servidor para entregar arquivos fora do diretório normal
"/../../passwd/etc"Pelo menos na minha experiência, um ponto importante é que boa parte desses ataques vem de atores estatais hostis
Pode ser controverso, mas bloquear faixas inteiras de IP de países problemáticos com os quais você não faz negócios pode ser útil. Já consegui reduzir a zero as tentativas de sondagem contra um serviço novo fazendo isso
A maioria das sondagens que chegam ao meu servidor vem dos EUA, e bem atrás em segundo lugar está a Holanda. Imagino que a maior parte venha da AWS e de outros datacenters
Trabalho na área de segurança de aplicações/produtos e administrei WAFs de empresas avaliadas em dezenas de bilhões de dólares por vários anos
Basta mover o DNS para a Cloudflare e aplicar algumas regras de WAF no site. Por exemplo, acionar um desafio gerenciado se a pontuação de bot for menor que 2, ou tratar requisições quando a pontuação de ataque atingir determinado valor. Provavelmente quase não custa nada e resolverá muitos problemas
Ainda assim, é preciso testar tudo antes de levar para produção. Também é uma boa ter um domínio de teste. WAF não é solução mágica; está mais para paliativo, e se o próprio app não estiver reforçado para aguentar ataques, nem o WAF mais avançado nem uma proteção contra bots vão salvá-lo
O Free Managed Ruleset parece ser implantado por padrão, e a Cloudflare mantém o changelog aqui: https://developers.cloudflare.com/waf/change-log
Funciona muito bem. Como só minha família acessa, foi fácil configurar, e cada pessoa recebe um certificado próprio que pode ser revogado se necessário
Como você parece conhecer bem essa área, queria perguntar se já administrou alguma solução que use infraestrutura Azure junto com Cloudflare e, se sim, se há algo que as pessoas costumam deixar passar além do básico tipo OWASP
Pode ser necessário se alguma empresa, por qualquer motivo, tiver mesmo que operar algo desatualizado, mas no fim continua sendo só um paliativo
Estou fazendo self-hosting há cerca de um ano de um servidor HTTP/S de 400 linhas que eu mesmo projetei, e é impressionante o volume de tráfego de ataque que entra pelas 3 portas abertas (22, 80, 443)
Ainda não tirei tempo para analisar o que exatamente os atacantes tentam fazer, mas este texto preenche muitas lacunas
Seria bom analisar da mesma forma as coisas estranhas que aparecem em
/var/log/auth.logTodo o código é open source e não há nem estado no lado do servidor, então é estranho que um invasor se dê ao trabalho de me mirar. Na melhor das hipóteses, o que ele conseguiria seria acesso root a uma VPS de 5 dólares por mês e talvez uma adulteração temporária de um domínio que ninguém visita
Se você deixar abertas as 3 portas mais conhecidas, vai receber conexões; eles não sabem nem se importam com o que você está executando
Também dá para hospedar malware ou rodar mineradores de criptomoeda
Meu ISP na prática quase nunca muda meu IP, e quando muda eu posso entrar no painel web do host e atualizar a regra
Eu sempre rodo fail2ban em cada servidor e ainda adiciono jails customizadas para pegar ataques compatíveis com o tipo de funcionalidade exposta pelo site
Dito isso, faz tempo que não verifico se os outros padrões do fail2ban ainda são suficientes para bloquear ataques comuns. Vou deixar este link salvo nos favoritos para ver depois
Eu também verifico os logs de acesso dos meus serviços hospedados por conta própria, e há um detalhe claramente ausente nessa análise
Uma parte considerável das requisições maliciosas vem de gente comum executando scanners de segurança facilmente encontrados no GitHub e em lugares parecidos. Em geral são ataques nada sofisticados, e essas instâncias de projetos ficam martelando servidores sem nem olhar a resposta nem se importar se foram limitadas
Alguns ataques não miram diretamente o IP, mas monitoram domínios e subdomínios, repetindo periodicamente o mesmo scan a partir da mesma faixa de IPs
Em um emprego antigo, scans repetidos vinham o tempo todo de um único IP fixo na Turquia, e a equipe passou a chamá-lo de “o turco”; quando aparecia algum padrão estranho de requisições, o primeiro passo na resposta a incidentes era verificar se era ele mexendo no nosso serviço
Se você estiver vendo esse tipo de log na AWS, por favor coloque AWS WAF na frente da VPC
Não é caro e ajuda bastante a reduzir dores de cabeça nessa situação. Mesmo que não bloqueie tudo antes de chegar ao serviço, ainda pode ajudar muito
Algumas regras agressivas demais quebraram discretamente partes do app
Havia uma regra de corpo da requisição que bloqueava quando o corpo continha
"localhost", e outra que bloqueava requisições sem cabeçalho User-Agent. Como antes não exigíamos User-Agent nas requisições de API, isso acabou quebrando toda a API para alguns usuários até descobrirmos a causaÉ preciso saber o que está sendo bloqueado e validar antes; caso contrário, em alguns cenários, você perde clientes
Ele cria uma falsa sensação de segurança mesmo sendo fácil de contornar, ainda traz custo de desempenho e também tem boa chance de bloquear tráfego legítimo: https://www.macchaffee.com/blog/2023/wafs/
Por exemplo, pesquisadores da nossa universidade estudam dados do Twitter e, só por seguirem links a partir de uma pequena amostra aleatória de tweets, o IP da universidade acaba bloqueado pela maioria dos WAFs
Às vezes penso que seria divertido criar um servidor Express que responda direito a um desses ataques só para fazer alguém perder tempo
Mas aí eu também estaria desperdiçando o meu tempo
[1] https://infosec.exchange/@gnyman/109318464878274206
[2] https://nyman.re/super-simple-ssh-tarpit/