2026-07-01 · Team Fenrir
Come riconoscere una web-shell in un sito WordPress
Una web-shell è la risposta più breve alla domanda “come è tornato dentro?”. Non è l’attacco iniziale: è ciò che l’attaccante lascia dopo, per rientrare a piacimento. Su WordPress prende quasi sempre la forma di un file PHP nascosto tra i tuoi. Riconoscerla richiede tre cose: sapere dove guardare, con quali comandi, e cosa cercare nei log. Questa guida copre tutte e tre.
Che cos’è esattamente una web-shell?
È uno script caricato sul server che espone un’interfaccia di comando via HTTP: l’attaccante apre un URL (o manda una POST) e il server esegue quello che gli viene chiesto — leggere file, scrivere altro codice, lanciare processi. OWASP la classifica tra le conseguenze dirette dell’upload di file non filtrato: se un’applicazione permette di caricare un file e quel file può essere eseguito lato server, il risultato è l’esecuzione di codice arbitrario. MITRE ATT&CK la cataloga come T1505.003 (Server Software Component: Web Shell), una tecnica di persistenza: il suo scopo è sopravvivere alla scoperta dell’attacco iniziale.
La differenza pratica rispetto ad altri malware: la web-shell non “fa” niente da sola. Sta ferma, invisibile, finché l’attaccante non la richiama. Per questo i sintomi classici (sito lento, redirect strani, spam) spesso mancano del tutto.
Dove si nasconde in WordPress?
Le web-shell finiscono dove il codice non dovrebbe esserci, o dove nessuno guarda:
wp-content/uploads/— la directory dei media. Dovrebbe contenere immagini e documenti, mai PHP. È il nascondiglio più comune perché è sempre scrivibile dal web server.- Dentro un plugin o un tema legittimo — un file aggiunto (
helper.php,class-cache.php) o poche righe iniettate in coda a un file vero. Il plugin funziona normalmente, quindi nessuno se ne accorge. wp-content/mu-plugins/— i “must-use plugins” si caricano automaticamente e non compaiono nella lista dei plugin attivabili. Pochi sanno che questa directory esiste: perfetta per una backdoor.- Nomi che imitano il core —
wp-conf.php,wp-sett.php,wp-cache.phpnella root o inwp-includes/. A colpo d’occhio sembrano file di WordPress; non lo sono.
Quali segnali la tradiscono?
Quattro indicatori concreti, in ordine di affidabilità:
- File PHP dove non dovrebbero esistere. Un
.phpinuploads/è sospetto per definizione. - Codice offuscato.
eval(,base64_decode(,gzinflate(,str_rot13(concatenati tra loro sono la firma classica: il payload è cifrato per eludere le scansioni, e viene decodificato ed eseguito al volo. - File del core o dei plugin che non combaciano coi checksum ufficiali. È il controllo più affidabile: non guarda come è scritto il codice, ma se è quello distribuito da WordPress.org.
- Timestamp incoerenti. Un file “core” modificato dopo l’ultimo aggiornamento è un’anomalia. Attenzione però: gli attaccanti sanno falsificare le date (
touch), quindi un timestamp pulito non prova l’innocenza — uno sporco è solo un indizio in più.
Come la cerco dalla riga di comando?
Quattro comandi, dal più semplice al più affidabile:
# 1. PHP nella directory dei media: non dovrebbe esserci nulla
find wp-content/uploads -name '*.php'
# 2. Pattern di offuscamento nei file del sito
grep -rEl "eval\(|base64_decode\(|gzinflate\(" wp-content/
# 3. Integrità del core contro i checksum ufficiali di WordPress.org
wp core verify-checksums
# 4. Integrità dei plugin (solo quelli del repository ufficiale)
wp plugin verify-checksums --all
Il comando 3 è il più prezioso: wp core verify-checksums confronta ogni file del core con i checksum pubblicati da WordPress.org e segnala sia i file modificati sia quelli estranei che non dovrebbero esistere. Il comando 2 produce falsi positivi (alcuni plugin legittimi usano base64_decode): usalo come lista di candidati da esaminare, non come verdetto.
Cosa cercare nei log del web server?
La web-shell si usa via HTTP, quindi lascia tracce negli access log. MITRE indica proprio il monitoraggio dei log e dei file tra i metodi di rilevamento della tecnica. I pattern tipici:
- POST ripetute verso un singolo file PHP che non è un endpoint noto (
admin-ajax.phpewp-cron.phpricevono POST legittime;wp-content/uploads/2026/01/img.phpno). - Richieste con parametri lunghi e illeggibili — spesso il comando da eseguire, codificato base64.
- Un solo IP che chiama sempre lo stesso file, a orari anomali, senza referrer e senza mai toccare il resto del sito: un visitatore vero naviga, una backdoor no.
- Risposte 200 su URL che non riconosci. Se un file PHP che non hai mai installato risponde 200, il problema è confermato.
Un grep utile come punto di partenza:
grep 'POST' access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20
Se in cima alla lista c’è un file che non riconosci, hai trovato il filo da tirare.
Come la rimuovo senza distruggere le prove?
L’istinto dice “cancella subito”. Resisti: la web-shell è il punto di rientro, non la causa. Se la elimini senza capire da dove è entrato l’attaccante, la ritroverai domani.
Nell’ordine:
- Conserva le prove — copia il file sospetto e le righe di log che lo riguardano fuori dal server (ti servono per ricostruire il punto d’ingresso, e in caso di obblighi di notifica).
- Ricostruisci l’ingresso — la prima richiesta verso quel file nei log, e cosa è successo subito prima: un upload? un login? l’exploit di un plugin?
- Chiudi la falla — aggiorna o rimuovi il componente vulnerabile, ruota tutte le credenziali (admin WordPress, database, FTP/SSH), invalida le sessioni.
- Solo ora rimuovi — elimina la web-shell e ripristina i file modificati da sorgenti pulite (i checksum del punto precedente ti dicono esattamente quali).
- Ri-verifica —
wp core verify-checksumspulito, log sotto osservazione per i giorni successivi: se l’attaccante aveva una seconda backdoor, la userà.
Come impedisco che torni?
La guida ufficiale di hardening di WordPress converge su pochi punti ad alto rendimento:
- Blocca l’esecuzione PHP in
uploads/— la contromisura singola più efficace: anche se un PHP viene caricato, il web server si rifiuta di eseguirlo. Su nginx:location ~* /uploads/.*\.php$ { return 403; }. - Aggiorna core, plugin e temi — la maggior parte delle compromissioni WordPress passa da componenti vulnerabili noti e già corretti.
- Meno componenti, meno superficie — ogni plugin disattivato-ma-installato è codice attaccabile che non ti serve: rimuovilo.
- Permessi minimi — i file non devono essere scrivibili dal web server dove non serve; niente
777. - Verifica d’integrità ricorrente —
wp core verify-checksumsin cron è un rilevatore di web-shell quasi gratuito.
Perché serve il monitoraggio continuo?
Tutto quanto sopra ha un limite strutturale: è manuale e puntuale. Una web-shell trovata col grep del sabato mattina è una web-shell che ha avuto una settimana di vantaggio. Il punto non è il singolo comando, ma avere qualcosa che osserva in continuo file e log e ti avvisa quando compare un PHP dove non dovrebbe, quando un file del core cambia checksum, quando un IP inizia a martellare un endpoint che non esiste.
È esattamente ciò che fa Fenrir SOC sui server e Fenrir per WordPress sui siti: integrità dei file, correlazione dei log e una risposta che scatta prima che tu apra il terminale. Tu dormi, il sito si difende da solo — e la web-shell la leggi nel report del mattino, già bloccata.
Domande frequenti
Che cos'è una web-shell?▾
Uno script (su WordPress quasi sempre PHP) caricato dall'attaccante per eseguire comandi sul server da remoto, tipicamente via richieste HTTP. È una backdoor persistente: MITRE ATT&CK la cataloga come tecnica di persistenza T1505.003.
Un antivirus basta a trovarla?▾
Non sempre: le web-shell offuscate eludono le firme. Servono anche controlli comportamentali sui file (integrità contro i checksum ufficiali, timestamp) e l'analisi dei log di accesso del web server.
Come verifico se un file del core di WordPress è stato modificato?▾
Con WP-CLI: `wp core verify-checksums` confronta ogni file del core con i checksum ufficiali di WordPress.org e elenca file modificati o estranei. Per i plugin del repository ufficiale esiste `wp plugin verify-checksums`.
Basta cancellare il file della web-shell?▾
No. La web-shell è il punto di rientro, non la causa: se non trovi e chiudi la falla d'ingresso (plugin vulnerabile, credenziali rubate, upload non filtrato), l'attaccante la ricrea. Prima di cancellare, conserva file e log come prova.