THREATHUNTING.IT / Hardening Guide

Porte aperte, servizi invisibili: come leggere davvero ciò che ascolta sul sistema

Il catalogo dei servizi non è l’elenco di ciò che è in esecuzione. La differenza tra /etc/services, socket in ascolto e processi di sistema è la chiave per un controllo consapevole su Linux e Windows.

LivelloIntermediate Porte aperte, servizi invisibili: come leggere davvero ciò che ascolta sul sistema

Porte aperte: cosa guardare davvero

Quando si parla di porte aperte, la metafora della porta aiuta fino a un certo punto. In un sistema acceso non esiste una porta fisica: esistono socket, cioè estremi di comunicazione creati da un processo. Su TCP, il socket può essere messo in ascolto; su UDP non c'è un handshake e la verifica riguarda endpoint associati a una porta. Distinguere tra catalogo dei nomi, socket attivi e servizio che li governa evita due errori opposti: allarmarsi per ogni voce di un file di configurazione e ignorare un processo sconosciuto che ascolta su tutte le interfacce.

Il catalogo non è lo stato

Su Linux, /etc/services è un file ASCII che associa nomi leggibili a numeri di porta e protocolli. Una riga come ftp 21/tcp dice che il nome ftp corrisponde alla porta 21 sul protocollo TCP; non dice che FTP sia installato, avviato o raggiungibile. Il file è un dizionario consultato dai programmi di rete, non un cruscotto dei processi attivi. Questo punto viene spesso frainteso. La presenza di una voce in /etc/services non implica che il servizio sia in esecuzione. Inoltre la politica IANA tende ad assegnare sia TCP sia UDP quando assegna una porta, perciò molte voci esistono in doppia copia anche per servizi che usano solo TCP. Vedere una riga UDP nel catalogo non significa che ci sia qualcuno in ascolto su UDP.

Un'altra distinzione utile riguarda i privilegi: su Linux e Unix i numeri di porta inferiori a 1024 possono essere associati solo da root. È un indizio sul livello di privilegio del processo, non una prova che il servizio sia legittimo o necessario. Anche un processo privilegiato può essere fuori posto.

Dove guardare: socket, non nomi

Per sapere cosa è realmente in ascolto bisogna interrogare il sistema operativo, non il file dei nomi. Su Linux, ss è uno strumento comune per elencare socket. L'opzione -t mostra TCP, -u UDP, -l i socket in ascolto, -p il processo proprietario e -n evita la risoluzione dei nomi.

bash
# Elenca tutti i socket in ascolto (TCP e UDP) con processo e PID, senza risolvere i nomi
sudo ss -tulpn

Per vedere i PID dei processi di altri utenti servono privilegi adeguati; senza di essi la colonna del processo può risultare incompleta. Il dato importante non è solo la porta, ma anche l'indirizzo locale: un servizio su 127.0.0.1:5432 ascolta solo in locale, mentre 0.0.0.0:5432 o [::]:5432 indica un ascolto su interfacce più ampie. La prima configurazione riduce l'esposizione, la seconda merita una domanda in più.

Su Windows si può partire da netstat -ano, che mostra endpoint e PID, oppure usare PowerShell per un elenco più leggibile.

powershell
# Socket TCP in ascolto: indirizzo, porta e PID proprietario
Get-NetTCPConnection -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess

# Endpoint UDP: indirizzo, porta e PID proprietario
Get-NetUDPEndpoint | Select-Object LocalAddress,LocalPort,OwningProcess

Il PID va poi ricondotto al processo e, quando esiste, al servizio che lo controlla. Un esempio di passaggio in PowerShell:

powershell
# Ricava il nome e il percorso dell'eseguibile a partire dal PID
$procId = 1234
Get-Process -Id $procId | Select-Object Id,ProcessName,Path

# Trova i servizi Windows ospitati da quel PID
Get-CimInstance Win32_Service | Where-Object ProcessId -eq $procId | Select-Object Name,DisplayName,StartMode,State

Su Windows bisogna però fare attenzione a un dettaglio: molti servizi condividono lo stesso processo svchost.exe. Un PID può quindi ospitare più servizi, e fermare il processo sarebbe una scorciatoia sbagliata. Prima si identifica il servizio, poi si decide se e come intervenire. Lo stesso vale su Linux quando un servizio principale avvia processi figli o worker: il nome del processo non coincide sempre con il nome dell'unità di sistema.

porte e servizi in ascolto

La domanda giusta non è "La porta è aperta?"

Una porta in ascolto non è automaticamente un problema. La domanda utile è: quel processo ha una ragione per ascoltare, su quell'indirizzo e con quel livello di privilegio? Per rispondere conviene costruire un inventario e confrontarlo con il ruolo della macchina.

  • Il servizio è previsto? Un server web, un database o un servizio di stampa possono essere normali su una macchina e fuori posto su un'altra.

  • Dove ascolta? Solo su loopback, su una rete interna o su tutte le interfacce? L'indirizzo di bind cambia molto l'esposizione.

  • Chi lo possiede? Un'unità di sistema, un servizio Windows, un container, un'applicazione avviata da un utente? Ogni caso richiede un controllo diverso.

  • Parte da solo? Sapere se il servizio è attivo ora non basta: conta anche se è abilitato all'avvio. Su Linux si distingue tra unità attiva e unità abilitata; su Windows tra stato corrente e modalità di avvio del servizio.

  • Da cosa dipende? Disabilitare un servizio senza conoscere le dipendenze può rompere funzioni non evidenti, come autenticazione, aggiornamenti o gestione remota.

Anche il firewall va tenuto separato dal processo. Una porta in ascolto può non essere raggiungibile dall'esterno perché il firewall la blocca o perché il servizio è legato solo a un'interfaccia locale. Viceversa, una regola firewall non chiude il processo: se il servizio non serve, va gestito sul sistema, non solo nascosto in rete.

Un caso concreto

Immagina che ss mostri un processo Python in ascolto su 0.0.0.0:8080. Non è automaticamente un'intrusione: potrebbe essere un'applicazione interna o un server di sviluppo. Se però è stato avviato da un utente e ascolta su tutte le interfacce, il passo successivo è capire quale applicazione sia, da quale directory parta e se quel tipo di esposizione serva davvero. Un server di sviluppo può essere limitato a 127.0.0.1 o spento quando non serve; un'applicazione destinata alla rete interna va invece documentata e protetta.

Vediamo come farlo in pratica. Supponiamo che sudo ss -tulpn abbia restituito una riga simile a questa:

output

tcp   LISTEN 0  128  0.0.0.0:8080  0.0.0.0:*  users:(("python3",pid=4321,fd=3))

Il PID è 4321. Da qui si procede per gradi.

bash
# Identifica il processo: nome, utente proprietario e comando completo
ps -fp 4321

Questo mostra la riga di comando con cui è stato avviato il processo. Spesso è già sufficiente a capire di cosa si tratta: per esempio python3 -m http.server 8080 è un server di sviluppo, non un servizio di produzione.

bash
# Vedi la directory di lavoro e l'eseguibile reale del processo
sudo ls -l /proc/4321/cwd /proc/4321/exe

cwd indica da quale directory è partito il processo, exe l'eseguibile effettivo (utile se il nome del processo è stato alterato o se è un interprete che esegue uno script). Per vedere l'intera riga di comando con i separatori nulli, più affidabile di ps:

bash
# Legge la riga di comando completa separando gli argomenti con spazi
sudo tr '\0' ' ' < /proc/4321/cmdline; echo
bash
# Controlla se il processo è governato da un'unità systemd o è stato avviato a mano
systemctl status 4321

Se il processo appartiene a un'unità systemd, questo comando la mostra con stato e modalità di avvio. Se invece restituisce un errore del tipo "unit 4321.service could not be found", è probabile che sia stato avviato manualmente da un utente o da uno script, e non da un servizio di sistema: è un'informazione decisiva per capire se quell'ascolto è previsto.

bash
# Conferma l'indirizzo di bind effettivo della porta 8080
sudo ss -tlnp 'sport = :8080'

Se compare 0.0.0.0:8080 o [::]:8080, il servizio è raggiungibile da altre macchine (salvo firewall); se compare 127.0.0.1:8080, l'ascolto è solo locale e l'esposizione è molto ridotta.

bash
# Controlla il firewall, che è un livello separato dal processo
sudo nft list ruleset        # su sistemi con nftables
sudo iptables -S             # su sistemi con iptables

Questo serve a distinguere due situazioni diverse: un servizio esposto ma bloccato dal firewall, e un servizio realmente raggiungibile. Ricorda che una regola firewall non chiude il processo: se il servizio non serve, va gestito sul sistema.

Se dai passaggi precedenti emerge un server di sviluppo avviato a mano, per esempio un server python, la correzione tipica è riavviarlo legandolo solo al loopback:

bash
# Riavvia il server di sviluppo in ascolto solo su localhost
python3 -m http.server 8080 --bind 127.0.0.1

Se invece il processo risulta parte di un'applicazione destinata alla rete interna, non lo si spegne: lo si documenta (cosa fa, chi lo ha avviato, su quale interfaccia deve ascoltare, con quale unità o modalità di avvio) e lo si protegge con le regole firewall e i privilegi adeguati.

Su Windows lo scenario equivalente può essere un processo sconosciuto con un PID che, una volta interrogato, risulta associato a più servizi dentro svchost.exe. In quel caso non si chiude il processo: si elencano i servizi ospitati, si guarda la loro modalità di avvio e si verifica quale funzione svolgono. Solo dopo si decide se uno di essi è superfluo.

Prima di chiudere

La verifica utile non finisce con un elenco di porte. Un buon controllo mette insieme quattro elementi: endpoint in ascolto, processo proprietario, servizio o unità che lo governa, comportamento all'avvio. Il criterio non è "porta chiusa significa sicuro", ma "porta aperta significa che qualcuno ha una ragione per ascoltare". Se quella ragione non è chiara, il lavoro da fare è identificare, non spegnere alla cieca.

VALUTAZIONE DEI LETTORI

Questo articolo ti è stato utile?

Punteggio 0 · 0 positivi, 0 negativi

Vedi gli articoli più apprezzati →

AUTORE

Da piu' di 30 anni sono appassionato di computers e tecnologia. il mio primo programma lo sviluppai in Basic nel 1989, non era un gran che :).. ma quella voglia di scrivere codici non mi ha piu' lasciato …

REVISIONE TECNICA

Redazione ThreatHunting.it

Revisionato il .

Come lavoriamo →

COMMUNITY

Commenti 0

Non ci sono ancora commenti. Puoi iniziare tu la conversazione.

Scrivi un commento +
Non sarà pubblicata.
I commenti vengono pubblicati dopo la moderazione.

PRIVACY / LE TUE SCELTE

Cookie e statistiche

Usiamo cookie necessari per accesso, sicurezza e memorizzazione delle preferenze. Solo con il tuo consenso raccogliamo statistiche sulle pagine visitate, paese, dispositivo, browser e provenienza, con un identificatore pseudonimo giornaliero. Il consenso abilita anche Google Analytics 4, descritto nell’informativa. Nessuna pubblicità o profilazione commerciale.

Puoi rifiutare le statistiche e continuare a usare il sito. Leggi l’informativa privacy e cookie e modifica la scelta in qualsiasi momento.