Riassumo qui tutto quello che ho scoperto sull’attacco massivo in atto contro i blog basati su Wordpress.
La situazione
Wordpress in versione precedente alla 2.5.x è vulnerabile ad una vasta gamma di attacchi che non sono contrastabili se non in un unico modo: tenere aggiornato Wordpress. Non esistono altri metodi, non per i comuni mortali.
L’attacco è generalizzato, nessuno è al sicuro. Se il blog è presente nei motori di ricerca (Google, MSN, Altavista, Yahoo, ecc.) è solo questione di tempo. La riuscita dell’attacco è indipendente dal tema utilizzato, riesce anche con il tema di default. Quello dei temi infetti è un altro problema.
Se il blog viene compromesso, un aggiornamento non risolve, e non risolve neanche una sommaria ripulita al database: l’intrusione è profonda e su molti fronti. Se ci si limita ad un aggiornamento ed a una sommaria pulizia del database, in breve il blog sarà di nuovo compromesso. Ci sono blog con Wordpress 2.5.1 con lo stesso problema e ci sono stati casi di blog violati, i cui proprietari sono stati avvertiti da me, puliti sommariamente e ri-violati nel giro di mezzora. Quindi la pulizia deve essere totale, come spiegato qui.
La sequenza di intrusione
Questa è verosimilmente la sequenza che porta alla violazione del blog. E’ ricostruita sulla base degli esemplari di codice e database forniti da persone coraggiose che non finirò mai di ringraziare. E che dovreste ringraziare tutti.
Selezione del blog bersaglio
L’attaccante cerca i blog basati su Wordpress con semplicissime query ai principali motori di ricerca. Usa strumenti automatizzati, che gli garantiscono di riuscire a trovare un gran numero di possibili bersagli. Attraverso una forma di fingerprinting determina la versione di Wordpress installata nel bersaglio. A questo proposito è del tutto inutile nascondere la versione che viene inserita nel tag apposito:
<meta name="generator" content="WordPress 2.5.1" />
l’attaccante usa un algoritmo molto più sofisticato per determinare la versione, ed ignora del tutto, o quasi, la stringa nell’header della pagina HTML emessa da Wordpress. Per dare un’idea, viene controllata l’esistenza di alcuni file e directory caratteristiche di certe versioni, come pure il formato dei feed.
Creazione di un amministratore abusivo
Attraverso un attacco di tipo SQL injection, sfruttando le suddette vulnerabilità di Wordpress, viene creato un amministratore “abusivo” del blog. Il tipo di attacco è calibrato sulla versione di Wordpress rilevata, quindi ce n’è per tutti. L’amministratore creato con questa tecnica è invisibile dal pannello di amministrazione utenti (dettagli qui), a meno di usare trucchi o di esaminare direttamente il database. L’utente abusivo si chiama di solito “WordPress” (la ‘W’ e la ‘P’ maiuscole), ma non è detto che rimanga così.
Iniezione dei primi file
Una volta ottenuto l’accesso amministratore, viene esaminato lo spazio di hosting, per capire se e quali file e directory permettono la scrittura e la modifica dei file, se è permesso il download e l’esecuzione diretta di script PHP da altri siti e varie altre impostazioni. Se la directory dei temi è scrivibile, viene inserito un file PHP con un nome camuffato o insospettabile in uno dei temi installati, di solito quello “Classic”, che nessuno va a guardare. Tipicamente ha il nome di un altro file presente fra quelli del tema, con aggiunto in coda al nome la stringa “_old”, e non è detto che l’estensione sia “.php”. Ho trovato falsi file ZIP, false immagini PNG e JPG. Oppure è un file PHP con un nome verosimile: functions.php, locals.php e simili. Stessa cosa può succedere con la directory dei plugin, dove in qualche caso ho trovato dei falsi file ZIP con lo stesso nome di uno dei plugin installati, in realtà file PHP.
Se nessuna directory o file è scrivibile, tranne quella degli upload o quella dei backup, il file viene iniettato in quelle posizioni.
Se tutti i file sono modificabili dagli script PHP stessi, come succede in alcuni hosting, vengono modificati alcuni file dell’installazione di Wordpress, iniettando poche righe di codice, anche una sola, di solito offuscata o ricodificata in Base64 o simile. Questo semplifica parecchio l’attacco.
In qualche caso, se la configurazione del server lo permette, il file è iniettato nella directory /tmp del server, con il nome che scimmiotta i file di sessione PHP: sess_11a2d23b2......, la stringa esadecimale nel nome è praticamente casuale.
In totale i file iniettati sono almeno due: il plugin camuffato ed una sorta di shell remota che permette di modificare a piacere file ed eseguire comandi impartiti da remoto.
Iniezione di codice e dati nel database
Uno dei file appena iniettati viene inserito come plugin agendo direttamente sulla corrispondente opzione nel database di Wordpress. Naturalmente anche questo plugin “abusivo” è invisibile dal pannello di gestione dei plugin. Il nome può variare, come detto sopra, come pure la posizione. La funzione del plugin è molteplice: iniettare i link di spam al momento della visita dello spider di uno dei motori di ricerca noti, controllare che il codice iniettato sia presente ed attivo, altrimenti operare automaticamente l’iniezione del codice negli script PHP originali. Ecco uno dei motivi per cui la semplice reinstallazione, o l’aggiornamento, e la sommaria pulizia del database non funziona: anche cancellando l’utente abusivo e togliendo i link di spam, il plugin rimane attivo, per via della posizione in cui è nascosto il file, ossia nel tema, cosa che si tende a preservare, negli upload o nella directory /tmp a cui non si pensa proprio. Alla prima occasione il plugin rimette tutto a posto. Il blog, anche se aggiornato all’ultima versione di Wordpress, è già compromesso.
Altro gruppo di dati che viene inserito è il blocco dei link spam. E’ nascosto nel database come opzione fasulla di Wordpress, oppure nella cache dei feed letti dai vari blog di sviluppo e news che si vedono nel pannello di amministrazione, ed è una lunga stringa, oltre 16kb, codificata in Base64, preceduta dalla stringa eval(base64_decode(, in qualche caso è anche rovesciata, quindi in testa non ha niente, ma in coda è presente la stringa: (edoced_46aseb(lave. In altri casi, i link non sono nel database, ma nel file wp-includes/class-mail.php, che non appartiene ai file standard dell’installazione. Il file è un array serializzato con apposite funzioni PHP (dettagli qui). Questo però nelle versioni più vecchie. Nelle ultime versioni in mio possesso il file non esiste più e viene usato il database, più complicato ma molto meno visibile.
In un paio di casi ho trovato nel database anche una copia di uno dei file iniettati, ricodificato anch’esso in Base64 per nasconderlo. Probabilmente è una copia di riserva da recuperare ed attivare se il blog viene ripulito dal proprietario.
Modifica del file index.php
Se l’hosting ha una configurazione di sicurezza “debole”, e quindi permette la modifica da parte degli script PHP stessi di tutti i file dell’installazione di Wordpress, viene cambiato il file index.php nella directory principale del blog. Nelle versioni da me esaminate c’era una istruzione di include di un file preso da un sito remoto. Questo file è quello che opera il redirect verso i siti di spam, di solito farmacie online. Non sono riuscito a mettere le mani su questo file, il download è probabilmente subordinato ad una qualche forma di protezione, tipo il controllo dello user agent o dell’indirizzo IP di chi chiede l’accesso al file. Vista la complessità e l’organizzazione dell’attacco, non mi stupirebbe che sia fatto un controllo verso un database di siti compromessi prima di consentire l’accesso al file.
Non tutti i siti hanno questa variante. Dipende molto dalla versione e dalla configurazione del server. Ma quelli che la possiedono vengono inclusi nelle liste di link in altri blog violati, per consentire appunto la ridirezione al sito degli spammer.
Altri file modificati
Il codice usato nell’attacco è in diverse varianti, e ci sono segnali che è in continua evoluzione, cambiando ed affinando le tecniche sia di intrusione che di evasione dei controlli. In qualche caso ho trovato del codice inserito come action, nel file wp-includes/default-filters.php. Lo stesso file conteneva una sorta di sistema di esecuzione di codice da remoto (dettagli qui), con tanto di autenticazione tramite cookie.
Come accorgersene
Non è per niente banale. Ci sono decine di blog italiani violati e centinaia in tutto il mondo, e nessuno dei proprietari si accorge di nulla. A differenza delle prime varianti, dove si avevano malfunzionamenti che potevano insospettire, le versioni ora in circolazione sono molto meno banali, e sono molto difficili da trovare “per caso”. Chi ha sviluppato il codice ed il metodo di violazione è partito dall’obbiettivo di nascondere il più possibile al legittimo proprietario ed ai visitatori abituali la presenza della violazione. Presenza che sfugge anche ad un controllo sommario. Se non si opera in modo mirato, non si noterà nulla di strano. Ho attrezzato un test di “infezione”, che esegue alcuni semplici controlli sulla pagina principale del blog, cercando i segni, assolutamente non evidenti, dell’infezione. Segni che potrebbero a breve cambiare e rendere inefficace il controllo stesso. Per questo motivo non posso per ora aprire il codice del controllo o descriverne nei dettagli il funzionamento. Se gli spammer scoprono i punti deboli del mio controllo, e ve ne sono, lo possono rendere inefficace in breve tempo, ed avremmo tutti un’arma in meno. Altra strada per trovare i segni dell’infezione è descritta qui, in un breve documento che ho scritto specificamente per CFItaly. E’ chiaramente un documento diretto a persone dotate di specifiche conoscenze e non una ricetta passo passo, quindi non è assolutamente fruibile per gli utenti “fai-da-te”. Nessuna connotazione dispregiativa in questo, ma se non si possiedono alcune competenze specifiche è del tutto inutile leggere un simile documento.
Come uscirne
Una procedura a grandi linee l’ho descritta qui. Occorre tenere presente che il metodo di attacco cambia continuamente, e chi ha sviluppato il kit del perfetto devastatore di blog non è un cretino qualsiasi: è una persona con competenze molto al di sopra della media degli sviluppatori web, ed in generale anche alla media degli sviluppatori in generale. Sia il test che la procedura per ora dovrebbero funzionare su tutte le varianti, anche sulle più recenti. La procedura è generica, nel senso che segue le linee guida delle normali operazioni da fare quando si ha a che fare con un server violato, ossia parte dal presupposto che niente sul quel server è più affidabile, anche i comandi più semplici. Quindi dovrebbe continuare ad essere utilizzabile anche se lo schema di infezione dovesse cambiare totalmente.
Quello che forse potrebbe smettere di funzionare è il test, a causa di quanto detto sopra. Inoltre c’è il problema che per me è sempre più difficile reperire codice infettato, ossia il contenuto dei blog colpiti, sia come file che come dump del database.
Naturalmente nelle mail che ho inviato a molti c’era la richiesta, ma i più la ignorano. Questo sta togliendo a tutti noi un’arma potentissima: il codice stesso dell’infezione, quindi la possibilità di esaminare come opera e quali sono i suoi punti deboli. Senza quel codice non si può fare nulla.
Temi ed equivoci
Qualche settimana fa il test che ho attrezzato ha avuto un minimo di risonanza in Rete, ma con un problema: è stato scambiato per un test volto ad appurare se il tema è “infetto”. Il problema dei temi troianizzati è in realtà molto differente, e riguarda un altro aspetto della sicurezza di Wordpress. Ho scritto un altro articolo in proposito qui. Per ora il tutto si limita ad un modo per iniettare pochi link di spam, una decina al massimo, nel footer del blog, ed in più a proteggere il tema dalle modifiche, inserendo codice offuscato e ricodificato nel file footer.php.
Ma… c’è un grosso ma. Se dovesse succedere che l’attacco in corso esaurisse la sua efficacia, niente ci può garantire che il prossimo veicolo di infezione siano proprio i temi scaricati ed installati senza verificarne la provenienza. Il metodo è semplicissimo da applicare: una volta che abbiamo inserito un file PHP nel nostro sito senza appurare cosa faccia, per chi ha nascosto codice malevolo nel tema è un gioco da ragazzi violare il nostro blog.
Quindi, chiarito che il mio test NON può verificare se il tema installato in un blog è “infetto” o troianizzato, l’unica possibilità è di installare solo i temi di cui possiamo verificarne la provenienza o quelli di cui possiamo controllare agevolmente il codice. La semplice presenza di stringhe codificate in Base64 ed eseguite con una istruzione eval() è un segno molto poco rassicurante. Ma il mio test non può controllare questo. E’ impossibile. E’ vero però che l’infezione rilevata dal mio test è infinitamente più pericolosa.
Conclusione
Come ho già spiegato qualche tempo fa, non è facile fare il webmaster. Le conoscenze necessarie sono tante e in ogni caso potremmo non avere quelle giuste per fronteggiare una situazione come questa che stiamo affrontando.
Se poi ci si mette la faciloneria e la leggerezza nel fare le cose, il rischio di rimanere scottati è molto alto. Per carità, nessuno vuole impedire alle persone di esprimersi liberamente, se però siamo a corto di competenze, e solo perché non è il nostro campo, ci sono validissime alternative a fare il blogger fai-da-te, basta riconoscere con un po’ d’umiltà che forse è al di là delle nostre capacità. Blogspot, Splinder, Wordpress.com e tanti altri sono a disposizione per chi vuole concentrarsi su quello che ha da dire, invece di trovarsi invischiato in grossi guai. Questa è la mia opinione. Poi ognuno è libero e consapevole delle sue scelte, quindi niente da dire se si preferisce un hosting e la scelta di fare da sé. Solo che Internet è un luogo ostile.
Per cui occhi aperti e Trust no one.

