Sito WordPress infetto: come pulirlo da terminale passo passo e non farsi reinfettare

Trovare una webshell sul proprio sito fa un certo effetto. La tentazione è cancellare il file sospetto e rimettere tutto online il prima possibile, ma è il modo migliore per ritrovarsi infettati di nuovo dopo qualche giorno. Chi è entrato una volta ha quasi sempre lasciato più di una porta aperta: altri file nascosti, un utente amministratore in più, un’attività pianificata che riscarica tutto. Questa guida segue l’ordine che conviene seguire su un VPS Ubuntu con accesso SSH. Se non hai ancora controllato il server, parti dal quadro generale che trovi nell’articolo su PHP2Shell.

I comandi usano WP-CLI. Se non lo hai, installalo prima di cominciare, perché in questa situazione risparmia moltissimo lavoro.

Prima di toccare qualsiasi cosa

Metti il sito offline, o almeno in manutenzione, così smette di servire malware ai visitatori. Poi fai uno snapshot del VPS dal pannello del provider e una copia dei file nello stato attuale. Servirà per capire come sono entrati e per non perdere nulla se qualcosa va storto durante la pulizia.

Pubblicità

cd /var/www/miosito
sudo tar czf /root/sito-infetto-$(date +%F).tar.gz .
sudo cp /usr/local/lsws/logs/access.log /root/access-$(date +%F).log
sudo cp /usr/local/lsws/logs/error.log /root/error-$(date +%F).log

Conserva la copia fuori dalla cartella del sito. Non rimetterla mai online e non estrarla in una cartella raggiungibile dal web.

Capire da dove sono entrati

Se pulisci senza sapere come è avvenuto l’accesso, la stessa falla resta aperta. Guarda i file creati o modificati di recente, dal più recente:

find . -type f -mtime -30 -printf '%TY-%Tm-%Td %TH:%TM  %u  %p\n' | sort -r | head -60

Il primo file anomalo ti dà una data. Ora cerca nei log di accesso cosa è successo in quel momento, cioè quali richieste sono arrivate poco prima:

grep "27/Oct/2026:09:" /root/access-*.log | grep -E "POST|\.php" | head -40

Cambia data e ora con quelle del tuo caso. Cerca richieste POST a plugin, file in uploads o script che non riconosci. Il percorso che compare ripetutamente di solito punta al plugin o al tema vulnerabile. Annotalo, perché è proprio quello da eliminare o aggiornare.

Cambiare subito le credenziali

Finché le password restano quelle vecchie, chiunque le abbia rubate può rientrare. Cambia tutto, ma solo dopo aver messo il sito offline, perché alcune modifiche possono invalidare le sessioni.

Controlla gli amministratori e cerca quelli che non conosci:

wp user list --role=administrator --fields=ID,user_login,user_email,user_registered --allow-root

Elimina gli utenti sospetti, assegnando i contenuti a un utente fidato:

wp user delete ID_SOSPETTO --reassign=ID_TUO --allow-root

Per gli utenti legittimi, genera il reset della password via email:

wp user reset-password ID_UTENTE --allow-root

Poi cambia le chiavi di sicurezza di WordPress, che disconnette tutti gli utenti e invalida i cookie già rubati:

wp config shuffle-salts --allow-root

Non dimenticare la password del database. Se la tua versione è compromessa, va cambiata sia nel database sia nel file wp-config.php:

ALTER USER 'utente_db'@'localhost' IDENTIFIED BY 'una-password-lunga-e-nuova';
FLUSH PRIVILEGES;

Allo stesso modo cambia le password FTP e SFTP e controlla le chiavi SSH autorizzate, perché un attaccante può aver lasciato la sua.

Rimettere a posto il core di WordPress

I file del core si possono sostituire con quelli originali. Prima salva la versione installata, poi elimina le due cartelle del core e riscaricale. Non basta sovrascrivere, perché i file estranei rimarrebbero lì in mezzo:

VER=$(wp core version --allow-root)
sudo rm -rf wp-admin wp-includes
wp core download --force --skip-content --version=$VER --allow-root
wp core verify-checksums --allow-root

Salvare la versione prima di cancellare è importante, perché il comando la legge proprio da un file che stai per eliminare. L’ultimo comando confronta tutto con i file ufficiali e segnala quelli che non dovrebbero esistere, per esempio i file PHP infilati nella cartella principale. Elimina a mano quelli segnalati dopo averli ispezionati.

Plugin e temi

Questa è la parte dove si nasconde più spesso il problema. Prima guarda cosa è installato:

wp plugin list --allow-root
wp theme list --allow-root

Disattiva ed elimina tutto ciò che non usi. Un plugin disattivato ma presente resta sfruttabile. Per quelli che servono, reinstalla la versione pulita e aggiornata:

wp plugin install nome-plugin --force --allow-root
wp plugin verify-checksums --all --allow-root

Il comando funziona per i plugin del repository ufficiale. Per quelli a pagamento devi scaricare di nuovo il pacchetto dal sito dell’autore e sostituire la cartella. Con i temi vale lo stesso. Se usi un tema figlio, apri a mano il file functions.php e cerca righe che non ricordi, in particolare codice lungo, illeggibile, oppure funzioni che caricano contenuti da altri indirizzi.

Cercare ciò che non dovrebbe esserci

Nelle cartelle di contenuto un attaccante nasconde i file in posti dove pochi guardano. Fai questi controlli uno per volta:

# PHP nella cartella uploads
find wp-content/uploads -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.phar" \)

# file PHP nascosti, che iniziano con un punto
find . -type f -name ".*.php"

# plugin obbligatori e drop-in, di solito quasi vuoti
ls -la wp-content/mu-plugins wp-content/*.php

# regole .htaccess aggiunte, anche nelle sottocartelle
find . -name ".htaccess" -exec echo "--- {}" \; -exec cat {} \;

I file advanced-cache.php, object-cache.php e db.php in wp-content sono legittimi solo se hai installato un plugin di cache che li richiede. Se non è il tuo caso, sono sospetti. Nel file .htaccess guarda soprattutto le regole di reindirizzamento: quelle che mandano i visitatori da Google su altri siti sono un classico.

Per trovare il codice tipico delle webshell in tutto il sito:

grep -RInE --include=*.php \
  "(eval|assert|system|shell_exec|passthru)\s*\(\s*(base64_decode|gzinflate|str_rot13|\\\$_(GET|POST|REQUEST|COOKIE))" .

Controlla ogni risultato nel contesto, perché qualche plugin legittimo usa funzioni simili. Cancella il file solo quando sei sicuro che sia estraneo.

Il database

Il malware non vive solo nei file. Può aver aggiunto script dentro gli articoli, modificato gli indirizzi del sito o inserito codice nelle opzioni. Il prefisso delle tabelle dipende dalla tua installazione, quindi usa quello restituito da WP-CLI:

PREFIX=$(wp db prefix --allow-root)

wp option get siteurl --allow-root
wp option get home --allow-root

wp db query "SELECT ID, post_title FROM ${PREFIX}posts WHERE post_content LIKE '%<script%' OR post_content LIKE '%<iframe%' LIMIT 50;" --allow-root

wp db query "SELECT option_name FROM ${PREFIX}options WHERE option_value LIKE '%base64_decode%' OR option_value LIKE '%eval(%' LIMIT 50;" --allow-root

wp cron event list --allow-root

Gli indirizzi siteurl e home devono essere esattamente il tuo dominio. Negli articoli, gli <script> possono essere legittimi se li hai inseriti tu (per esempio per statistiche o incorporamenti), ma quelli che non riconosci vanno rimossi. Nell’elenco delle attività pianificate cerca eventi con nomi casuali o che richiamano funzioni strane: sono un modo comune per far riscaricare il malware dopo la pulizia.

Controllare anche il server

Un’infezione di WordPress può essere solo la parte visibile di una compromissione più ampia. Verifica che non ci siano cron job sconosciuti, utenti di sistema nuovi, chiavi SSH aggiunte o processi strani, come descritto nella guida su come verificare da terminale se il server è stato infettato. Se l’attaccante aveva accesso al sistema e non solo al sito, la pulizia dei file di WordPress non basta.

Leggi anche: Server infettato dopo PHP2Shell? I comandi da terminale per scoprirlo subito

Controlla anche che PHP sia alla versione corretta. Se la falla è stata sfruttata attraverso PHP stesso, rimettere a posto WordPress senza aggiornare il linguaggio vuol dire lasciare la porta com’era. La procedura sicura per farlo, con snapshot e ritorno alla versione precedente, è nella guida all’aggiornamento di lsphp su OpenLiteSpeed.

Permessi e riavvio

Dopo la pulizia rimetti permessi sensati e riavvia i servizi, così nessun processo carica ancora codice vecchio:

sudo find . -type d -exec chmod 755 {} \;
sudo find . -type f -exec chmod 644 {} \;
sudo chmod 640 wp-config.php
sudo /usr/local/lsws/bin/lswsctrl restart
wp cache flush --allow-root

Svuota anche la cache del plugin che usi, per esempio LiteSpeed Cache, perché potrebbe aver salvato pagine infette.

Quando conviene ripartire da zero

Se hai trovato più di una webshell, se non capisci da dove sono entrati, o se l’attaccante aveva accesso al server e non solo al sito, la pulizia manuale è una scommessa. In quei casi la strada più sicura è creare un VPS nuovo, installare WordPress pulito e importare solo i contenuti: database controllato e cartella uploads verificata, senza copiare plugin, temi o file di configurazione dal vecchio server. Ci vuole più tempo, ma ti lascia la certezza di non portarti dietro niente.

Leggi anche: Fail2ban su VPS Ubuntu: come proteggere SSH e WordPress dagli attacchi brute force

Anche il ripristino da backup è una buona opzione, a una condizione: il backup deve essere precedente all’intrusione. Se ripristini una copia già infetta, hai solo perso tempo.

Dopo la pulizia

Il lavoro non finisce quando il sito torna online. Entra in Google Search Console e guarda la sezione sicurezza: se Google ha segnalato il sito come compromesso, dopo la pulizia puoi chiedere un riesame. Nei giorni seguenti controlla i log per nuovi file in uploads, nuovi utenti amministratori e richieste sospette. Ripeti la ricerca dei file modificati dopo tre o quattro giorni, perché le reinfezioni compaiono quasi sempre in quella finestra.

Infine chiudi la porta che era aperta. Se il plugin vulnerabile è stato sostituito, il problema è risolto in quel punto. Per ridurre i danni futuri, blocca l’esecuzione di PHP nella cartella uploads, tieni aggiornato tutto e, come spiegato nella guida ai comandi per wp-config.php, disattiva la modifica dei file dalla dashboard. Un sito pulito ma lasciato com’era prima torna infetto nel giro di poco.

Altro per te

PHP
PHP Compatibility Checker
Controlla il tuo plugin WordPress prima di aggiornare PHP Verifica la compatibilità con PHP 8.0–8.5 Scopri eventuali problemi nel codice PHP Analizza il tuo plugin WordPress online Preparati a PHP 8.5
Verifica ora →
PDF Strumenti PDF gratis Nel browser, senza upload Apri gli strumenti

🔒

Contenuto riservato

Per scaricare questo file devi prima registrarti oppure accedere con il tuo account.

XWhatsAppTelegram