Ransomware e defacement su WordPress: cosa succede davvero e come si recupera

File cifrati da uno script PHP, database svuotati, finti riscatti e home sostituite: come distinguere cifratura reale e bluff e come recuperare il sito.

Una finestra del browser con una finta richiesta di riscatto, un conto alla rovescia e un indirizzo bitcoin, affiancata da un terminale in cui il comando file mostra che i file PHP del sito sono ancora leggibili: la cifratura annunciata è un bluff

«Il sito è stato cifrato, per riaverlo paga in bitcoin.» Leggere una frase del genere al posto della propria home page è un’esperienza che mette in crisi anche chi ha sangue freddo. La parola ransomware evoca le aziende ferme per settimane, i server cifrati, i dati pubblicati sui siti di estorsione. Su WordPress, però, dietro quella frase c’è quasi sempre qualcosa di diverso e di più gestibile: a volte una cifratura vera ma limitata ai file del sito, a volte un database cancellato, molto spesso solo una pagina che mente.

La prima domanda davanti a una richiesta di riscatto non è «quanto chiedono», ma «cosa è successo davvero». La risposta si trova quasi sempre in meno di un’ora, guardando i file e il database invece della pagina.

In questo articolo mettiamo in fila le forme che prendono ransomware e defacement sui siti WordPress, gli episodi documentati che le illustrano, i controlli per distinguere una cifratura reale da un bluff e la sequenza di recupero. È un articolo difensivo: descriviamo cosa si osserva sul sito colpito, non come si costruisce un attacco.

Cosa si intende davvero per ransomware su WordPress

Il ransomware classico è un programma che gira sul computer o sul server della vittima, cifra i dati con una chiave che solo l’attaccante possiede e chiede un pagamento per consegnarla. Su un sito WordPress ospitato su un server Linux, l’attaccante di solito non ha il controllo del sistema: ha il controllo dell’utente con cui gira PHP, ottenuto con una password rubata o una vulnerabilità di un plugin. Da quella posizione può fare tre cose, che nella pratica si presentano tutte con il nome di ransomware.

Può cifrare o rinominare i file del sito con uno script PHP. Può cancellare o svuotare il database e lasciare al suo posto una tabella con la richiesta di riscatto. Oppure può limitarsi a mostrare un messaggio, senza toccare nulla, confidando che il panico faccia il resto. A queste si aggiunge il defacement, che non chiede soldi ma sostituisce la home page con un messaggio di rivendicazione. Le quattro situazioni hanno conseguenze e rimedi molto diversi, ed è per questo che la diagnosi viene prima di ogni altra decisione.

File cifrati da uno script PHP

La cifratura dei file esiste ed è documentata. Nel 2017 Wordfence ha descritto un ransomware per WordPress che ha chiamato EV ransomware: uno script PHP caricato sul sito compromesso che cifrava i file, aggiungeva l’estensione .EV e creava una pagina per la «decifratura» insieme a un .htaccess che vi reindirizzava ogni richiesta. Come riportato anche da Help Net Security, i ricercatori notarono un dettaglio decisivo: lo strumento non conteneva un meccanismo di decifratura funzionante, quindi anche pagando la chiave i file non sarebbero tornati da soli.

Questo tipo di attacco ha due caratteristiche utili da conoscere. La prima è che lo script gira con i permessi dell’utente PHP: può cifrare ciò che quell’utente può scrivere, cioè i file del sito, ma non i backup custoditi altrove né i file di sistema. La seconda è che uno script PHP deve rimanere funzionante per mostrare la pagina di riscatto, quindi spesso lascia intatti alcuni file o cifra solo certe estensioni. Nei casi che vediamo più di frequente, poi, la «cifratura» è una semplice rinomina o una codifica reversibile, senza alcuna chiave segreta.

Quando i file sono cifrati davvero e non esiste un backup esterno, non tutto è perduto. Il core di WordPress, i plugin e i temi pubblici si riscaricano nella stessa versione; ciò che conta sono i contenuti, che stanno nel database e di solito non vengono toccati da uno script che lavora sui file, e i media nella cartella degli upload. Per questi ultimi si cercano copie parziali nella cache del CDN, nelle cartelle di cache dei plugin, sul computer di chi ha caricato le immagini o in un vecchio ambiente di sviluppo. Un sito ricostruito così è spesso più pulito dell’originale, perché nasce da componenti scaricati di nuovo invece che da file di cui nessuno conosceva la storia.

Il finto ransomware: una pagina e un conto alla rovescia

All’estremo opposto c’è il bluff puro. Nel novembre 2021 Sucuri ha analizzato una campagna di finto ransomware che mostrava sui siti colpiti la scritta «SITE ENCRYPTED», un indirizzo bitcoin e un conto alla rovescia. Nessun file era cifrato: il messaggio era generato da codice aggiunto in un file del plugin Directorist, e un comando SQL aveva cambiato lo stato di tutti gli articoli e le pagine pubblicate in un valore non valido, così che il sito restituisse errori 404 e sembrasse davvero svuotato. Secondo BleepingComputer, che riprendeva i dati di Sucuri, i siti colpiti erano circa 291, e l’ingresso era avvenuto con credenziali di amministratore.

Il recupero, in quel caso, richiedeva di rimuovere il codice aggiunto, riportare lo stato dei contenuti a «pubblicato» con una query e cambiare tutte le password di amministratore, eliminando gli account non riconosciuti. Nessun pagamento avrebbe cambiato nulla, perché non c’era niente da decifrare. È un esempio perfetto di perché la pagina di riscatto non va mai presa per buona.

Il database svuotato e la nota in una tabella

Il terzo scenario colpisce il database, e non richiede nemmeno di passare da WordPress. Akamai ha documentato nel 2020 la campagna PLEASE_READ_ME, che colpiva server MySQL esposti su Internet con password deboli: i dati venivano esportati e inviati agli attaccanti, il database cancellato e sostituito da una tabella chiamata WARNING con la richiesta di riscatto, e veniva creato un utente MySQL aggiuntivo per mantenere l’accesso. Secondo l’analisi, i dati rubati venivano poi messi in vendita indipendentemente dal pagamento.

Per un sito WordPress la situazione si riconosce subito: il sito mostra la schermata di installazione o un errore di connessione al database, e tra le tabelle ce n’è una che non appartiene a WordPress. Le varianti che passano da un accesso a WordPress, invece, cancellano le tabelle dal pannello di un plugin di gestione del database o da una webshell. In entrambi i casi il punto chiave è che i dati sono stati letti prima di essere cancellati: oltre al recupero c’è una probabile violazione di dati personali da gestire.

Defacement: la home sostituita

Il defacement non chiede soldi. La home page viene sostituita da una pagina con un nome, uno slogan, spesso un messaggio politico o una rivendicazione di gruppo, e a volte da una musica di sottofondo. Tecnicamente è quasi sempre una di tre modifiche: un file index.html nella radice, che molti server servono prima di index.php; un index.php riscritto; una direttiva DirectoryIndex aggiunta al file .htaccess, come quelle descritte nell’articolo su .htaccess e .user.ini. Più raramente cambiano le opzioni siteurl e home nel database, o viene pubblicato un articolo in evidenza.

Il defacement è rumoroso per scelta, e proprio per questo inganna: una volta ripristinata la home, il sito sembra a posto. Ma chi ha potuto scrivere index.php ha potuto scrivere anche altro, e spesso la pagina vistosa è accompagnata da webshell e utenti aggiunti, gli stessi strumenti di persistenza che troviamo nelle infezioni silenziose. Trattarlo come un problema di grafica è l’errore più comune.

Il defacement ha anche un effetto che va oltre il sito: la pagina modificata viene indicizzata dai motori di ricerca e a volte archiviata in raccolte pubbliche che i gruppi usano come vetrina. Per questo, dopo la bonifica, conviene chiedere una nuova scansione delle pagine principali dalla Search Console e verificare che il dominio non sia finito in qualche lista di reputazione, come descritto nell’articolo sulla rimozione dalle blacklist.

Cifratura vera o bluff: come capirlo

Bastano pochi comandi, lanciati in sola lettura su una copia o direttamente sul server senza modificare nulla. Il primo guarda le estensioni: se migliaia di file hanno la stessa estensione sconosciuta, qualcosa li ha rinominati. Il secondo guarda il contenuto: un file PHP leggibile è in chiaro, un file che file identifica come dati binari o come un’unica lunga riga base64 potrebbe essere cifrato. Il terzo guarda il database: tabelle presenti, stati dei contenuti, tabelle e utenti estranei.

cd /var/www/esempio.it/public_html

# Estensioni più frequenti: una sola estensione anomala su migliaia di file è un segnale
find . -type f | sed -n 's/.*\.\([^./]*\)$/\1/p' | sort | uniq -c | sort -rn | head

# Il file di versione del core è ancora leggibile?
file wp-includes/version.php; head -c 300 wp-includes/version.php

# File creati o modificati nelle ultime 48 ore (la nota di riscatto e lo script)
find . -type f -mmin -2880 -printf '%TY-%Tm-%Td %TH:%TM  %p\n' | sort | tail -40

# Database: tabelle, stati dei contenuti e utenti MySQL estranei
wp db tables
wp db query "SELECT post_status, COUNT(*) FROM wp_posts GROUP BY post_status;"
mysql -e "SELECT user, host FROM mysql.user;"   # richiede i privilegi di amministratore MySQL

Il risultato colloca il caso in una delle caselle dello schema qui sotto. Anche nei casi di cifratura reale, conviene cercare nei file creati di recente lo script che l’ha eseguita: se la chiave è scritta nel codice o nei log delle richieste, come succede con gli strumenti più rozzi, i file si possono recuperare senza pagare nessuno. Il progetto No More Ransom, promosso da forze di polizia e aziende di sicurezza, raccoglie inoltre strumenti di decifratura gratuiti per le famiglie di ransomware di cui sono state recuperate le chiavi.

Schema di diagnosi con quattro esiti a partire da una pagina di riscatto o di rivendicazione. Prima domanda: i file PHP del core sono leggibili? Se no, e molti file hanno una nuova estensione, l’esito è cifratura reale dei file, da recuperare dai backup e cercando lo script e l’eventuale chiave. Se sì, seconda domanda: le tabelle di WordPress e i contenuti sono presenti e pubblicati? Se mancano tabelle o compare una tabella WARNING, l’esito è database cancellato con probabile furto di dati. Se i contenuti hanno uno stato anomalo, l’esito è finto ransomware, reversibile con una query. Se tutto è presente e cambia solo la home, l’esito è defacement. Tutti gli esiti confluiscono in una fascia comune: conservare le prove, trovare il vettore, bonificare.
Pochi controlli su file e database bastano per capire se si tratta di cifratura reale, database cancellato, finto ransomware o defacement; la bonifica serve in tutti e quattro i casi.

Non pagare, e conservare le prove

Il consiglio di non pagare non è moralismo. Come ricorda No More Ransom, pagare conferma agli attaccanti che il metodo funziona e non garantisce di ricevere la chiave. Nei casi descritti sopra, poi, pagare sarebbe stato inutile per definizione: la decifratura di EV non funzionava, il finto ransomware non aveva cifrato nulla e nella campagna sui database i dati venivano venduti comunque. Chi ha un backup affidabile non ha bisogno di trattare; chi non ce l’ha, ha comunque buone probabilità di recuperare più di quanto creda.

Prima di ripristinare o cancellare qualcosa, si conservano le prove. Lo stato del sito al momento della scoperta serve a trovare il punto d’ingresso, a capire quali dati sono stati letti e, se si decide di sporgere denuncia alla Polizia Postale, a documentare l’accaduto:

INC=/root/incidente-$(date +%F); mkdir -p "$INC"

# File del sito con permessi, proprietari e date
tar --numeric-owner -czpf "$INC/sito.tar.gz" -C /var/www/esempio.it public_html

# Database nello stato attuale, anche se svuotato
mysqldump --single-transaction --routines --triggers --events esempio_wp > "$INC/db.sql"

# Log del web server e di PHP-FPM, prima che la rotazione li cancelli
cp -a /var/log/nginx /var/log/php*-fpm* "$INC/" 2>/dev/null

# Impronte per dimostrare che le copie non sono state alterate
sha256sum "$INC"/* > "$INC/SHA256SUMS"

Nel frattempo il sito va tolto dalla vista del pubblico senza toccare i file: una pagina di manutenzione servita direttamente dal web server, con codice di stato 503, evita che i visitatori vedano la richiesta di riscatto e che i motori di ricerca la indicizzino, e lascia intatta la scena. Cancellare subito la pagina di riscatto o il file index.html del defacement è comprensibile, ma distrugge proprio le date e i contenuti che servono per risalire all’ingresso.

L’ordine completo delle prime mosse, dalla messa offline al cambio delle credenziali, è descritto nell’articolo sulle prime due ore dopo un attacco.

Recuperare: backup, bonifica, vettore e comunicazione

Il recupero ha quattro componenti, e saltarne una significa rivedere lo stesso messaggio fra qualche settimana. La prima è il ripristino dei dati: file e database da una copia che l’attaccante non ha potuto toccare. Qui si vede la differenza tra un backup nella stessa cartella del sito, spesso cifrato insieme a tutto il resto, e una copia immutabile e fuori sede come quelle descritte nell’articolo sui backup a prova di ransomware. Il ripristino va fatto su un ambiente pulito e con le cautele dell’articolo sui backup che riportano il malware, perché la copia può già contenere la backdoor da cui è partito tutto.

La seconda è la bonifica: webshell, utenti amministratori aggiunti, cron, mu-plugin, utenti MySQL creati dagli attaccanti. La terza è il vettore: la vulnerabilità o la credenziale che ha permesso l’accesso, da chiudere prima di rimettere online il sito. La quarta è la comunicazione, e non riguarda solo i visitatori. Se il database conteneva dati personali ed è stato letto, cancellato o reso indisponibile, può trattarsi di una violazione da valutare e, se ne ricorrono le condizioni, da notificare al Garante entro 72 ore, come spieghiamo nell’articolo su GDPR e sito hackerato. Clienti e fornitori preferiscono sapere dall’azienda cosa è successo, con parole semplici e senza minimizzare, piuttosto che scoprirlo da altri.

Sequenza di recupero in sei passaggi numerati disposti su una linea: uno, isolare il sito con una pagina di manutenzione servita dal web server; due, conservare file, database e log con le impronte sha256; tre, diagnosticare se si tratta di cifratura, database cancellato, bluff o defacement; quattro, ripristinare da una copia immutabile su un ambiente pulito; cinque, bonificare la persistenza e chiudere il vettore d’ingresso; sei, cambiare le credenziali, comunicare e valutare l’obbligo di notifica. Sotto la linea, un riquadro rosso barrato indica il passaggio da evitare: pagare il riscatto.
La sequenza di recupero: prima le prove e la diagnosi, poi il ripristino, la bonifica e la chiusura del vettore; il pagamento non compare in nessun punto.

Se il tuo sito mostra una richiesta di riscatto o una pagina di rivendicazione, non cancellare nulla e scrivici. Facciamo la diagnosi, conserviamo le prove, ripristiniamo dai backup disponibili e bonifichiamo ogni installazione WordPress a livello applicativo e di sistema, con tempi garantiti di 6, 12 o 24 ore dalla ricezione degli accessi necessari, consegnando un rapporto utile anche per le eventuali notifiche.

IL PROSSIMO PASSO

Il tuo sito
è infetto?

Ogni ora conta: il malware continua a colpire visitatori e clienti, e Google, l’hosting e le blacklist non aspettano. Scegli il piano, paga online e condividi gli accessi: la bonifica parte subito, a prezzo fisso e con tempi garantiti.

Richiedi la bonifica

Ti porta ai piani: bonifica entro 6, 12 o 24 ore dalla ricezione degli accessi.

MANAGED SERVER S.R.L.info@rimozionemalware.com +39 02 5656 9681

Lunedì – venerdì · 09:30 – 19:30

Preferisci un modulo online?
Contattaci su managedserver.it ↗