VPS hackeado: isole, preserve e recrie o servidor
VPS comprometido? Isole-o no firewall do provedor, crie um snapshot como evidência, troque todas as chaves e recrie o ambiente a partir de uma imagem limpa.
Não limpe um VPS comprometido
Se o seu VPS foi comprometido, a decisão mais importante vem antes de executar qualquer comando. Não tente limpar a máquina. Isole-a no provedor, crie um snapshot do disco como evidência, altere todas as credenciais que ela armazenava e depois recrie o ambiente em um servidor novo, usando fontes confiáveis.
Não é possível provar que um rootkit foi removido, porque as ferramentas que permitiriam provar isso são controladas pelo invasor.
Esse é o argumento completo. Veja como isso funciona. Um invasor que obteve acesso root pode substituir ps para que um ID de processo nunca apareça na saída. Uma linha em /etc/ld.so.preload carrega código do invasor em todos os programas dinamicamente vinculados no sistema. Assim, ls, ss e find fornecem resultados falsos da mesma forma consistente. Um módulo de kernel carregável pode ocultar arquivos abaixo da camada de chamadas do sistema. Dessa forma, até mesmo um binário baixado novamente vê um disco limpo. Você exclui o minerador, o gráfico de CPU cai e o servidor fica silencioso. O silêncio também é compatível com um backdoor funcional.
Recriar o ambiente custa menos do que parece. Um VPS típico consiste em alguns pacotes, um diretório de configuração e um conjunto de dados. Portanto, a recriação é um trabalho finito, com um fim definido. Procurar todas as alterações feitas pelo invasor não tem um fim previsível e nunca chega a uma prova.
Confirme que houve realmente uma intrusão
Muitos servidores reportados como invadidos não foram. Milhares de tentativas de login SSH falhadas por dia são ruído normal da Internet, porque cada endereço IPv4 público é analisado continuamente. Uma saída de lastb cheia de tentativas root e admin significa que os scanners encontraram a sua porta. Isso não significa que alguém conseguiu entrar.
Estes sinais indicam um problema real:
- Um login bem-sucedido que não consegue justificar, como
Accepted password for root from 203.0.113.7. - Uma chave em
authorized_keysque não adicionou. - Uma notificação de abuso do seu fornecedor de alojamento sobre tráfego a sair do seu servidor.
- Um processo a consumir 100% da CPU com um nome copiado de uma thread do kernel. Os miners introduzidos através de sockets Redis e Docker expostos são frequentemente reportados com nomes como
kdevtmpfsiekinsing. - Ligações de saída para endereços que nenhum dos seus serviços utiliza.
A dissimulação como thread do kernel tem um teste rápido. As threads reais do kernel aparecem entre parênteses retos e não têm um executável associado, por isso sudo ls -l /proc/<pid>/exe falha com elas com No such file or directory. Se um processo apresentado como [kworker/0:2] tiver um link exe que aponta para algo dentro de /tmp, é um programa normal de utilizador a usar um nome de kernel.
Execute estas verificações sabendo que o servidor pode estar a fornecer informações falsas. Elas são suficientes para concluir que existe um problema. Não são suficientes para concluir que não existe nenhum.
Interrompa a rede no provedor, não dentro do servidor
O isolamento vem primeiro, porque todas as etapas seguintes são inúteis enquanto outra pessoa ainda tiver um shell ativo. Ler logs, substituir chaves e restaurar dados não serve de nada com um atacante ativo a monitorizar o sistema.
Faça isso no painel de controlo do provedor, na firewall de rede que funciona fora do sistema operativo. Bloqueie o tráfego de entrada e de saída, e mantenha a consola web como forma de acesso. As regras aplicadas nesse nível continuam válidas independentemente do que aconteça no disco.
Há dois motivos para não fazer isso a partir do servidor. Uma firewall configurada dentro de um kernel comprometido é aplicada por esse kernel, e root pode limpar as regras do nftables com a mesma facilidade com que você as configura. Além disso, sudo ip link set enp1s0 down via SSH encerra primeiro a sua própria sessão e bloqueia o acesso a uma máquina que ainda estava a examinar.
Bloqueie o tráfego de saída e o de entrada. Um reverse shell estabelece uma ligação de saída do seu servidor para o atacante, portanto um bloqueio apenas de entrada deixa uma ligação já estabelecida a funcionar normalmente. Se o provedor oferecer apenas regras de entrada, as opções restantes são desligar a interface de rede ou desligar a instância.
Ainda não reinicie. Verifique primeiro se /var/log/journal existe. Se esse diretório não existir, o journald está a escrever em /run/log/journal, que fica na memória, e um reboot apagará o registo da intrusão. Os processos em execução também desaparecem no reboot, e as respetivas linhas de comando são frequentemente a evidência mais clara que poderá obter.
Crie um snapshot do disco antes de alterar qualquer coisa
Um snapshot e um backup têm funções diferentes neste caso. O snapshot que criar agora é uma cópia do disco comprometido: é a sua evidência e é a única forma de voltar atrás depois de substituir algo por acidente. Os seus backups antigos são o caminho de recuperação. Se o painel do seu fornecedor usar os dois termos de forma imprecisa, leia primeiro como os snapshots de VPS diferem dos backups reais, porque as regras de retenção e o comportamento da restauração não são iguais.
Crie o snapshot no painel do fornecedor antes de iniciar sessão novamente. Um snapshot em execução é consistente com uma falha: captura o disco tal como estava naquele instante, como se a alimentação tivesse sido desligada. Isso é adequado para preservar evidências. Dê-lhe um nome que impeça qualquer pessoa de o restaurar por engano. Algo direto como COMPROMISED-do-not-restore-2026-08-12 tem o nível adequado de clareza. Mantenha-o até terminar a investigação e fechar qualquer ticket de abuso com o seu host.
Como aceder quando o SSH deixou de funcionar
Há dois caminhos, ambos no painel do provedor. O console web (VNC ou serial) liga-se à máquina como se tivesse ligado um teclado. Funciona quando o sshd está parado, quando a firewall está mal configurada e quando o atacante alterou a porta SSH. A autenticação usa uma palavra-passe local. Por isso, num servidor que só aceita chaves, pode ser necessário redefinir a palavra-passe de root antes de o console ser útil.
O modo de recuperação é a melhor opção. Arranca um sistema live pequeno com o seu disco ligado, mas sem estar em execução. Assim, os seus comandos são confiáveis: o kernel comprometido e os binários comprometidos não estão a ser executados. Monte o disco apenas para leitura.
lsblk -f
sudo mkdir -p /mnt/victim
sudo mount -o ro /dev/vda1 /mnt/victimSe lsblk mostrar volumes LVM (gestor de volumes lógicos) em vez de uma partição simples, ative-os primeiro com sudo vgchange -ay e, em seguida, monte o dispositivo que aparece em /dev/mapper/.
Não use chroot no disco montado para o explorar. Um chroot executa os binários do atacante com as suas permissões, eliminando precisamente a razão pela qual iniciou o modo de recuperação.
Recolha as evidências que ainda são fiáveis
Execute estes comandos a partir do modo de recuperação, com o disco montado apenas para leitura em /mnt/victim. Comece pelos logins, porque permitem datar a intrusão. Depois disso, tudo o resto é mais simples com uma janela temporal definida.
sudo grep -aE 'Accepted (password|publickey)' /mnt/victim/var/log/auth.log
sudo last -f /mnt/victim/var/log/wtmp
sudo lastb -f /mnt/victim/var/log/btmp
sudo journalctl -D /mnt/victim/var/log/journal -u ssh --since "2026-07-01"A ausência de /var/log/auth.log não é, por si só, suspeita. Algumas imagens atuais do Ubuntu são fornecidas sem rsyslog. Nesse caso, o sshd escreve apenas no journal, que é o que a linha journalctl -D consulta. O que merece atenção é uma interrupção em logs que eram contínuos ou um ficheiro de log truncado para zero bytes. A eliminação de logs é comum e, normalmente, é feita de forma pouco cuidadosa.
Em seguida, verifique as contas e as chaves.
sudo find /mnt/victim/root /mnt/victim/home -name 'authorized_keys*' -exec ls -l {} +
sudo awk -F: '$3 == 0 {print $1}' /mnt/victim/etc/passwd
sudo lsattr /mnt/victim/root/.ssh/authorized_keysA linha awk mostra todas as contas com ID de utilizador 0. Qualquer resultado diferente de root corresponde a uma segunda conta root. O padrão find inclui deliberadamente authorized_keys2, porque o OpenSSH lê ambos os nomes de ficheiro por predefinição e o segundo é fácil de ignorar. Se lsattr mostrar um i na lista de atributos, o ficheiro é imutável. Um atacante define esse atributo para que a tentativa de eliminar a chave falhe com Operation not permitted, enquanto um administrador cansado assume que a alteração foi aplicada.
A persistência costuma esconder-se num pequeno número de locais. Verifique todos.
sudo ls -lt /mnt/victim/etc/systemd/system
sudo ls -l /mnt/victim/etc/cron.d /mnt/victim/var/spool/cron/crontabs
sudo cat /mnt/victim/etc/ld.so.preload
sudo grep -rnE 'curl|wget|base64|/dev/tcp' /mnt/victim/etc/update-motd.d /mnt/victim/etc/rc.local /mnt/victim/root/.bashrc /mnt/victim/root/.profile/etc/ld.so.preload não existe num sistema Ubuntu ou Debian normal. Por isso, No such file or directory é o resultado esperado, e qualquer conteúdo merece atenção. Um ficheiro de login que encaminha a saída de base64 -d para uma shell é o mesmo tipo de indício. Uma configuração legítima não precisa de ocultar o próprio conteúdo.
Construa a linha temporal com base na hora de alteração, e não na hora de modificação.
sudo find /mnt/victim -xdev -newerct '2026-08-01' -type f -printf '%TF %TT %p\n' | sorttouch permite definir a hora de modificação para qualquer valor pretendido pelo atacante. Por isso, o mtime pode ser falsificado facilmente. A hora de alteração (ctime) é atualizada sempre que o inode sofre uma alteração, e touch não a consegue fazer recuar. Assim, -newerct produz uma lista mais fiável do que foi escrito recentemente. Ainda não é uma prova, porque root pode alterar o relógio do sistema ou escrever diretamente no dispositivo de blocos.
Vale a pena verificar a integridade dos pacotes com um comando, tendo presente uma ressalva. Num sistema em execução, sudo dpkg --verify mostra uma linha para cada ficheiro pertencente a um pacote cujo checksum já não corresponde, com um 5 na coluna do checksum. sudo debsums -ac faz o mesmo, incluindo ficheiros de configuração, quando o pacote debsums está instalado. Interprete o resultado apenas numa direção. Um /usr/sbin/sshd alterado é uma evidência real. Um relatório limpo não prova nada, porque a mesma conta root que substituiu o binário pode reescrever as listas de checksums em /var/lib/dpkg/info/. Scanners de rootkits, como rkhunter e chkrootkit, seguem a mesma regra: uma deteção fornece informação; uma execução sem deteções não confirma que o sistema esteja limpo.
Copie para fora da máquina tudo o que recolheu antes de fazer qualquer alteração destrutiva.
sudo tar --ignore-failed-read -C /mnt/victim -czf /root/evidence-2026-08-12.tgz \
var/log etc root/.ssh root/.bash_history home
sha256sum /root/evidence-2026-08-12.tgzRegiste esse hash num local fora do servidor. Se isto alguma vez se transformar numa participação à seguradora ou numa denúncia à polícia, conseguir demonstrar que o arquivo não foi alterado desde a recolha é o que distingue uma evidência de uma pasta com ficheiros. Apagar algo acidentalmente durante uma investigação é normal. O snapshot e este arquivo são o que torna esse erro recuperável. Reverter depois um rm incorreto é muito mais difícil do que se imagina, como explica recuperar ficheiros eliminados com rm -rf.
Identifique a via de entrada
Uma reinstalação que não fecha a via de entrada volta a deixar o servidor comprometido, muitas vezes em poucos dias, porque a análise que o encontrou da primeira vez nunca para. Quatro vias abrangem a maioria dos comprometimentos de servidores individuais.
Autenticação por palavra-passe no SSH. Uma linha Accepted password for root proveniente de um endereço que não reconhece é, por si só, a resposta. Verifique PasswordAuthentication em /etc/ssh/sshd_config e em todos os ficheiros dentro de /etc/ssh/sshd_config.d/. O sshd usa o primeiro valor que encontra para uma palavra-chave, e a linha Include aparece no topo do ficheiro principal no Ubuntu. Por isso, um ficheiro de configuração incluído pode substituir silenciosamente a definição que editou mais abaixo.
Um serviço publicado sem autenticação. Redis na porta 6379, a API do Docker na porta 2375 ou uma base de dados ligada a 0.0.0.0 em vez de 127.0.0.1. O Docker é a surpresa mais comum. Publicar uma porta de contentor insere regras DNAT (tradução de endereços de rede de destino) que são avaliadas antes das cadeias do ufw. Assim, ufw status pode indicar que uma porta está bloqueada enquanto o contentor por trás dela responde à Internet inteira. Entenda isto antes da reinstalação: porque as portas publicadas pelo Docker contornam o ufw explica a ordem das regras e a correção.
Uma aplicação web sem correções. Procure no log de acesso do servidor web, perto do timestamp suspeito mais antigo, um POST para um caminho de upload ou de administração. Depois, procure ficheiros na raiz web com uma hora de alteração correspondente. Um ficheiro PHP perdido num diretório de uploads é o resultado clássico.
Uma credencial exposta. Uma chave submetida para um repositório, um token colado num chat ou um ficheiro .env servido como ficheiro estático por um servidor web mal configurado. A automatização facilita este erro acidental, o que justifica manter os segredos fora dos agentes de IA e dos respetivos ficheiros de configuração.
Se, depois de tudo isto, não conseguir identificar a via de entrada, assuma que uma credencial foi exposta e trate todos os segredos que a máquina armazenava como públicos.
Rote todas as credenciais que a máquina poderia ter visto
Faça a rotação depois de cortar a rede, nunca antes. Fazer a rotação enquanto o atacante ainda tem uma ligação simplesmente entrega os novos segredos.
- Todas as chaves privadas SSH armazenadas no servidor, além de todas as contas noutros sistemas que confiassem na chave pública correspondente.
- Qualquer chave encaminhada para a máquina com
ssh -A. O encaminhamento do agente deixa um socket em/tmp, e o root nessa máquina pode utilizá-lo para se autenticar como você em qualquer local onde a sua chave seja aceite, enquanto a sua sessão permanecer aberta. - Tokens de API em ficheiros
.env, em linhasEnvironment=do systemd, na configuração de CI e nas credenciais do provedor. - Palavras-passe de bases de dados e as contas de aplicação que as utilizam.
- Chaves privadas TLS (transport layer security) que o servidor mantinha. Emita novamente o certificado e revogue o antigo.
- A palavra-passe da sua conta de alojamento, com a autenticação de dois fatores ativada. Esse painel pode reconstruir, criar snapshots e abrir uma consola em todos os servidores que possui, por isso é o perímetro real.
- Qualquer palavra-passe introduzida numa sessão de shell nesse host enquanto ele estava comprometido, porque o root pode gravar uma sessão de terminal à medida que ela acontece.
Se uma palavra-passe nessa máquina for utilizada noutro local, altere-a também nesse local. A reutilização é o que transforma uma VPS comprometida numa conta de email comprometida.
A lista de verificação da reconstrução
- Crie um servidor novo a partir de uma imagem nova da distribuição. Não use o snapshot do sistema comprometido nem uma restauração de todo o sistema de ficheiros raiz.
- Instale os pacotes a partir dos repositórios da distribuição. Nunca copie um binário do disco antigo.
- Restaure apenas os dados, a partir de uma cópia de segurança criada antes da primeira evidência na sua linha temporal. Inclua dumps de bases de dados, uploads e o estado da aplicação. Deixe
/etc,/usre os ficheiros de unidade antigos para trás. - Introduza manualmente os segredos rodados. Não copie o
.envantigo. - Inspecione o conteúdo web restaurado à procura de ficheiros adicionados durante a janela da intrusão antes de voltar a disponibilizá-lo.
- Reforce a segurança antes de o expor: SSH apenas com chaves, uma conta de trabalho que não seja root, uma firewall de entrada com política default-deny e nenhum serviço publicado para além do necessário. Siga os primeiros dez minutos num VPS novo, depois reforce o SSH corretamente e, em seguida, adicione fail2ban no Ubuntu 24.04 para reduzir o ruído dos logins. Dê a cada serviço a sua própria conta com privilégios mínimos para que o próximo ponto de entrada não permita acesso root.
- Desligue o servidor antigo e mantenha o seu snapshot até a investigação e qualquer ticket de abuso estarem encerrados.
- Corrija as cópias de segurança. Se o passo 3 foi baseado em suposições, a verdadeira lição é que o histórico de cópias de segurança era demasiado curto para recuar para antes da intrusão. Cópias de segurança versionadas, fora do servidor e com retenção longa permitem obter um ponto de restauração limpo da próxima vez: cópias de segurança restic num VPS oferece ambas as coisas.
Se não conseguir datar a intrusão, não pode escolher uma cópia de segurança segura. Nesse caso, restaure apenas os dados que consegue inspecionar visualmente: um dump SQL que consiga ler ou um diretório de imagens que consiga listar. Considere suspeito tudo o que for executável e volte a instalá-lo a partir dos repositórios.
O que significa o aviso de abuso do seu provedor
A maioria das pessoas descobre que o seu servidor foi comprometido através do provedor, e não pelo próprio sistema de monitorização. Os provedores veem o tráfego de saída: tentativas de força bruta por SSH contra outras redes, spam na porta 25 ou a participação num ataque de reflexão. O ticket normalmente inclui marcas temporais, portas e uma amostra dos fluxos, além de um prazo contado em horas.
Responda ao ticket, mesmo que a única informação disponível seja que o servidor está isolado e a ser reconstruído. Os provedores encaminham o tráfego para null-route ou suspendem o servidor quando um ticket fica sem resposta. Isso transforma o incidente numa indisponibilidade. Em seguida, peça as linhas brutas do log que sustentam o relatório. Essas marcas temporais foram registadas fora da sua máquina. Por isso, são a única parte da linha temporal que o atacante não poderia editar. Muitas vezes, permitem datar a intrusão com mais precisão do que qualquer informação no disco.
Um servidor de cliente comprometido é uma ocorrência normal para um provedor. A forma correta de lidar com o caso não é usada contra si. A questão mais ampla de saber se o alojamento VPS é seguro depende principalmente do que o cliente configura. Essa é precisamente a parte que agora terá de configurar novamente do zero.
Quando chamar um profissional
- O servidor continha dados pessoais pertencentes a outras pessoas. Ao abrigo do RGPD (Regulamento Geral sobre a Proteção de Dados), uma violação de dados pessoais deve ser comunicada à autoridade de controlo sem demora injustificada e, quando tal for viável, no prazo de 72 horas após tomar conhecimento dela. Determinar se esse prazo já começou é uma questão jurídica, não uma tarefa de administração de sistemas.
- Estavam abrangidos dados de cartões de pagamento. As redes de cartões exigem um investigador forense aprovado, e a sua própria investigação pode danificar o caso.
- Existe um pedido de extorsão ou os seus dados foram encriptados.
- A máquina podia aceder a outras máquinas: uma rede interna, um hypervisor ou um CI runner com credenciais de produção. Um host comprometido num grupo deve ser tratado como um incidente que abrange todo o grupo até prova em contrário.
- Vai precisar de provas que sejam aceites por uma seguradora ou pelas autoridades policiais. Pare depois de criar o snapshot, faça uma imagem completa do disco e registe quem o manuseou e quando.
Para um único VPS que execute os seus próprios serviços e não contenha dados de terceiros, o procedimento acima cobre todo o trabalho. Isole o VPS no fornecedor. Crie um snapshot para preservar as provas. Recolha o que ainda for fiável. Faça a rotação de tudo. Recompile o sistema de forma limpa.
FAQ
Posso limpar um VPS invadido em vez de o reconstruir?
Não com confiança, porque estaria a pedir ao sistema comprometido que produza um relatório sobre si próprio. Um ps substituído oculta um processo, uma linha em /etc/ld.so.preload injeta código em todas as ferramentas ligadas dinamicamente que executar e um módulo do kernel pode ocultar ficheiros de todos os programas em simultâneo. É possível encontrar elementos, pelo que uma deteção é significativa. Não é possível demonstrar a ausência de elementos, pelo que um resultado limpo não é conclusivo. A limpeza só é defensável quando o servidor não contém nada importante e aceita que possa ser comprometido novamente.
Devo desligar um servidor comprometido ou deixá-lo em execução?
Bloqueie primeiro a rede no provedor e, em seguida, deixe-o em execução tempo suficiente para criar um snapshot e analisar os processos em execução. Desligá-lo elimina a lista de processos e apaga o journal por completo quando /var/log/journal não existe, porque o journald passa então a escrever na memória, em /run. Desligue-o mesmo assim se estiver a atacar ativamente outras redes e não tiver forma de bloquear o tráfego de saída. Interromper os danos é mais importante do que preservar as evidências.
Como determino quando o atacante entrou?
Procure a linha mais antiga de Accepted password ou Accepted publickey que não consiga explicar, em /var/log/auth.log ou no journal. Confirme-a com uma listagem dos tempos de alteração, find / -xdev -newerct 'YYYY-MM-DD' -type f, porque o ctime é mais difícil de falsificar do que o mtime. Depois compare ambos com os timestamps do ticket de abuso do provedor, que foram registados fora da máquina e não podiam ser editados. Escolha um backup anterior à mais antiga dessas três datas. Se nada coincidir, assuma que o comprometimento é anterior ao seu histórico de backups e restaure apenas dados que consiga inspecionar.
Os meus backups podem ser restaurados em segurança depois de um comprometimento?
Normalmente, os dados podem, depois de inspecionados. Os ficheiros do sistema não. Um backup criado depois da intrusão contém o backdoor, pelo que restaurar todo o root filesystem também restaura o atacante. Verifique igualmente o próprio repositório de backups: se as credenciais dele estavam armazenadas no servidor comprometido, o histórico pode ter sido apagado ou alterado. Este é um dos motivos para usar destinos de backup append-only ou baseados em pull. Restaure os dados das aplicações e, em seguida, instale novamente o software a partir dos repositórios da distribuição.
Tenho de informar alguém de que o meu VPS foi comprometido?
Responda sempre ao aviso de abuso do seu host. Além disso, depende de quem era proprietário dos dados armazenados na máquina. Dados pessoais pertencentes a outras pessoas podem criar uma obrigação legal de comunicação, como a notificação à autoridade de controlo no prazo de 72-hour prevista no GDPR. Se as credenciais dos utilizadores estavam armazenadas no servidor, informe esses utilizadores para que possam alterar as palavras-passe noutros serviços. Se as chaves existentes na máquina autorizavam o acesso a sistemas de terceiros, como um code host ou uma conta cloud, informe esses provedores para que possam verificar se houve utilização indevida. Um servidor exclusivamente pessoal que não contenha dados de terceiros não implica qualquer obrigação além da resposta ao ticket de abuso.