Vai al contenuto principale

Quando il server si infetta: cronaca di una messa in sicurezza

cronaca di una messa in sicurezza

Il 22 ottobre 2026 un antivirus ha segnalato file sospetti su molti siti ospitati su diversi stesso server. Quel server lo gestisco con il marchio jackalope.it: circa sessanta siti, clienti diversi, un pannello di hosting, tecnologie miste. Nei giorni seguenti ho lavorato un comando alla volta, con l’aiuto di un assistente di intelligenza artificiale che leggeva i risultati e proponeva i passi. I comandi li ho sempre eseguiti io.

Racconto cosa abbiamo trovato, cosa abbiamo fatto e, soprattutto, cosa ancora non so.

Come ce ne siamo accorti

Non è partito un allarme unico. Nella stessa giornata l’antivirus ha segnalato anomalie in siti diversi: pagine PHP con nomi esadecimali nelle cartelle delle immagini, file di configurazione del server web duplicati in decine di cartelle, cartelle annidate dentro cartelle uguali. Un solo sito infetto sarebbe stato un incidente. Molti siti con le stesse firme nello stesso giorno erano una campagna.

Cosa abbiamo trovato

L’ingresso più probabile è una vulnerabilità recente (CVE-2026-102785): permetteva di eseguire codice senza autenticarsi, appena ieri. I log mostrano lo schema: una richiesta che indica l’indirizzo di un file da scaricare, un errore e, due o dodici secondi dopo, una pagina PHP appena comparsa nella cartella delle immagini che risponde senza problemi. Poi le sessioni di comandi: circa sei richieste in dieci o quindici secondi, tipiche di uno script. Anche il sito di jackalope.it è stato toccato, ma l'infezione è stata contenuta e nulla è trapelato.

Tre episodi collaterali raccontano meglio dell’attacco cosa significa gestire una rete di server:

  1. Un sito già ripulito a luglio mostrava la stessa firma: la campagna era quasi certamente attiva da allora, ma era rimasta silente e nessun sistema di difesa se n'era accorto.
  2. Un negozio online, il 18 ottobre, aveva un file PHP camuffato da robots.php e una copia di jQuery gonfiata a oltre un megabyte con codice offuscato: probabilmente un intercettatore dei dati di pagamento, in una campagna diversa. Nei giorni di attività il negozio non ha sviluppato ordini altrimenti il sistema di difesa ci avrebbe avvertito.
  3. Tra le chiavi di accesso remoto autorizzate ce n’era una sconosciuta. L’ho rimossa per prudenza, senza trovare accessi da indirizzi esterni: può essere di un tecnico del fornitore, non l’ho dimostrato, ma era un dubbio: meglio rimuoverlo.

Sul pannello, in due mesi, oltre diecimila tentativi di accesso falliti, quasi tutti contro l’utente amministratore. Il blocco automatico funzionava bene, ma i tentativi lenti restavano sotto soglia.

La stessa campagna, altrove

Le stesse firme (un file di regole da pochi byte, con lo stesso contenuto in decine di cartelle, e le stesse cartelle annidate) le ho ritrovate su altri server che seguo. Nei due enti professionali nazionali, in particolare, il problema era partito da una serie di siti territoriali non presidiati, tutti sotto un unico utente di sistema: un sito infetto ha reso raggiungibili gli altri. L’ingresso preciso  è stato identificato e segnalato alle autorità. Il blocco urgente (quarantena, aggiornamenti, cambio delle credenziali critiche) l’ho chiuso in circa mezza giornata di lavoro, ma restavano punti aperti che elencherò nel paragrafo dei limiti. Un terzo server, di un ente ecclesiastico, aveva un’esposizione simile, ma li è stato semplice: nessun segno di intrusione, aggiornamenti applicati subito.

Nelle stesse ore, il caso PHP

Il 21 ottobre, mentre nei log comparivano le prime richieste sospette, un’altra notizia occupava le aperture. Due vulnerabilità critiche nel cuore di PHP (CVE-2026-109618 e CVE-2026-109619, battezzate PHP2Shell) permettevano di eseguire codice su un server senza alcuna credenziale. Per precauzione, in vari Paesi europei siti di ministeri e prefetture sono stati messi offline in attesa della correzione, uscita lo stesso giorno nelle versioni 8.2.35, 8.3.36, 8.4.27 e 8.5.12. I blackout sono stati in gran parte preventivi, ma i fornitori di sicurezza hanno segnalato anche tentativi di sfruttamento reali.

Nei miei log ho la prova che PHP2Shell è stata usata per tentare un ingresso ed una escalation. Dalla sera del 22 ottobre tutti i miei siti girano su PHP 8.5, il ramo con la correzione, uno solo gestito in autonomia da un cliente, aveva permesso l'infiltrazione. La lezione resta: tra l’annuncio di una falla e il suo sfruttamento passano ormai poche ore, non settimane come una volta.

Cosa abbiamo fatto

L’ordine conta: prima leggere, poi conservare le prove, poi mettere in quarantena (mai cancellare subito), poi cambiare le credenziali, poi aggiornare.

Per ogni sito: password del database cambiata e file di configurazione riallineato, chiavi di sicurezza rigenerate (così le sessioni rubate non valgono più), amministratori verificati, permessi dei file ristretti. Sul pannello: autenticazione a due fattori. Sul server: accesso remoto solo con chiave, trasferimento file FTP disattivato perché nessuno lo usava, soglie del blocco automatico allargate. L’antivirus ora avvisa subito via email ed SMS e fa la scansione completa ogni 2 ore. Ovviamente è stato necessario potenziare le infrastrutture per reggere a questa serie di elaborazioni.

Poi la pulizia: ventotto database dormienti archiviati e rimossi, i backup completi cancellati dal server dopo averne una copia fuori, il sistema di ticket aggiornato all’ultima versione. Ogni modifica con backup, comando di ritorno e verifica che i siti rispondessero come prima.

Cosa ancora non so

È la parte più importante, e non la tolgo per far suonare meglio il titolo, perché non sarebbe onesto. Non conosco bene l’ingresso in alcuni siti: la falla del tema è la causa più probabile, ma non una causa dimostrata. Diversi plugin di WordPress a pagamento non offrono un controllo d’integrità, quindi la loro pulizia si basa su ricerche di indicatori, che sono un controllo debole. Il 23 ottobre molti file sono stati riscritti in blocco, da un autore che non so identificare, presumo sia un aggiornamento automatico, ma sto ancora indagando. Alcuni accessi al pannello hanno risposto in modo che non distingue un login riuscito da uno fallito. Un indirizzo ha contattato un sito ogni giorno per mesi, da ottobre 2025 a gennaio 2026, poi più nulla: può essere un impianto più vecchio e non posso escluderlo. Infine il cambio delle credenziali di sistema è in mano al gestore della macchina virtuale, e finché non arriva una risposta da loro considero quella parte aperta.

Per questo scrivo “messo in sicurezza, con limiti dichiarati”. Non scrivo “pulito”.

Due intelligenze artificiali, due ruoli

Le falle di PHP erano rimaste nascoste per oltre dieci anni e sono state trovate con l’aiuto dell’intelligenza artificiale malevola, dalla parte degli attaccanti. Chi ha fatto la scoperta scrive che questi strumenti abbassano molto il costo di trasformare una falla vecchia in un attacco funzionante, e questo vale soprattutto per chi attacca. Non so se dietro le sessioni a script dei miei log ci fosse una persona, un programma o un’IA: lo schema dice automazione, nient’altro.

Dall’altra parte, io ho usato un assistente AI per leggere e incrociare log e file di decine di siti: milioni di righe di codice... un lavoro che a mano mi avrebbe richiesto molto più tempo. Non dico che l'AI abbia fermato l’infezione, quell' è stato fatto da esseri umani che hanno interpretato i dati, ma di sicuro ha accelerato la lettura, non ha sostituito il giudizio. la nostra AI sbagliava, e ho scoperto ogni errore perché i comandi li eseguivo io e controllavo i risultati. La velocità conta da entrambe le parti: chi non aggiorna regala all’avversario il vantaggio più grande.

Cosa ho imparato sul metodo

Un output vuoto non è un esito. Un filtro cercava dati nel formato sbagliato e non trovava nulla: sembrava un controllo superato, era un controllo mal scritto. Prima di fidarmi di un vuoto verifico che il filtro sia adatto ai dati e conto le righe.

Un hash uguale non prova una colpa. Un file sospetto, identico in centinaia di cartelle, era anche la regola standard di un noto programma per blog. Conta il contesto: data, cartella, chi l’ha scritto.

Prima si legge, poi si ripulisce. Chi era intervenuto prima di noi aveva cancellato i campioni dei file malevoli, ripulendo le proprie tracce: restano gli hash, non le prove. Da allora ogni cancellazione ha un’anteprima con il numero atteso di file, e se il numero non coincide il comando non fa nulla.

Una modifica alla volta, con backup, ritorno e verifica prima e dopo. E gli errori vanno scritti, soprattutto quelli dell’assistente: segnaposto lasciati nei comandi, test dopo una modifica presentati come validi senza accertare che il file fosse cambiato, un negozio attribuito al cliente sbagliato. Li annotavamo in un documento di passaggio, aggiornato a ogni sessione.

Se non aggiornate, siete il bersaglio più facile

Il filo comune di tutti questi casi è lo stesso: componenti non aggiornati, con falle già note, in sistemi dove nessuno guarda. Tre regole pratiche:

  1. Aggiornate subito tema, plugin e PHP, e controllate la versione reale in uso, non quella che pensate di avere.
  2. Un utente di sistema per ogni sito: il primo infetto non deve poter toccare gli altri.
  3. Tenete un posto fuori dal server dove log e prove sopravvivono all’incidente.

La messa in sicurezza continua: restano le credenziali di sistema, alcuni siti da ripassare e i punti aperti elencati sopra.

Per questo non scrivo «pulito». Un sistema non è forte perché nessuno lo attacca, ma perché lo attaccano e resiste. Il mio sta ancora sostenendo l’esame, e ogni giorno senza una nuova scoperta è un voto, non un diploma.