Il contesto
Un’azienda manifatturiera di medie dimensioni, che produce componenti per macchine industriali e vende soprattutto ad altre imprese, in Italia e all’estero. Il sito, su WordPress da una decina d’anni, è il suo biglietto da visita: catalogo dei prodotti, schede tecniche da scaricare, pagine in tre lingue e un modulo per le richieste di offerta che alimenta il lavoro dell’ufficio commerciale. Lo gestiva un piccolo studio grafico esterno, che si occupava dei contenuti e, quando capitava, degli aggiornamenti. Per riservatezza, nome dell’azienda, prodotti e dettagli che permetterebbero di identificarla sono stati omessi o modificati.
Da quasi un anno il sito dava problemi a intermittenza. Il vecchio fornitore di hosting aveva sospeso due volte l’invio della posta dal server perché partivano messaggi di spam; alcuni clienti avevano segnalato che, aprendo il sito dal telefono, finivano su pagine di lotterie; il pannello mostrava picchi di carico senza una ragione evidente. Ogni volta lo studio grafico aveva aggiornato qualche plugin, cambiato una password e il problema si era attenuato, per poi ripresentarsi qualche settimana dopo.
La falsa ripartenza
A fine estate la direzione ha preso una decisione che sembrava ragionevole: cambiare fornitore. L’idea, condivisa da tutti, era che i problemi dipendessero dal vecchio hosting, «un server vecchio e lento», e che un nuovo spazio, più moderno e con un buon supporto, avrebbe chiuso la questione. Lo studio grafico ha eseguito il trasloco in un pomeriggio, con un plugin di migrazione: un archivio unico con tutti i file e il database, caricato sul nuovo spazio e ripristinato così com’era. Cambiati i DNS, il sito funzionava, era più veloce e per qualche giorno non è successo nulla. In azienda si è parlato di «ripartenza pulita».
È una convinzione diffusa, e comprensibile: se il problema si presenta su un server, spostarsi su un altro sembra la cura. Ma un’infezione di WordPress vive quasi sempre nei file del sito e nel suo database, cioè proprio in ciò che una migrazione copia. Cambiare casa portandosi dietro gli scatoloni senza aprirli non libera dai tarli.
I sintomi
Undici giorni dopo il trasloco il nuovo fornitore ha bloccato la posta in uscita dell’account: dal sito partivano centinaia di messaggi l’ora verso indirizzi mai visti. Due giorni dopo il responsabile commerciale ha ricevuto da un distributore estero la schermata di una ricerca su Google in cui, sotto il nome dell’azienda, comparivano pagine in una lingua straniera che vendevano farmaci. Il nuovo hosting, a quel punto, ha chiesto di bonificare il sito prima di riattivare la posta. La direzione ci ha contattato con una domanda precisa: «Abbiamo cambiato tutto, com’è possibile?». Ha scelto il servizio con intervento entro 12 ore.
Cosa abbiamo trovato a livello applicativo
La risposta è arrivata in fretta, confrontando il sito migrato con le versioni originali di WordPress, del tema e dei plugin. Quasi tutto ciò che non tornava era arrivato dentro l’archivio della migrazione, con le date di modifica dei mesi precedenti:
- un file nella cartella
mu-plugins, con il nome di un modulo di compatibilità, che WordPress carica sempre e che non compare nell’elenco dei plugin attivi, come descritto nell’articolo sulle backdoor nei mu-plugins e nei drop-in; - un plugin falso, con intestazione e descrizione copiate da un plugin di sicurezza noto, che si nascondeva dall’elenco della bacheca e generava al volo le pagine di spam mostrate solo ai motori di ricerca;
- quattro file PHP negli upload, sparsi in cartelle degli anni precedenti, con il contenuto codificato più volte: backdoor per rientrare e un modulo per l’invio della posta, la fonte dei messaggi di spam;
- un file
.user.ininella radice del sito che faceva caricare uno di quei file prima di ogni pagina, un meccanismo spiegato nell’articolo su .htaccess, .user.ini e auto_prepend_file. Il plugin di migrazione lo aveva copiato come qualunque altro file, e il nuovo server, che usa PHP-FPM, lo aveva rispettato alla lettera.
Il database raccontava il resto. Tra gli utenti c’erano due amministratori che nessuno in azienda né nello studio grafico conosceva, uno dei quali creato più di otto mesi prima: il caso tipico degli amministratori fantasma. In wp_options un’opzione dal nome anonimo conteneva un blocco serializzato con la configurazione del redirect per i visitatori da mobile e l’elenco dei domini di destinazione, del tipo descritto nell’articolo sui payload serializzati in wp_options. Anche questi erano passati intatti da un server all’altro, perché la migrazione aveva importato il database senza che nessuno lo guardasse.
Cosa abbiamo trovato a livello di sistema
Sul nuovo server il sistema era pulito: nessuna voce estranea nel crontab dell’account, nessun processo sospetto, nessuna chiave SSH aggiunta. È un dettaglio importante, perché conferma che il problema non era mai stato «il server vecchio». Ma a livello di sistema c’erano comunque due scoperte che spiegavano la rapidità della ricaduta.
La prima era nei log del nuovo server. Il giorno dopo il cambio dei DNS, da un indirizzo estero, c’era stato un accesso riuscito alla bacheca con l’account dello studio grafico, seguito da richieste dirette a una delle backdoor negli upload. Nessuna forzatura: la password era la stessa di prima, e con ogni probabilità era già nelle mani di chi aveva infettato il sito. Anche le password del database, dell’SFTP e le chiavi di sicurezza in wp-config.php erano state copiate senza cambiarle.
La seconda riguardava il vecchio hosting, di cui l’azienda ci ha fornito gli accessi. L’account era ancora attivo, pagato fino a fine anno, e ospitava sia una copia del sito sia un vecchio ambiente di prova su un sottodominio, entrambi infetti. Nel suo crontab c’era una voce che ogni ora richiamava una delle backdoor, e i log mostravano che l’ingresso iniziale, mesi prima, era avvenuto attraverso un plugin per le gallerie di immagini abbandonato dallo sviluppatore, con una vulnerabilità nota di caricamento di file. Lo stesso plugin, naturalmente, era stato migrato ed era attivo anche sul nuovo server.
Come l’abbiamo rimosso
Prima di intervenire abbiamo salvato le prove da entrambi gli account: copia dei file sospetti, esportazione del database, crontab e log. Poi, d’accordo con la direzione, abbiamo trattato la bonifica come la migrazione che avrebbe dovuto essere:
- messo il sito in manutenzione e bloccato l’accesso alla bacheca, per chiudere la porta usata con le vecchie credenziali;
- reinstallato il core di WordPress, il tema e tutti i plugin da fonti ufficiali, invece di pulire i file esistenti; il plugin delle gallerie, abbandonato, è stato sostituito con uno mantenuto;
- ricopiato dagli upload solo ciò che doveva esserci, cioè immagini e documenti, dopo averli controllati uno per uno per tipo e contenuto, e rimosso
.user.ini,mu-pluginse le backdoor; - ripulito il database: eliminati i due amministratori fantasma e l’opzione con il payload, controllati post, opzioni caricate automaticamente, utenti e trigger;
- cambiato tutte le credenziali: password degli utenti, del database, dell’SFTP e del pannello, e generato nuove chiavi e salt in
wp-config.php; - verificato i file e il database con una nuova scansione e il confronto dei checksum, e controllato che le pagine di spam restituissero un errore anche quando richieste come motore di ricerca.
Il vecchio account, su nostra indicazione, è stato svuotato e chiuso dopo averne conservato una copia per l’analisi: finché restava online, con una copia infetta e un cron attivo, era un punto d’appoggio pronto all’uso. Il nuovo fornitore ha riattivato la posta dopo aver ricevuto il nostro rapporto, e lo studio grafico ha segnalato a Google, dalla Search Console, gli indirizzi delle pagine di spam da rimuovere.
La migrazione giusta
Il cuore del caso non è tecnico, ma di metodo. Una migrazione è il momento ideale per ripartire davvero da zero, a patto di non limitarsi a copiare. L’ordine corretto è quello che abbiamo seguito noi, solo in anticipo: prima si verifica e si pulisce, poi si trasloca. Con lo studio grafico abbiamo scritto una lista di controllo da seguire per tutti i traslochi futuri, anche per i siti di altri clienti.
Tre punti, in particolare, fanno la differenza. Il software si reinstalla, non si copia: core, tema e plugin scaricati dalle fonti ufficiali non possono contenere le modifiche di un attaccante, mentre una copia le porta con sé. Il database si guarda prima di importarlo, perché utenti, opzioni e trigger sopravvivono a qualunque cambio di server. E le credenziali si rinnovano tutte, perché un sito spostato con le stesse password è un sito di cui qualcun altro può già avere le chiavi.
L’hardening
Sul nuovo account abbiamo impedito l’esecuzione di PHP negli upload, bloccato la modifica dei file dalla bacheca e impostato i permessi di wp-config.php come descritto nell’articolo sull’hardening di wp-config.php. Gli utenti con ruolo di amministratore sono passati da cinque a due, entrambi con l’autenticazione a due fattori; lo studio grafico lavora ora con un ruolo da editor e ottiene i privilegi più alti solo quando servono. L’invio della posta passa da un servizio SMTP autenticato invece che dalla funzione di posta del server, così un eventuale abuso sarebbe subito visibile. Infine è attivo il monitoraggio dell’integrità dei file, con un avviso per qualunque file PHP nuovo fuori dalle cartelle attese.
Il risultato
Il sito è stato dichiarato pulito entro le 12 ore previste dal servizio, calcolate dalla ricezione degli accessi a entrambi gli hosting. La posta è stata riattivata il giorno successivo, e nel giro di tre settimane le pagine di spam sono sparite dai risultati di ricerca sul nome dell’azienda. Nei due mesi seguenti il monitoraggio non ha registrato modifiche non autorizzate, né invii anomali di posta. Per la prima volta in un anno i problemi non si sono «attenuati»: sono finiti. La direzione ha ricevuto un rapporto con la ricostruzione dell’infezione dall’ingresso iniziale sul vecchio server fino alla ricaduta sul nuovo, e la lista di controllo per le migrazioni.
Cosa insegna questo caso
Cambiare hosting è spesso una buona idea, ma non è una bonifica. Quando i problemi di un sito si ripetono, la domanda da farsi non è «dove si trova?», ma «che cosa contiene?», e la risposta va cercata prima del trasloco, non dopo. Il caso insegna anche qualcosa sull’organizzazione: nessuno aveva mai chiesto allo studio grafico di indagare sulle cause, solo di far sparire i sintomi, e la migrazione era stata trattata come un’operazione tecnica di un pomeriggio invece che come un’occasione per verificare tutto. Infine, un vecchio account lasciato acceso «per sicurezza» è il contrario della sicurezza: va chiuso appena il nuovo sito è verificato.
Rimozionemalware.com è il servizio di bonifica dei siti WordPress di Managed Server S.r.l., che gestisce server e hosting dal 2005. Interveniamo sull’applicazione e sul sistema, con tempi garantiti di 6, 12 o 24 ore per ogni installazione di WordPress, calcolati dalla ricezione degli accessi. Se stai per cambiare hosting e il tuo sito ha avuto problemi, o se li ha di nuovo dopo il trasloco, puoi contattarci: meglio verificarlo prima di spostarlo.