1 pontos por GN⁺ 2025-12-19 | 1 comentários | Compartilhar no WhatsApp
  • Em um servidor Hetzner operado por um usuário, foi detectado um uso anormal de CPU e, após investigação, descobriu-se que um programa de mineração da criptomoeda Monero (xmrig) estava em execução
  • A causa foi o comprometimento do contêiner da ferramenta de analytics Umami, que incluía a vulnerabilidade de execução remota de código no Next.js (CVE-2025-66478)
  • Felizmente, como esse contêiner era executado com um usuário não root (non-root) e não tinha mount no host nem elevação de privilégios, a invasão ficou limitada ao interior do contêiner
  • O invasor explorou a desserialização insegura dos componentes de servidor do Next.js para executar um payload malicioso e instalar o minerador
  • Este caso mostra a importância do gerenciamento de dependências e das configurações de segurança de contêineres, e o autor reforçou as medidas de segurança com ativação de firewall, endurecimento do SSH e atualizações regulares

O hack e a resposta inicial

  • Recebeu da Hetzner um e-mail de alerta informando que o servidor havia escaneado a rede externa
    • Incluía o aviso de que o servidor poderia ser bloqueado caso não houvesse ação em até 4 horas
  • Após acessar por SSH e verificar, encontrou-se um processo usando 819% de CPU no caminho /tmp/.XIN-unix/javae, além de vários processos xmrig
  • Foi confirmado que a mineração de criptomoeda havia ocorrido por cerca de 10 dias

Investigação da via de invasão

  • Todos os processos maliciosos estavam em execução com o usuário UID 1001, o que correspondia ao contêiner do Umami
  • Foi encontrado um executável do minerador no diretório /app/node_modules/next/dist/server/lib/xmrig-6.24.0/
  • O comando de execução incluía o endereço do pool de mineração auto.c3pool.org:443 e a chave do usuário

Vulnerabilidade no Next.js e forma do ataque

  • A causa foi a vulnerabilidade de desserialização dos React Server Components do Next.js (CVE-2025-66478)
    • Quando o invasor envia uma requisição HTTP manipulada, código arbitrário pode ser executado no servidor
    • Como resultado, torna-se possível instalar e executar um minerador de criptomoeda
  • O autor achava que “não usava Next.js diretamente”, mas só depois percebeu que o Umami é baseado em Next.js

Verificação do isolamento do contêiner

  • Foi confirmado que /tmp/.XIN-unix/javae não existia no sistema de arquivos do host
    • Era apenas o efeito de os processos do contêiner aparecerem na saída do docker ps, enquanto o isolamento real era mantido
  • Resultado do docker inspect
    • Usuário: nextjs
    • Privileged: false
    • Mounts: nenhum
  • Portanto, o malware não conseguiu acessar o host, registrar tarefas no cron, criar serviços do sistema nem instalar rootkits

Recuperação e reforço de segurança

  • Após parar e excluir o contêiner infectado do Umami, o uso de CPU voltou ao normal
  • O firewall UFW foi ativado, permitindo apenas SSH, HTTP e HTTPS
  • Depois de reportar os resultados da investigação à Hetzner, o ticket foi encerrado em 1 hora

Lições e pontos de melhoria

  • Dizer “eu não uso X” não inclui necessariamente as dependências
    • É preciso verificar de qual stack tecnológica são compostas as ferramentas utilizadas
  • Ficou comprovado o efeito do isolamento de contêineres
    • Uso de usuário não root, modo sem privilégios e ausência de volumes desnecessários impediram a ampliação dos danos
  • Há necessidade de defesa em profundidade (Defense in Depth)
    • Firewall, fail2ban, monitoramento e atualizações regulares são essenciais
  • Também foi destacada a importância de escrever o próprio Dockerfile e de minimizar os privilégios do contêiner

Medidas após o incidente

  • O Umami foi reimplantado na versão mais recente e todos os contêineres de terceiros foram auditados
    • Foram verificados usuário de execução, mounts, momento de atualização e necessidade de cada um
  • Houve migração para autenticação por chave SSH, desativação do login por senha e configuração do fail2ban
  • Foi feito reforço do monitoramento com Grafana e Node Exporter, além da aplicação imediata de atualizações de segurança

Conclusão

  • A vulnerabilidade no Next.js do Umami permitiu o abuso do servidor para minerar Monero por 10 dias, mas
    o isolamento do contêiner e a execução sem root limitaram os danos
  • Com essa experiência, o autor assimilou a importância de entender as dependências, configurar a segurança e gerenciar atualizações
  • O incidente foi resolvido em cerca de 2 horas e ficou como um caso real que comprovou a eficácia da segurança de contêineres

1 comentários

 
GN⁺ 2025-12-19
Comentários do Hacker News
  • Antigamente eu recomendava ativar o UFW, mas hoje recomendo o firewalld
    O UFW fica difícil de administrar com o tempo, enquanto o firewalld é bem mais estável por usar configuração baseada em XML
    Com o comando firewall-cmd, dá para configurar SSH, HTTPS, porta 80 etc., e é melhor usar o backend nftables
    No caso do Docker, ele frequentemente contorna as regras do firewall e abre portas por conta própria, então é mais seguro definir StrictForwardPorts=yes em /etc/firewalld/firewalld.conf

    • Em vez de abrir portas como 8080:8080, é melhor vincular ao IP privado, como 192.168.0.1:8080:8080
      Eu rodo Docker numa VM 10.0.10.11 e achei prático deixar o acesso disponível só via WireGuard, com o Caddy fazendo reverse proxy
    • Recomendo instalar Podman em vez de Docker. Problemas de contornar firewall são comuns no Docker
    • Independentemente de qual frontend de netfilter você use, sem restrição de conexões de saída não adianta muito
      Malware vai tentar se conectar a pools de mineração externas ou servidores de C2, então é preciso bloquear o acesso à rede para binários não autorizados
      Também ajuda remover permissão de execução de /tmp, /var/tmp e /dev/shm
    • A Hetzner oferece serviço de firewall externo gratuito, então dá para usar isso como primeira linha de defesa
    • Pessoalmente, acho que só o nftables.conf já é simples e claro o suficiente
      O iptables já está obsoleto, então não é obrigatório ter uma camada extra como o firewalld
  • Isso parece ser um problema relacionado ao “React2Shell CVE-2025-55182
    É estranho que uma vulnerabilidade que afetou sistemas por mais de um ano quase não tenha recebido atenção
    Se você implantou um webapp com Next.js nos últimos 12 meses, há uma boa chance de ele já fazer parte de uma botnet
    É frustrante ver a indústria ficando só em conselhos do tipo “use Docker” e “ative o firewall”
    Ultimamente tenho ficado tão cético com o ecossistema de frontend que estou pensando em migrar minha carreira para C++

    • O ciclo de troca de tecnologias no frontend hoje é bem mais brando do que antes
      Agora a combinação de Next.js, React, Tailwind e Postgres está praticamente consolidada como padrão há 5 anos
      Comparado ao período de proliferação de frameworks no fim dos anos 2000 e início dos 2010, está bem mais estável
      Se você não gosta de modas e mudanças, o desenvolvimento com IA muda muito mais rápido hoje
    • Dá para construir webapps tranquilamente sem usar frameworks JS modernos
      No backend, use uma stack sólida como .NET, Java ou Go, e no frontend escolha o que preferir
      Isso reduz CVEs e também o cansaço com tecnologia
    • Minha instância do Pangolin também foi comprometida por essa vulnerabilidade
      Discussão relacionada no GitHub
    • Eu também implantei cerca de 100 frontends em Next.js, mas por sorte não fui afetado porque não usei Server Components
  • Se você limitar o uso de CPU de um contêiner Docker com --cpus="0.5", um serviço com defeito ou minerador não afeta o sistema inteiro

    • Rodar o contêiner em modo read-only também pode reduzir ainda mais a superfície de ataque
    • Só que, se o limite de CPU for baixo demais, a invasão pode passar despercebida por mais tempo e causar atraso na detecção
    • Você precisa conhecer bem o perfil de desempenho do aplicativo. Se depois houver tráfego em burst, pode acabar sofrendo throttling sem querer
    • Também é bom configurar os limites soft/hard de memória junto
  • Operar um servidor sem firewall é uma escolha bem ousada
    Se você usar também o firewall externo da Hetzner, ganha mais uma camada de defesa para quando cometer algum erro
    Eu permito SSH só a partir do IP da minha casa e, quando preciso de acesso externo, abro temporariamente pelo site da Hetzner

    • Na maioria dos casos, firewall não ajuda tanto assim
      O que realmente importa é não rodar software com vulnerabilidade de RCE
      O Docker parecer um salvador, na prática, foi mais sorte do que qualquer outra coisa
    • Se for um serviço web público, o firewall não ajuda muito
      Em vez disso, dá para usar um bastion host e controlar entrada e saída com um proxy HTTP, mas a configuração é complexa
    • Em 30 anos administrando Linux, a única vez que fui hackeado foi quando deixei portas bem conhecidas abertas
      Usar portas não padrão teve um efeito surpreendentemente útil
    • Deixar autenticação por senha ativada é arriscado. Pessoalmente, não acho que fail2ban seja indispensável
    • Eu mudo a porta do SSH aleatoriamente para tentar evitar scanners de porta
      Não sei se funciona de verdade, mas parece uma espécie de guarda-chuva psicológico
  • Fiquei curioso se rodar um contêiner Docker como root permite atacar o host também

    • O Docker não é uma fronteira de segurança. Ele só fornece isolamento em nível de processo
      Se você quer rodar código não confiável, precisa usar VM (KVM/QEMU) ou tecnologias como gVisor(https://gvisor.dev/) e Firecracker(https://firecracker-microvm.github.io/)
      É melhor entender o Docker não como sandbox, mas como um ambiente de execução isolado
    • Mesmo dentro do contêiner, o invasor já consegue usar CPU para minerar Monero
      A configuração padrão do Docker não limita RAM, CPU nem uso de disco, então ele também é vulnerável a ataques de DoS
      Além disso, muitos guias recomendam opções perigosas como --privileged ou CAP_SYS_PTRACE
    • No modo privileged, dá para acessar o sistema de arquivos root do host via socket do Docker
      Também é possível subir um novo contêiner e escalar para privilégios de root
    • É preciso ativar user namespace para haver uma fronteira de segurança real
      Como isso ainda não é o padrão no Docker, se você não configurar, o risco de escape é grande
      No passado, a maioria dos escapes de contêiner poderia ter sido evitada com user namespace
    • Escapes de contêiner existem, mas a maioria dos casos é só ataque automatizado de mineração
      Se o servidor não lida com dados sensíveis, limpar apenas os contêineres pode ser suficiente
  • Para reduzir a superfície de ataque, serviços que não precisam ser públicos não devem ser expostos externamente
    Por exemplo, ferramentas de análise podem ficar acessíveis só via WireGuard ou proxy SOCKS por SSH

  • Eu também sofri uma infecção por minerador de Monero num servidor da Hetzner
    Felizmente aconteceu só dentro de um contêiner LXC do Incus, e como a prioridade de CPU era baixa eu nem percebi
    Uma chave SSH foi adicionada à conta root e um agente de administração remota foi instalado
    No fim descartei o contêiner, mas tirei algumas lições disso

    • É preciso assumir que o sistema será comprometido algum dia e configurar isolamento e limites de recursos
    • Manter snapshots do ZFS e backups regulares facilita a recuperação
    • O ideal é descartar sistemas comprometidos, mas dependendo da situação também dá para fazer rollback e reforçar depois
    • O minerador chamou atenção porque estava mal configurado; se a invasão fosse silenciosa, talvez eu nem tivesse percebido
    • Isso aconteceu num contêiner onde eu tinha instalado o Umami
  • O texto incluía alucinações de IA que não tinham sido revisadas por uma pessoa
    Ele repetia que era uma vulnerabilidade relacionada ao Puppeteer, mas isso não era verdade

    • No primeiro parágrafo do texto original, estava explicitamente indicado que era uma transcrição de uma sessão do Claude
  • Recentemente estão instalando mineradores de Monero por toda parte explorando uma vulnerabilidade do React 19
    Eu também passei pelo mesmo problema

    • Esse tipo de malware de mineração é bem visível e causa pouco dano, então acaba sendo até útil
      Funciona como uma espécie de bug bounty automático, no sentido de revelar a vulnerabilidade
      Se você tem bom monitoramento de rede ou processos, é fácil detectar
    • Um servidor Umami na Oracle Cloud foi infectado e eu reinicializei o servidor
      Acabou sendo uma boa oportunidade para melhorar o sistema de backup
  • Quando vejo casos assim, penso que foi melhor eu não continuar administrando VPS por conta própria
    Já tentei antes, mas me considero só um administrador mediano e achei difícil manter a segurança
    Então hoje prefiro pagar e deixar isso com especialistas, o que me dá muito mais tranquilidade