Una scansione dei file pulita non è un sito pulito. Gli script iniettati vivono comodamente dentro i contenuti: il corpo di un articolo, un widget, una riga di impostazioni, un'opzione del tema. Reinstallare l'applicazione sostituisce i file e lascia ognuno di quelli esattamente dov'era.

Cercalo

SELECT * FROM wp_posts
 WHERE post_content LIKE '%<script%'
    OR post_content LIKE '%eval(%'
    OR post_content LIKE '%base64_decode%'
 LIMIT 50;

SELECT option_name, LEFT(option_value, 120) FROM wp_options
 WHERE option_value LIKE '%<script%' LIMIT 50;

La stessa idea vale per qualunque schema: le colonne di testo che i visitatori vedono, più la tabella delle impostazioni. Cercare un tag script dentro contenuti che non dovrebbero mai contenerne ne trova la maggior parte.

Oppure cerca direttamente in tutto il dump

Più rapido che tirare a indovinare fra le tabelle, e funziona anche su uno schema che non conosci.

mysqldump -u user -p dbname > /tmp/scan.sql
grep -n -E '<script|eval\(|base64_decode|document\.write' /tmp/scan.sql | head -40
shred -u /tmp/scan.sql

Ripuliscilo

  1. Prima fai un backup del database — stai per lanciare istruzioni UPDATE su contenuti in produzione.
  2. Sistema una riga a mano — conferma la stringa esatta, e che toglierla lasci un contenuto valido.
  3. Poi il resto, con una portata strettaUPDATE wp_posts SET post_content = REPLACE(post_content, '<script src="//bad.example"></script>', '') WHERE post_content LIKE '%bad.example%';
  4. Confronta il conteggio prima e dopo — una REPLACE che tocca più righe di quante ne abbia trovate la tua SELECT significa che il criterio è troppo largo.
Non lanciare mai una REPLACE larga su tutte le colonne di testo in una volta sola. È il modo più rapido di trasformare una violazione in una perdita di dati, e il backup fatto due minuti fa diventa l'unica copia dei tuoi contenuti.

E poi chiudi la porta

I contenuti vengono iniettati attraverso qualcosa: un plugin vecchio, una password di amministrazione rubata, una cartella di caricamento scrivibile. Ripulire le righe senza trovare quel qualcosa significa che tornerà nel giro di giorni. Vedi Ripulire un sito violato.