A pergunta raramente surge do nada. O servidor ficou mais lento, o alojamento escreveu por causa do tráfego de saída, ou no correio há um aviso de acesso que não foi seu. Depois começa a parte mais desagradável: não se sabe o que observar nem por que ordem, e o primeiro impulso — apagar tudo e reinstalar — é quase sempre prematuro.
Segue-se uma ordem de verificação que leva uns vinte minutos e que, na maioria dos casos, dá uma resposta clara. Vai do mais barato ao mais caro: primeiro o que se vê de imediato, depois o que exige comparação.
Primeiro passo: quem entrou
Comece pelos acessos. Se um estranho entrou, quase de certeza entrou por SSH, e ficou rasto.
last -20
lastb | head -20
who
last mostra os últimos acessos bem-sucedidos, lastb os falhados, who quem está ligado neste momento. O que importa não é a quantidade mas a forma. Milhares de tentativas falhadas a partir de endereços que nunca regressam são o ruído de fundo habitual: acontece a qualquer endereço público sem interrupção e não significa nada.
Inquietante é outra coisa:
- um acesso bem-sucedido a partir de um endereço onde não está ninguém dos seus;
- um acesso com um nome de utilizador que nunca criou;
- tentativas falhadas com um nome que existe mesmo nesta máquina: significa que alguém conhece a lista dos seus utilizadores e não anda a percorrer um dicionário;
- uma sessão aberta neste momento que não foi aberta por si.
Verifique também se surgiram chaves alheias. O ficheiro ~/.ssh/authorized_keys é a forma mais comum de se fixar: a palavra-passe pode ser mudada as vezes que se quiser, a chave permanece.
cat ~/.ssh/authorized_keys
sudo cat /root/.ssh/authorized_keys
Cada linha ali é o acesso de alguém. Se não consegue dizer de quem, considere-a alheia.
Segundo passo: o que mudou no sistema
Uma intrusão deixa quase sempre rastos no disco: um binário substituído, uma linha acrescentada a uma configuração, um ficheiro novo na pasta do servidor web. Verificar isso a olho é inútil: é preciso uma referência.
No Debian e no Ubuntu a referência já existe: cada pacote conhece as somas de verificação dos seus próprios ficheiros.
sudo apt install debsums
sudo debsums -c
O comando lista os ficheiros que diferem do que a distribuição instalou. Parte dos resultados será legítima: os ficheiros de configuração em /etc existem precisamente para serem alterados. Já um executável alterado em /usr/bin, /usr/sbin ou /bin num servidor em que nunca mexeu à mão é outra conversa.
A segunda fonte são os ficheiros recentes onde não deveriam existir. Uma web shell costuma estar na pasta de carregamentos e parece um .php inofensivo:
find /var/www -type f -name '*.php' -mtime -14 -ls
Catorze dias são apenas um ponto de partida; ponha o período em que tem a certeza de nada ter publicado.
Terceiro passo: o que sai para fora
Um servidor comprometido raramente é tomado por si mesmo. É usado: para enviar spam, para minerar, para chegar a outras redes, para alojar ficheiros alheios. Tudo isso cria ligações de saída que antes não existiam.
ss -tulpn
ss -tp state established
O primeiro comando mostra o que está à escuta, o segundo o que está estabelecido agora. É preciso ler a coluna do processo. Levantam dúvidas: um processo desconhecido à escuta em 0.0.0.0; ligações de saída para portas altas em endereços com que a sua aplicação nada tem a ver; e sobretudo um processo iniciado a partir de /tmp ou /dev/shm: dessas pastas não corre nada legítimo.
Veja também a carga. Um minerador denuncia-se por manter o processador ocupado em permanência enquanto o sítio não goza de popularidade nenhuma.
Se os sinais aparecerem
O primeiro impulso é limpar depressa: apagar a chave alheia, matar o processo, eliminar o ficheiro. Não o faça: estaria a destruir precisamente aquilo que depois permitiria perceber por onde ele entrou. E se isso ficar por perceber, ele voltará, talvez amanhã.
Uma ordem que preserva tanto os dados como o quadro geral:
- Tirar um instantâneo do disco no alojamento, se for possível. É o único passo que depois não se pode repetir.
- Isolar a máquina da rede ou fechar tudo exceto o seu próprio IP, mas não a desligar. Ao desligá-la perde a lista de processos e as ligações abertas, que são metade das provas.
- Guardar os registos para fora:
/var/log/auth.log, os do servidor web, a saída dos três comandos acima. - Só então apurar como foi obtido o acesso.
Uma reinstalação de raiz é o final correto se o acesso foi obtido com privilégios de root. Nenhuma limpeza garante que nada ficou para trás. Mas reinstalar sem ter percebido a causa não faz sentido: devolveria o mesmo buraco a um sistema novo.
Para que a pergunta não chegue de repente
Tudo o que ficou dito é uma verificação manual pontual e responde à pergunta «o que está a acontecer agora». O problema é que ela costuma ser feita tarde: quando o alojamento já escreveu ou o sítio já caiu.
Cada uma destas verificações existe como ferramenta autónoma capaz de vigiar continuamente: os acessos falhados, fail2ban; as alterações de ficheiros, AIDE; a integridade dos pacotes, debsums; as portas abertas, um instantâneo periódico de ss. Instalá-las separadamente não é difícil; difícil é habituar-se a ler todos os dias seis saídas diferentes, razão pela qual, na prática, não são lidas.
É exatamente esse o sentido de um painel reunido: os mesmos dados, mas numa só página e com histórico, para que «ontem não era assim» se veja sem ser preciso ir procurar. Abaixo estão as páginas de demonstração que mostram como isto fica montado.