Credenziali FTP rubate dal PC dello sviluppatore: quando l’infezione arriva dal client

Infostealer, FileZilla e password salvate: come i log FTP rivelano un accesso rubato e in che ordine ruotare le credenziali prima di ripulire il sito.

Una finestra di editor con il file sitemanager.xml di FileZilla, in cui la riga della password codificata in base64 è evidenziata in rosso, collegata da una freccia tratteggiata gialla a un server FTP che registra un login riuscito da un indirizzo sconosciuto

Il sito viene ripulito, le backdoor rimosse, i plugin aggiornati. Dopo tre giorni ricompare un file PHP nella cartella del tema, con la data di modifica di quella notte. Nessuna vulnerabilità nota, nessun plugin sospetto, nessuna richiesta anomala negli access log prima della comparsa del file. In casi come questo la domanda giusta non è «da quale buco del sito sono entrati», ma «chi aveva le chiavi»: spesso l’attaccante non ha forzato nulla, ha semplicemente usato le credenziali FTP rubate dal computer di chi il sito lo gestisce.

Quando le credenziali escono da un PC infetto, cambiarle da quello stesso PC significa consegnarle di nuovo all’attaccante.

In questo articolo vediamo come gli infostealer raccolgono le credenziali salvate nei client FTP, nei browser e nelle chiavi SSH, come i log del server FTP permettono di riconoscere un accesso con credenziali valide ma da un indirizzo sconosciuto, perché la sola bonifica del sito non basta e in che ordine rimettere in sicurezza client, credenziali e server.

Un’infezione che non parte dal sito

Nella maggior parte delle compromissioni di WordPress il punto d’ingresso è applicativo: un plugin vulnerabile, un modulo di upload senza controlli, una password di amministratore debole. Esiste però una categoria di casi in cui il sito, dal punto di vista del codice, era in ordine. L’attaccante è entrato dalla porta principale, con nome utente e password corretti, attraverso lo stesso canale che usa lo sviluppatore per pubblicare le modifiche: FTP, SFTP o SSH.

Il sintomo tipico è la reinfezione senza spiegazione. Il sito viene ripulito, magari anche con cura, e dopo qualche giorno riappaiono file nuovi, spesso in più installazioni gestite dalla stessa persona o dalla stessa agenzia. Un indizio forte è proprio questo: se si infettano contemporaneamente siti su hosting diversi, con CMS diversi, che hanno in comune solo chi li amministra, il fattore comune da indagare è il computer di quella persona.

Negli access log, in questi casi, manca il passaggio atteso: nessuna richiesta POST verso un file vulnerabile prima della comparsa della backdoor. Come visto nell’articolo su come leggere gli access log, la prima richiesta alla webshell arriva senza che nulla l’abbia creata via HTTP: il file è arrivato da un altro canale, che ha i suoi log.

Cosa rubano gli infostealer dal PC di chi gestisce i siti

Gli infostealer sono malware per desktop, quasi sempre Windows, che raccolgono in pochi secondi tutto ciò che sul computer ha valore e lo spediscono all’attaccante. Arrivano con software craccato, falsi aggiornamenti, allegati di posta o annunci che imitano programmi legittimi, e spesso si cancellano subito dopo la raccolta.

Per chi gestisce siti web, il bottino è particolarmente ricco. Le analisi tecniche di famiglie diffuse come RedLine elencano in modo esplicito, accanto a password e cookie dei browser, i file di configurazione del client FTP: l’analisi di CloudSEK descrive come il malware cerchi sitemanager.xml e recentservers.xml di FileZilla nella cartella AppData. In concreto, un infostealer sul PC di uno sviluppatore può portare via:

  • i siti salvati nel client FTP, con host, porta, utente e password di ciascuno;
  • le password memorizzate nel browser, tra cui quelle del pannello di hosting, di wp-admin e di phpMyAdmin;
  • i cookie di sessione, che permettono di entrare in un pannello già autenticato senza conoscere la password e senza passare dall’autenticazione a due fattori;
  • le chiavi SSH private in ~/.ssh o nei file di PuTTY, utilizzabili subito se non sono protette da passphrase;
  • i file di progetto sul desktop o nei repository locali: wp-config.php, file .env, script di deploy con credenziali scritte dentro.

Questi dati finiscono in archivi venduti o scambiati in blocco. Chi li compra usa strumenti automatici che provano tutte le credenziali FTP, caricano una webshell dove l’accesso riesce e passano oltre. Per questo tra il furto e l’uso possono passare settimane, e l’infezione del sito non coincide con la compromissione del PC.

Schema in quattro fasi del furto di credenziali dal client. Primo: il PC dello sviluppatore viene infettato da un infostealer tramite software craccato, falso aggiornamento o allegato. Secondo: il malware copia sitemanager.xml e recentservers.xml di FileZilla, le password e i cookie del browser e le chiavi SSH, e li invia a un server di raccolta. Terzo: le credenziali, rivendute, vengono provate da un sistema automatico che si collega in FTP al server da un indirizzo IP mai visto. Quarto: con un login valido viene caricato un file PHP nel sito. Una freccia di ritorno rossa ricorda che, se la password viene cambiata dallo stesso PC infetto, il ciclo ricomincia.
Dal PC al sito: il server riceve un login perfettamente valido, e cambiare password dal computer ancora infetto riapre il ciclo.

FileZilla e le password salvate in chiaro

FileZilla è il client FTP più diffuso ed è anche il bersaglio più citato, per una ragione semplice: per molti anni ha salvato le password in file XML leggibili. Il Gestore siti scrive in sitemanager.xml, la cronologia delle connessioni rapide in recentservers.xml; su Windows i due file stanno in %APPDATA%\FileZilla\, su Linux in ~/.config/filezilla/. Senza protezione, la password compare in un elemento <Pass> codificato in base64, che non è una cifratura ma una semplice trasformazione reversibile.

Dalla versione 3.26.0 FileZilla permette di proteggere le password salvate con una password principale, ma come riportava BleepingComputer all’arrivo della funzione l’opzione non è attiva in automatico: va abilitata nelle impostazioni. Per verificare come sono salvate le password sul proprio computer basta guardare il file:

# Linux e macOS: esiste la configurazione del Gestore siti?
ls -l ~/.config/filezilla/sitemanager.xml ~/.config/filezilla/recentservers.xml

# Come sono salvate le password (base64 = leggibili da chiunque legga il file)
grep -o '<Pass encoding="[^"]*"' ~/.config/filezilla/sitemanager.xml | sort | uniq -c

# Windows (PowerShell)
Select-String -Path "$env:APPDATA\FileZilla\sitemanager.xml" -Pattern '<Pass encoding'

Se il risultato mostra encoding="base64", chiunque abbia letto quel file conosce le password. Con la password principale attiva l’attributo cambia e la password è cifrata: un infostealer che copia il file non ottiene le credenziali in chiaro, anche se un malware che registra i tasti premuti resta comunque un problema. E i gestori di password dei browser vengono decifrati dagli stealer direttamente sul computer della vittima, dove le chiavi necessarie sono disponibili.

Cosa raccontano i log FTP

Sul server, la prova di un accesso con credenziali rubate sta nei log del demone FTP o di SSH. Il formato dipende dal software: Pure-FTPd, comune nei pannelli come cPanel, scrive tramite syslog in /var/log/messages o /var/log/syslog; vsftpd usa /var/log/vsftpd.log e, con xferlog_enable=YES, il registro dei trasferimenti /var/log/xferlog; ProFTPD scrive in genere in /var/log/proftpd/proftpd.log e ha un proprio xferlog. Gli accessi SFTP, invece, sono accessi SSH e compaiono in /var/log/auth.log (Debian e Ubuntu) o /var/log/secure (RHEL e derivate).

La prima cosa da fare è elencare gli indirizzi da cui ogni utente FTP si è autenticato, e confrontarli con quelli noti dello sviluppatore, dell’agenzia e del cliente:

# Pure-FTPd: login riusciti, raggruppati per IP e utente
zgrep -h "is now logged in" /var/log/messages* \
  | sed -E 's/.*\(\?@([^)]+)\).* ([^ ]+) is now logged in.*/\1 \2/' \
  | sort | uniq -c | sort -rn

# vsftpd: login riusciti e caricamenti
grep -E "OK LOGIN|OK UPLOAD" /var/log/vsftpd.log

# ProFTPD
grep "Login successful" /var/log/proftpd/proftpd.log

# SFTP e SSH: accessi con password o con chiave
grep -E "Accepted (password|publickey)" /var/log/auth.log /var/log/secure 2>/dev/null

Il registro più utile per la ricostruzione è però xferlog, perché ha un formato standard in cui ogni riga è un trasferimento. I campi, separati da spazi, sono la data (cinque parole), la durata, l’indirizzo remoto, la dimensione, il nome del file, il tipo di trasferimento, un indicatore, la direzione (i per i caricamenti, o per gli scaricamenti), la modalità di accesso, il nome utente e, in fondo, lo stato di completamento. Filtrare i caricamenti di file PHP è quindi immediato:

# Caricamenti (direzione i) di file .php: data, IP, utente, file
awk '$12 == "i" && $9 ~ /\.php$/ {print $1,$2,$3,$4,$5, $7, $14, $9}' /var/log/xferlog

# Tutti i trasferimenti da un indirizzo sospetto
grep " 203.0.113.45 " /var/log/xferlog
Una finestra di terminale mostra tre righe di xferlog. Le prime due sono caricamenti dello sviluppatore da un indirizzo noto, in orario lavorativo, di file CSS e di un template del tema. La terza, evidenziata in rosso, è un caricamento alle 03:12 di notte da un indirizzo mai visto, con lo stesso utente FTP, di un file cache.php nella cartella uploads. Sotto, le etichette spiegano i campi della riga: data e ora, indirizzo remoto, dimensione, percorso del file, direzione i per upload, nome utente e stato c per completato.
Stesso utente, stessa password: a distinguere l’accesso dell’attaccante sono l’indirizzo, l’orario e il tipo di file caricato.

Gli schemi ricorrenti sono riconoscibili: accessi da indirizzi di data center o di reti residenziali in paesi dove nessuno del gruppo lavora, sessioni brevissime che caricano un solo file e si chiudono, caricamenti notturni, e soprattutto lo stesso indirizzo che nello stesso minuto accede a più account FTP diversi sullo stesso server. Quest’ultimo è il segno di uno strumento automatico che sta scorrendo un archivio di credenziali rubate. Se il furto è vecchio, le righe utili possono essere già nei log ruotati e compressi, da leggere con zgrep.

Distinguere un accesso FTP da una vulnerabilità del sito

Il passaggio decisivo è la correlazione tra la data di comparsa del file infetto e i log. Si parte dal file: la sua data di modifica (stat mostra anche la data di cambio dell’inode, più difficile da falsificare) indica una finestra temporale. In quella finestra si cerca, da una parte, una richiesta HTTP che possa averlo creato e, dall’altra, un trasferimento FTP o una sessione SFTP.

# Date del file sospetto (Modify e Change)
stat wp-content/uploads/2026/09/cache.php

# Richieste HTTP nello stesso minuto
grep "14/Sep/2026:03:1[0-4]" /var/log/nginx/access.log

# Trasferimenti FTP nello stesso intervallo
grep "Sep 14 03:1[0-4]" /var/log/xferlog

Se la riga in xferlog c’è e l’access log non mostra nulla di rilevante, il vettore è chiaro. Se invece il file è di proprietà dell’utente del web server e non dell’utente FTP, è molto più probabile che l’abbia scritto un processo PHP, cioè che l’ingresso sia stato applicativo. Le due ipotesi non si escludono: spesso l’attaccante entra via FTP una sola volta, carica una webshell e poi lavora solo via HTTP; i log FTP mostrano l’origine, gli access log tutto il resto.

Perché ripulire solo il sito non basta

Quando il vettore è un furto di credenziali, la bonifica del sito, anche perfetta, lascia intatta la causa. Le credenziali sono ancora in mano a chi le ha comprate, e il ciclo si ripete finché qualcuno non le cambia. E spesso le cambia lo sviluppatore dal proprio PC, salvando la nuova password nel client FTP: se il malware è ancora attivo, la nuova password segue la strada della vecchia.

C’è poi il perimetro. Le credenziali rubate da un singolo computer riguardano quasi sempre molti siti: tutti quelli salvati nel client FTP, tutti i pannelli nel browser. Ripulire il sito che ha dato l’allarme e ignorare gli altri significa rimandare il problema. Su un server condiviso, inoltre, un accesso FTP con un utente che ha permessi su più document root può infettare più siti in una volta, come descritto nell’articolo sulla contaminazione incrociata negli hosting condivisi. Infine, un accesso con credenziali valide lascia spesso tracce che vanno oltre i file: amministratori creati nel database, chiavi SSH aggiunte a authorized_keys, voci nel crontab. Vanno cercate tutte, perché cambiare la password FTP non chiude una chiave SSH aggiunta dall’attaccante.

# Chiavi autorizzate: confrontare con quelle note, riga per riga
cat ~/.ssh/authorized_keys
ssh-keygen -lf ~/.ssh/authorized_keys

# Crontab dell'utente del sito
crontab -l -u cliente

L’ordine giusto: client, credenziali, sito

La sequenza conta più delle singole operazioni. Il principio è lo stesso descritto per le prime ore dopo un attacco: non si cambia una credenziale da un dispositivo di cui non ci si fida.

  1. Mettere da parte il PC sospetto. Scollegarlo dalla rete, non usarlo per accedere a nessun servizio e farlo analizzare o reinstallare. Un antivirus che non trova nulla non è una garanzia, perché molti stealer si cancellano dopo la raccolta.
  2. Ruotare tutte le credenziali da una macchina pulita. Non solo l’FTP del sito colpito: pannello di hosting, account FTP e SSH di tutti i siti gestiti, password degli amministratori WordPress, utente del database (con aggiornamento di wp-config.php), caselle di posta, registrar del dominio, account del provider DNS.
  3. Invalidare le sessioni. I cookie rubati restano validi finché la sessione non scade: vanno disconnesse le sessioni attive nei pannelli e rigenerati i salt di WordPress, come spiegato nella guida all’hardening di wp-config.php.
  4. Revocare e rigenerare le chiavi SSH che stavano sul PC, rimuovendo le vecchie chiavi pubbliche da tutti i server.
  5. Solo a questo punto bonificare i siti, tutti quelli raggiunti dalle credenziali, e controllare i log per capire cosa è stato caricato e quando.

Invertire i passi 2 e 5 è l’errore più frequente: si ripulisce il sito mentre le vecchie credenziali sono ancora attive, e qualche ora dopo lo stesso strumento automatico ricarica gli stessi file. Il sito sembra reinfettato da una backdoor sfuggita alla pulizia, mentre in realtà è stato semplicemente reinfettato dall’esterno.

Confronto tra due sequenze di risposta. In alto, la sequenza sbagliata: il sito viene ripulito subito, la password FTP viene cambiata dal PC ancora infetto e salvata nel client, lo stealer la invia di nuovo e dopo pochi giorni il sito è reinfettato, segnato in rosso. In basso, la sequenza corretta in cinque passi: isolare il PC, ruotare tutte le credenziali da una macchina pulita, invalidare sessioni e salt, revocare le chiavi SSH, bonificare tutti i siti e restringere gli accessi, con esito verde.
La stessa bonifica dà risultati opposti a seconda dell’ordine: prima si chiude la fuga di credenziali, poi si ripuliscono i siti.

Ridurre la superficie: SFTP con chiavi, allowlist e niente FTP

Dopo la bonifica, l’obiettivo è fare in modo che una credenziale rubata valga il meno possibile. L’FTP in chiaro andrebbe eliminato del tutto: trasmette utente e password senza cifratura e, nella maggior parte dei pannelli, accetta accessi da qualunque indirizzo. Se lo sviluppatore ha davvero bisogno di un accesso ai file, SFTP con autenticazione a chiave è la scelta ragionevole, con una chiave protetta da passphrase e caricata in un agent, così che il file della chiave da solo non basti.

# /etc/ssh/sshd_config.d/10-sftp.conf
PasswordAuthentication no
KbdInteractiveAuthentication no

Match User cliente
    ForceCommand internal-sftp -l INFO
    ChrootDirectory /srv/chroot/cliente
    AllowTcpForwarding no
    X11Forwarding no

# Verificare la sintassi e ricaricare
sshd -t && systemctl reload ssh    # su RHEL e derivate: systemctl reload sshd

L’opzione -l INFO di internal-sftp fa registrare nel log di sistema le aperture e le chiusure dei file, con i byte scritti: è l’equivalente di xferlog per SFTP, e senza di essa in caso di incidente si sa solo chi si è collegato, non cosa ha caricato. La directory indicata in ChrootDirectory deve appartenere a root e non essere scrivibile da altri utenti, altrimenti sshd rifiuta la connessione; i file del sito vanno quindi in una sottocartella.

Il secondo livello è limitare da dove ci si può collegare. Un’allowlist degli indirizzi dello sviluppatore o dell’agenzia, applicata sul firewall o nel pannello, rende inutile una credenziale usata da un altro paese; dove gli indirizzi non sono fissi, una VPN con indirizzo di uscita noto ottiene lo stesso risultato. Il terzo è separare: un utente per sito e per persona, con accesso solo alla propria document root, così che le credenziali di un collaboratore non aprano l’intero server. Lato client: niente password salvate senza password principale, niente software craccato sul computer da cui si amministrano i siti, autenticazione a due fattori su pannelli, registrar e posta. Molte di queste misure sono raccolte nella checklist di hardening dopo la bonifica.

Riconoscere un furto di credenziali richiede di guardare oltre i file del sito: log FTP e SSH, proprietari dei file, chiavi autorizzate, crontab, sessioni aperte nei pannelli. È un lavoro che spiega molte reinfezioni «impossibili». Nei nostri interventi la correlazione tra log di sistema e access log è parte dell’analisi, e quando i volumi sono grandi ci aiutano modelli di intelligenza artificiale eseguiti in locale, che raggruppano accessi e trasferimenti anomali senza che i log escano dall’infrastruttura.

Se il tuo sito continua a reinfettarsi o sospetti che le credenziali di accesso siano state rubate, la bonifica garantita in 6, 12 o 24 ore per ogni installazione WordPress comprende l’individuazione del vettore e le indicazioni su quali credenziali ruotare e in che ordine. Puoi contattarci, possibilmente da un dispositivo diverso da quello sospetto.

IL PROSSIMO PASSO

Il tuo sito
è infetto?

Ogni ora conta: il malware continua a colpire visitatori e clienti, e Google, l’hosting e le blacklist non aspettano. Scegli il piano, paga online e condividi gli accessi: la bonifica parte subito, a prezzo fisso e con tempi garantiti.

Richiedi la bonifica

Ti porta ai piani: bonifica entro 6, 12 o 24 ore dalla ricezione degli accessi.

MANAGED SERVER S.R.L.info@rimozionemalware.com +39 02 5656 9681

Lunedì – venerdì · 09:30 – 19:30

Preferisci un modulo online?
Contattaci su managedserver.it ↗