Una webshell è uno degli strumenti più pericolosi che un attaccante può installare sul tuo sito — e uno dei più difficili da rilevare.
Non è un virus nel senso tradizionale del termine. Non rallenta il sito, non mostra messaggi, non cripta i file. Una webshell siede silenziosamente sul server, invisibile agli utenti e spesso ai plugin di sicurezza, aspettando che l'attaccante decida di usarla.
Questo articolo spiega cosa è una webshell tecnicamente, come viene installata, come viene nascosta, e cosa serve architetturalmente per bloccarla prima che arrivi sul server.
Cos'è una webshell tecnicamente
Una webshell è un file — tipicamente PHP, ma anche ASP, JSP o Python — caricato sul server di un sito web che permette all'attaccante di eseguire comandi sul sistema operativo sottostante attraverso il browser.
In pratica: l'attaccante apre il browser, naviga all'URL del file webshell installato (ad esempio https://tuosito.it/uploads/immagine.php), e ottiene un'interfaccia da cui può eseguire comandi sul server come se avesse accesso diretto alla riga di comando. Può leggere file, modificarli, esfiltrare dati, installare altri strumenti, creare account amministratore, usare il server come relay per attaccare altri sistemi.
La webshell più semplice possibile in PHP è letteralmente una riga:
<?php system($_GET['cmd']); ?>Questo file, se caricato sul server e raggiungibile via browser, permette di eseguire qualsiasi comando del sistema operativo passandolo come parametro URL. Le webshell reali sono molto più sofisticate — interfacce complete con gestione file, accesso al database, reverse shell, tutto offuscato per evitare il rilevamento.
Come viene installata una webshell
Una webshell non si installa da sola. Richiede che l'attaccante abbia già trovato un punto di ingresso nel sistema. I vettori più comuni sono tre.
Upload di file senza validazione adeguata
Il vettore più frequente su WordPress è il caricamento di file attraverso form o aree di upload che non validano correttamente il contenuto. Un plugin che controlla solo l'estensione del file — verificando che si chiami .jpg invece di .php — può essere ingannato con un file che ha estensione apparentemente innocua ma contiene codice PHP nel corpo.
La tecnica più sofisticata è il file polyglot: un file che ha magic bytes validi (i primi byte che identificano il formato — nel caso di JPEG iniziano con FF D8 FF) ma contiene codice PHP embedded nel resto del contenuto. Il browser lo interpreta come immagine, il server lo esegue come PHP se la configurazione lo permette.
SQL injection con file write
Se un attacco SQL injection ha successo e il database ha permessi di scrittura sul filesystem, l'attaccante può usare la funzione SELECT INTO OUTFILE di MySQL per scrivere direttamente un file PHP sul server. Non serve nemmeno un form di upload — basta una query SQL malevola non bloccata.
Vulnerabilità in plugin o temi
Plugin WordPress con Remote Code Execution (RCE) o Local File Inclusion (LFI) non patchati permettono all'attaccante di caricare o eseguire codice arbitrario sul server. Le vulnerabilità di questo tipo vengono scoperte e pubblicate regolarmente — e tra il momento della pubblicazione e il momento in cui l'amministratore aggiorna il plugin, il sito è esposto.
Come viene nascosta
Un attaccante competente non lascia la webshell in una posizione ovvia. Le tecniche di occultamento più diffuse sono quelle che rendono il rilevamento difficile anche per chi sa cosa cercare.
Offuscamento del codice
Il codice della webshell viene codificato in Base64, frammentato in variabili multiple, concatenato con funzioni di stringa, o compresso — in modo che il file non contenga stringhe riconoscibili come system, exec o passthru. Un antivirus o scanner che cerca queste stringhe non trova nulla.
Esempio di offuscamento base:
<?php
$a = base64_decode('c3lzdGVt');
$a($_GET['c']);
?>Il codice decodificato esegue system($_GET['c']) — ma nessuna delle stringhe pericolose appare in chiaro nel file.
Estensioni e nomi file ingannevoli
La webshell viene rinominata con nomi che sembrano innocui: config.php, cache.php, wp-options.php, thumb.php. In un'installazione WordPress con centinaia di file PHP distribuiti in decine di cartelle, un file in più è praticamente invisibile senza una scansione sistematica.
Timestamp falsificati
Gli attaccanti modificano il timestamp del file webshell per farlo sembrare un file preesistente — la data di modifica appare identica agli altri file della stessa cartella. Chi controlla la data di modifica per identificare file aggiunti di recente non trova anomalie.
Iframe e injection nei file esistenti
Invece di creare un nuovo file, l'attaccante può iniettare il codice webshell all'interno di file PHP già esistenti — modificando functions.php, index.php o qualsiasi file già presente. Il file risultante è legittimo nella struttura ma contiene codice aggiuntivo nascosto in fondo o frammentato nel corpo.
Perché i plugin di sicurezza WordPress non bastano
Wordfence e simili fanno scansione dei file cercando firme note di webshell. Questo approccio ha limiti strutturali che è importante capire.
Le firme vengono aggiornate dopo la scoperta di nuove webshell — non prima. Una webshell nuova o sufficientemente offuscata non corrisponde a nessuna firma nel database e non viene rilevata. Wordfence free riceve gli aggiornamenti delle firme con 30 giorni di ritardo rispetto alla versione premium — finestra durante la quale le nuove webshell non vengono identificate.
Inoltre, la scansione avviene dopo che il file è già sul server. Il problema non è rilevare la webshell una volta installata — è bloccarla prima che arrivi. Una scansione periodica che trova la webshell tre giorni dopo l'installazione significa tre giorni di accesso aperto al server.
La soluzione architettural corretta è bloccare il caricamento di file malevoli al momento dell'upload — non scansionare il filesystem cercando quello che è già passato.
Come bloccare una webshell prima che arrivi sul server
Il blocco efficace richiede analisi del contenuto del file al momento dell'upload, non solo dell'estensione o del nome. Le sei verifiche che separano un sistema di upload sicuro da uno vulnerabile sono quelle che KeideaCMS applica nativamente su ogni file caricato.
1. Validazione del nome file
Null bytes, doppie estensioni (shell.php.jpg), caratteri di controllo, e 80+ estensioni pericolose bloccate: non solo .php, ma anche .phtml, .phar, .php5, .pht, .shtml e tutte le varianti che PHP può eseguire.
2. Rilevamento codice PHP nel contenuto
Analisi binaria del contenuto del file cercando tag PHP (<?php, short tag <?, ASP tag <%) e funzioni pericolose (eval, system, exec, passthru, base64_decode) nei file che non dovrebbero contenerli. Un file .jpg che contiene <?php viene bloccato indipendentemente dall'estensione.
3. Firme webshell note
Database di firme delle webshell più diffuse: c99, r57, b374k, WSO, FilesMan, Alfa Shell, AnonymousFox, p0wny, weevely e altre 15+. Il file viene confrontato con queste firme prima dell'accettazione.
4. Analisi entropia Shannon
Il codice offuscato ha un'entropia statisticamente anomala rispetto a un file legittimo dello stesso tipo. L'analisi dell'entropia di Shannon — con soglia a 7.2 su scala 8.0 — identifica file con distribuzione di byte sospetta, tipica del codice compresso o criptato nascosto nel contenuto.
5. Decodifica payload Base64
I blocchi Base64 embedded nel contenuto del file vengono cercati e decodificati ricorsivamente. Un payload offuscato a livelli multipli — Base64 dentro Base64 dentro un file immagine — viene smascherato prima che il file venga accettato.
6. Rilevamento file polyglot
Verifica che i magic bytes del file corrispondano al formato dichiarato e che il contenuto binario non contenga codice PHP embedded dopo l'header legittimo. È la verifica più sofisticata — e quella che blocca la tecnica di attacco più difficile da rilevare.
Queste sei verifiche sono integrate nel core di KeideaCMS — non sono un plugin aggiuntivo che qualcuno deve ricordarsi di aggiornare. L'architettura completa di sicurezza di KeideaCMS, incluso il sistema di scansione file, è documentata qui.
Cosa fare se sospetti una webshell già installata
Se il sito ha subito accessi anomali, se trovi file PHP in cartelle dove non dovrebbero esserci, se il server consuma risorse inspiegabilmente, o se Google ha segnalato contenuti insoliti nelle pagine indicizzate — la priorità è contenimento, non diagnosi.
I passi immediati: isola il sito mettendolo offline o limitando l'accesso per IP, fai un backup completo dello stato attuale (incluso il sito compromesso — serve per l'analisi forense), e confronta il filesystem con un backup precedente alla compromissione cercando file aggiunti o modificati. Non fidarti dei timestamp — usa hash MD5 o SHA-256 per confrontare i file.
Se il sito gestisce dati personali — e quasi tutti i siti aziendali lo fanno — una compromissione che ha permesso accesso al database o ai file è una violazione GDPR con obbligo di notifica al Garante entro 72 ore. Abbiamo scritto una guida approfondita su WAF e protezione strutturale che spiega perché la prevenzione è l'unica risposta efficace.