Perché conta
Ogni intrusione parte dalla stessa domanda: cosa c’è in ascolto, e dove? Il port scanning risponde a questa domanda ed è la prima fase della ricognizione (la tecnica T1046 di MITRE ATT&CK). Non è un attacco in sé, ma è il segnale più precoce che qualcuno sta preparando il passo successivo. Chi lo rileva ha un vantaggio: l’attaccante non ha ancora fatto nulla di irreversibile.
Capire la scansione serve a due cose: sapere cosa un attaccante vede di te (la tua superficie d’attacco reale, cfr. port knocking e SPA per nasconderla) e sapere come riconoscerla nei log, ad esempio con Zeek o Suricata.
Come funziona
Uno scanner sfrutta il comportamento di TCP definito in RFC 9293: un SYN verso una porta in ascolto riceve SYN/ACK, verso una porta chiusa riceve RST, e se un firewall scarta il pacchetto non riceve nulla. Ogni risposta classifica la porta.
sequenceDiagram
participant A as Scanner
participant T as Target
A->>T: SYN :22
T-->>A: SYN/ACK (open)
A->>T: RST (non completa l'handshake)
A->>T: SYN :23
T-->>A: RST/ACK (closed)
A->>T: SYN :25
Note over A,T: nessuna risposta, poi retry (filtered)
I tipi di scansione principali:
- SYN scan (
-sS): manda il SYN e non completa l’handshake. È veloce e, richiedendo raw socket, serve root. - Connect scan (
-sT): usa laconnect()del sistema operativo, quindi completa l’handshake e finisce nei log delle applicazioni. - UDP scan (
-sU): una porta aperta spesso non risponde, una chiusa risponde con ICMP port unreachable; è lenta perché l’ICMP è limitato in rate. - Version detection (
-sV): dopo aver trovato la porta, legge il banner e prova probe applicativi.
Il tempo necessario dipende dal numero di porte $N$ e dalla velocità $r$ in pacchetti al secondo, più i retry $k$:
$$T \approx \frac{N \cdot (1 + k)}{r}$$
Su tutte le 65535 porte, con $r = 1000$ pkt/s e $k = 1$ per le porte filtrate, servono circa 130 secondi. Rallentare lo scanner a pochi pacchetti al secondo non lo ferma, ma lo trasforma in un’operazione di ore, molto più visibile.
L’attacco
Una scansione tipica prima scopre gli host, poi le porte, poi identifica i servizi:
|
|
Lo stesso lavoro, in modalità “lenta” per aggirare soglie semplici, riduce la frequenza e randomizza l’ordine:
|
|
Sul filo, una scansione SYN ha una firma chiara: un solo IP sorgente, molte porte di destinazione
distinte, pacchetti di soli SYN e molti RST di ritorno. In Wireshark basta il filtro
tcp.flags.syn==1 && tcp.flags.ack==0 e ordinare per porta.
La difesa
Non si può impedire a qualcuno di mandare un SYN, ma si può ridurre ciò che risponde (solo i servizi
necessari, policy drop sul resto) e penalizzare chi sonda troppo. Con nftables un set dinamico
raccoglie gli IP che colpiscono troppe porte non servite e li blocca per un po':
|
|
Le porte legittime vengono accettate prima, quindi solo i pacchetti verso porte non servite alimentano il
contatore. Chi ne tocca più di 5 al secondo finisce in @scanners e viene scartato per dieci minuti
(i dettagli su set e conntrack in stateful firewall con nftables).
Una soglia sul rate non vede però la scansione lenta. Per quella serve una finestra più lunga: in
Suricata una regola con threshold conta i SYN distinti verso lo stesso target e porta l’allarme al
SIEM.
|
|
Altri accorgimenti: non restituire banner informativi, filtrare ICMP port unreachable in uscita dove ha senso, e fare sulla propria rete la scansione prima degli altri, così da conoscere la superficie reale.
Lab
Con containerlab o due container sulla stessa bridge: un target con la policy nftables sopra e un attaccante con Nmap.
- Lancia
nmap -sS -p- --min-rate 1000dall’attaccante verso il target senza regole: quante porte risultanoopeneclosed? - Carica la configurazione nftables. Ripeti la scansione: cosa cambia nell’output e in
nft list set inet filter scanners? - Rilancia con
-T2 --scan-delay 500ms: viene bloccato? Perché sì o perché no?
Soluzione
- Senza regole le porte non servite rispondono RST: Nmap le conta come
closede riporta solo quelle aperte (ad esempio 22 e 443). - Con la policy
drople porte non servite non rispondono: dopo i primi pacchetti l'IP entra in@scannerse il resto viene scartato. Nmap vede quasi tutto comefilterede può perfino perdere le porte aperte, perché anche i suoi SYN verso 22 e 443 vengono scartati dalla regolaip saddr @scanners drop. - Con 2 pacchetti al secondo il limite di 5/s non scatta: lo scanner passa. La scansione lenta richiede una finestra lunga (Suricata/Zeek con soglia su minuti o ore), non un semplice rate limit.
Conclusione
Il port scanning è rumoroso per natura: un solo IP che sonda molte porte lascia tracce evidenti. La difesa efficace combina superficie minima (solo ciò che serve risponde), penalizzazione automatica degli scanner veloci e rilevazione su finestre lunghe per quelle lente. La ricognizione è il momento in cui costa meno fermare un attacco.
Prossimo nella serie: Torna alla roadmap