1 pontos por GN⁺ 2024-01-29 | 1 comentários | Compartilhar no WhatsApp
  • 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/ e test/; algumas requisições usavam User-Agent com erro de digitação, como Mozlila/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
    • .env normalmente é tratado como um arquivo que guarda secrets da aplicação
  • 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
  • Diretórios comuns que podem ter sido deixados por engano também eram requisitados repetidamente
    • Exemplos: /old/, /new/, /test/, /backup/, /temp/
  • Alguns User-Agents continham Mozlila/5.0, aparentemente um erro de digitação de Mozilla/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
  • 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
  • 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 Bash
    • echo Content-Type: text/html; echo ; imprime o Content-Type da 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 country para baixar e executar o script de shell remoto tenda.sh
    • Após decodificar a URL, o comando seguia um fluxo de ir para /tmp, apagar arquivos, baixar o script com wget, dar permissão de execução e executá-lo
  • 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
  • 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 packer e UPX 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 de 34932 para 93732, permitindo ver mais strings
  • Entre as strings do binário descompactado havia M-SEARCH * HTTP/1.1, ST: urn:dial-multiscreen-org:service:dial:1 e 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.mips não estava mais disponível quando se tentou buscá-lo
    • Ao executar nmap no servidor, só foram encontrados 22/tcp ssh e 646/tcp filtered ldp como portas abertas

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*, baixar huhu.mips, dar permissão de execução e executá-lo com o argumento zyxel.selfrep
  • Esse ataque parecia mirar um exploit de zhttpd em 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çalho ST relacionado 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.mips e executá-lo como selfrep.huawei
  • 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âmetro mac para baixar huhu.mpsl e 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
  • 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

 
GN⁺ 2024-01-29
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

    • Dá a sensação de que é preciso colocar pelo menos algo como autenticação básica na frente desde o primeiro instante de exposição pública
      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
    • Dei uma olhada recente nos logs de Certificate Transparency e fiquei curioso se existe alguma ferramenta ou método prático para consultar logs de CT
      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
    • Usar mais certificados curinga também ajuda. Fica mais difícil descobrir subdomínios específicos a atacar só pelos logs de CT
    • Muitas vezes isso não é um atacante, e sim serviços como o urlscan.io que monitoram logs de CT e rastreiam a web para procurar malware
    • Eu mesmo hospedo vários serviços, mas desisti completamente de deixá-los expostos diretamente na internet
      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

    • Se em todos os casos se tratava de vulnerabilidades conhecidas corrigidas tarde demais, então uma abordagem que depende só de patches está fadada a falhar em algum momento. Pode ser um 0-day ou o atacante pode ser mais rápido
      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 útil
      Coloque 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
    • Fiquei curioso sobre a parte de priorizar o ciclo de patching mais rápido possível. Você usa alguma ferramenta para decidir quando aplicar patches, ou segue algum intervalo de tempo?
      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

    • Se for uma forma de incluir arquivos que originalmente não deveriam estar hospedados, tecnicamente pode ser os dois. Por exemplo, "/../../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

    • O problema principal não é esse, e sim que muita gente não quer acabar bloqueando também usuários legítimos daquela região
    • Seria ótimo se atores estatais não pudessem simplesmente comprar servidores em outros países e lançar os ataques a partir dali
    • Há mais de 15 anos, olhando logs de servidores de pequenos negócios locais que hospedávamos, concluímos que dava para bloquear todos os endereços IP da APNIC
    • No fim das contas, bloqueio geográfico não acaba só barrando tráfego legítimo e fazendo atacantes determinados usarem proxies?
    • Nesse caso você teria de bloquear os Estados Unidos e a Holanda
      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

    • Para quem não conhece: https://blog.cloudflare.com/waf-for-everyone/
      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
    • Do ponto de vista de quem faz self-hosting, uso o WAF da CloudFlare com regras de TLS mútuo para deixar passar apenas chamadores legítimos que eu conheço
      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
    • Hoje em dia normalmente administro apenas aplicações internas, então a superfície de ataque é bem menor do que em serviços públicos
      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
    • Funciona bem para um site WordPress padrão, e dá para adicionar os plugins GuardGiant e Sucuri como camada extra
    • Colocar um WAF na frente do app e achar que o trabalho acabou não é muito diferente de passar batom em porco
      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.log
    Todo 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

    • Isso tudo são bots automatizados. Ninguém está realmente prestando atenção em você
      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
    • Se conseguirem acesso à sua VPN, ela serve muito bem como ponto de partida para atacar outras máquinas e adicionar mais uma camada para esconder rastros
      Também dá para hospedar malware ou rodar mineradores de criptomoeda
    • Vale considerar permitir a porta 22 só para o seu próprio IP e bloquear o resto
      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

    • Se o sistema estiver expondo uma vulnerabilidade tão facilmente explorável, fail2ban não vai salvá-lo
  • 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

    • Boa sugestão, mas é preciso tomar cuidado com o conjunto de regras padrão. Nós ativamos o AWS WAF por exigência de conformidade SOC 2
      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
    • Os ataques descritos no texto provavelmente não seriam problema para nenhuma aplicação web moderna. Por isso não entendo por que seria preciso adicionar um WAF
    • Usar as regras padrão do AWS WAF não é tão simples assim. Na nossa aplicação, muitas requisições e IPs legítimos foram bloqueados
      É preciso saber o que está sendo bloqueado e validar antes; caso contrário, em alguns cenários, você perde clientes
    • Na prática, WAF muitas vezes atrapalha mais do que ajuda
      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/
    • WAF tende a bloquear de forma ampla, às vezes por razões pouco claras
      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