La domanda raramente nasce dal nulla. Il server è diventato più lento, il provider ha scritto per il traffico in uscita, oppure nella posta c’è una notifica di accesso che lei non ha effettuato. Poi comincia la parte più spiacevole: non è chiaro che cosa guardare né in quale ordine, e il primo impulso — cancellare tutto e reinstallare — è quasi sempre prematuro.
Di seguito un ordine di controllo che richiede una ventina di minuti e nella maggior parte dei casi dà una risposta netta. Procede dal meno costoso al più costoso: prima ciò che si vede subito, poi ciò che richiede un confronto.
Primo passo: chi è entrato
Cominci dagli accessi. Se qualcun altro è entrato, quasi certamente lo ha fatto via SSH, e una traccia è rimasta.
last -20
lastb | head -20
who
last mostra gli ultimi accessi riusciti, lastb quelli falliti, who chi è collegato in questo momento. Ciò che conta non è la quantità ma la forma. Migliaia di tentativi falliti da indirizzi che non tornano mai sono il rumore di fondo abituale: accade a qualsiasi indirizzo pubblico senza interruzione e non significa nulla.
Inquietante è altro:
- un accesso riuscito da un indirizzo dove non c’è nessuno dei suoi;
- un accesso con un nome utente che lei non ha mai creato;
- tentativi falliti con un nome che su questa macchina esiste davvero: significa che qualcuno conosce l’elenco dei suoi utenti e non sta scorrendo un dizionario;
- una sessione aperta in questo momento che lei non ha aperto.
Verifichi inoltre se sono comparse chiavi altrui. Il file ~/.ssh/authorized_keys è il modo più comune per radicarsi: la password si può cambiare quante volte si vuole, la chiave resta.
cat ~/.ssh/authorized_keys
sudo cat /root/.ssh/authorized_keys
Ogni riga lì è l’accesso di qualcuno. Se non può dire di chi, la consideri altrui.
Secondo passo: che cosa è cambiato nel sistema
Un’intrusione lascia quasi sempre tracce sul disco: un binario sostituito, una riga aggiunta a una configurazione, un file nuovo nella cartella del server web. Verificarlo a occhio è inutile: serve un riferimento.
Su Debian e Ubuntu il riferimento esiste già: ogni pacchetto conosce le somme di controllo dei propri file.
sudo apt install debsums
sudo debsums -c
Il comando elenca i file che differiscono da ciò che ha installato la distribuzione. Una parte dei risultati sarà legittima: i file di configurazione sotto /etc esistono proprio per essere modificati. Un eseguibile modificato in /usr/bin, /usr/sbin o /bin su un server che lei non ha mai toccato a mano è invece un altro discorso.
La seconda fonte sono i file recenti dove non dovrebbero essercene. Una web shell di solito sta nella cartella dei caricamenti e sembra un innocuo .php:
find /var/www -type f -name '*.php' -mtime -14 -ls
Quattordici giorni sono solo un punto di partenza; metta il periodo in cui è certo di non aver pubblicato nulla.
Terzo passo: che cosa esce
Un server compromesso viene raramente preso per sé stesso. Viene usato: per inviare spam, per minare, per raggiungere altre reti, per ospitare file altrui. Tutto questo crea connessioni in uscita che prima non c’erano.
ss -tulpn
ss -tp state established
Il primo comando mostra che cosa è in ascolto, il secondo che cosa è stabilito adesso. Va letta la colonna del processo. Fanno sorgere domande: un processo sconosciuto in ascolto su 0.0.0.0; connessioni in uscita verso porte alte a indirizzi con cui la sua applicazione non ha nulla a che fare; e soprattutto un processo avviato da /tmp o /dev/shm: da quelle cartelle non parte nulla di legittimo.
Guardi anche il carico. Un miner si tradisce perché il processore è occupato in permanenza mentre il sito non gode di alcuna popolarità.
Se i segnali ci sono
Il primo impulso è ripulire in fretta: cancellare la chiave altrui, uccidere il processo, eliminare il file. Non lo faccia: distruggerebbe proprio ciò che poi permetterebbe di capire da dove è entrato. E se questo resta incompreso, tornerà, magari domani.
Un ordine che preserva sia i dati sia il quadro:
- Fare uno snapshot del disco presso il provider, se possibile. È l’unico passo che poi non si può ripetere.
- Isolare la macchina dalla rete o chiudere tutto tranne il proprio IP, ma non spegnerla. Spegnendola perde l’elenco dei processi e le connessioni aperte, che sono metà degli indizi.
- Salvare i registri all’esterno:
/var/log/auth.log, quelli del server web, l’output dei tre comandi di sopra. - Solo adesso capire come è stato ottenuto l’accesso.
Una reinstallazione da zero è la conclusione giusta se l’accesso è stato ottenuto con privilegi di root. Nessuna pulizia garantisce che non sia rimasto nulla. Ma reinstallare senza aver capito la causa è inutile: rimetterebbe lo stesso buco su un sistema nuovo.
Perché la domanda non arrivi all’improvviso
Tutto quanto sopra è un controllo manuale una tantum e risponde alla domanda «che cosa sta succedendo adesso». Il guaio è che di solito la si pone tardi: quando il provider ha già scritto o il sito è caduto.
Ognuno di questi controlli esiste come strumento autonomo capace di sorvegliare di continuo: gli accessi falliti, fail2ban; le modifiche ai file, AIDE; l’integrità dei pacchetti, debsums; le porte aperte, uno snapshot periodico di ss. Installarli separatamente non è difficile; difficile è abituarsi a leggere ogni giorno sei output diversi, motivo per cui in pratica non li si legge.
Questo è esattamente il senso di un pannello unificato: gli stessi dati, ma su una sola pagina e con uno storico, perché «ieri non era così» si veda senza doverlo andare a cercare. Sotto ci sono le pagine dimostrative che mostrano come appare il tutto assemblato.