Mappa Globale#
Cos'e'#
Sequenza di pacchetti che stabilisce, mantiene e chiude una connessione TCP. Ogni pacchetto porta uno o piu' flag che indicano lo scopo del pacchetto. Leggere i flag in tcpdump e' la competenza base di un SOC analyst.
TL;DR#
Prima dei dati → negoziazione obbligatoria in 3 pacchetti
Durante → dati con conferma (ACK) ad ogni scambio
Chiusura → FIN (educata) o RST (brusca)Esempio reale visto in tcpdump durante SSH da Kali a Ubuntu:
192.168.64.200 > 192.168.64.3.22: Flags [S] # SYN
192.168.64.3.22 > 192.168.64.200: Flags [S.] # SYN+ACK
192.168.64.200 > 192.168.64.3.22: Flags [.] # ACK
192.168.64.200 > 192.168.64.3.22: Flags [P.] # PUSH dati
192.168.64.3.22 > 192.168.64.200: Flags [.] # ACK confermaI Flag TCP#
| Flag | Simbolo tcpdump | Nome completo | Traduzione | Significato operativo |
|---|---|---|---|---|
| SYN | [S] | Synchronize | Sincronizza | Apre la connessione — "voglio connettermi" |
| ACK | [.] | Acknowledge | Conferma | Conferma ricezione — "ho ricevuto" |
| SYN+ACK | [S.] | Synchronize + Acknowledge | Sincronizza + Conferma | Risposta al SYN — "ok, e tu?" |
| PSH | [P.] | Push | Spingi | Consuma questi dati subito, non aspettare il buffer |
| RST | [R] | Reset | Reimposta | Chiude bruscamente — porta chiusa o errore |
| FIN | [F.] | Finish | Finisci | Chiusura elegante — "ho finito di mandare" |
| URG | [U] | Urgent | Urgente | Dati urgenti — raramente usato |
Three-Way Handshake (3 passi) APERTURA#
Client Server
| |
| ------- [S] SYN --------> | "voglio connettermi"
| |
| <------ [S.] SYN+ACK ---- | "ok, sono pronto. tu?"
| |
| ------- [.] ACK --------> | "confermato, si parte"
| |
| CONNESSIONE APERTA |
| |
| ------- [P.] dati ------> | i dati veri iniziano qui
| |
| <------ [.] ACK ---------- | "ricevuto"Il terzo pacchetto [.] e' solo ACK — lunghezza 0, nessun dato.
I dati viaggiano solo dopo la connessione stabilita.
Four-Way Handshake (4 passi) CHIUSURA#
Client Server
| |
| ------- [F.] FIN+ACK ---> | "ho finito di mandare"
| |
| <------ [F.] FIN+ACK ---- | "anch'io ho finito"
| |
| ------- [.] ACK --------> | "confermato"
| |
| CONNESSIONE CHIUSA | Chiusura: FIN vs RST#
Due modi per chiudere una connessione — molto diversi dal punto di vista difensivo:
CHIUSURA ELEGANTE (FIN) CHIUSURA BRUSCA (RST)
Client Server Client Server
| | | |
| -- [F.] FIN -> | | <-- [R] RST -- |
| <- [.] ACK --- | | |
| <- [F.] FIN -- | connessione |
| -- [.] ACK --> | tagliata |
| | immediatamente |
connessione |
chiusa |
correttamenteDal punto di vista SOC:
Molti FIN → traffico normale, sessioni che finiscono
Molti RST → segnale sospetto:
- port scan in corso
- servizio che crasha
- firewall che blocca
- SYN floodPort Scan — cosa vedi in tcpdump#
Un nmap -sS (SYN scan) sulla stessa rete produce pattern riconoscibili:
PORTA APERTA (es. 22 SSH)
Kali --[S]--> Ubuntu:22 SYN
Ubuntu --[S.]--> Kali SYN+ACK (il servizio risponde)
Kali --[R]--> Ubuntu:22 RST (nmap taglia prima del terzo ACK)
PORTA CHIUSA (es. 801)
Kali --[S]--> Ubuntu:801 SYN
Ubuntu --[R.]--> Kali RST (nessun servizio in ascolto)Differenza chiave: porta aperta risponde [S.], porta chiusa risponde [R.].
SYN Scan — perche' e' silenzioso#
Il SYN scan (nmap -sS) non completa mai il handshake:
Handshake completo SYN Scan
(connessione normale) (nmap -sS)
[S] --> [S] -->
[S.] <-- [S.] <--
[.] --> ← terzo passo [R] --> ← nmap manda RST
registrato nei log NON registrato nei log
del servizio del servizioRisultato: auth.log e i log SSH non vedono nulla.
tcpdump sul livello di rete vede tutto.
Lezione difensiva: i log applicativi non bastano — serve cattura a livello di rete.
SYN Flood — attacco DoS#
Variante offensiva del SYN scan:
Attaccante manda migliaia di [S] verso la stessa porta
senza mai completare il handshake.
Il server tiene aperta una "half-open connection" per ognuno
in attesa del terzo [.] che non arrivera' mai.
Quando le half-open connections esauriscono la memoria:
→ nuove connessioni legittime vengono rifiutate
→ il servizio va giu'Pattern in tcpdump che lo indica:
# Tanti SYN dallo stesso IP verso la stessa porta, nessun ACK finale
sudo tcpdump -i enp0s1 'tcp[tcpflags] & tcp-syn != 0'ARP — il livello sotto TCP#
Prima che TCP possa mandare il primo SYN, la macchina deve sapere il MAC address della destinazione. Questo avviene via ARP:
Kali vuole mandare SYN a Ubuntu (192.168.64.3)
PRIMA:
Kali --> broadcast "chi ha 192.168.64.3? dimmelo" ARP Request
Ubuntu --> Kali "sono io, MAC b6:56:08:90:16:03" ARP Reply
Kali salva in ARP cache: 192.168.64.3 = quel MAC
POI:
Kali --> Ubuntu [S] SYN TCP iniziaLa ARP cache evita di fare questa domanda ad ogni pacchetto. Stati della cache:
REACHABLE → comunicato di recente, MAC valido con certezza
STALE → obsoleto — non comunichiamo da un po',
probabilmente ancora valido ma verifichero'
alla prossima comunicazione
FAILED → ho provato, nessuno ha risposto (host giu' o
non raggiungibile — come 8.8.8.8 senza gateway)Scenario Reale — riconoscere un port scan nei log#
Un analista SOC vede questo pattern in tcpdump:
14:30:45.000 IP 10.0.0.50 > 10.0.0.3.22: Flags [S.] → porta aperta
14:30:45.001 IP 10.0.0.50 > 10.0.0.3.23: Flags [R.] → porta chiusa
14:30:45.001 IP 10.0.0.50 > 10.0.0.3.80: Flags [R.] → porta chiusa
14:30:45.002 IP 10.0.0.50 > 10.0.0.3.443: Flags [S.] → porta aperta
14:30:45.002 IP 10.0.0.50 > 10.0.0.3.3306: Flags [R.] → porta chiusaSegnali di port scan:
- stesso IP sorgente verso molte porte in rapida sequenza
- mix di
[S.]e[R.]come risposta - nessun
[.]di completamento (SYN scan) - auth.log vuoto — il servizio non ha visto nulla
Azione: blocca l'IP sorgente, controlla se ha gia' stabilito connessioni, cerca nei log applicativi tracce di tentativi riusciti.
Tipi di Scan e Cosa Rivelano#
I diversi tipi di scan nmap usano combinazioni di flag TCP diverse per ottenere informazioni senza completare il handshake. Ogni tipo rivela qualcosa di diverso.
| Scan | Flag inviati | Risposta porta aperta | Risposta porta chiusa | Cosa rivela |
|---|---|---|---|---|
| SYN scan (-sS) | SYN | SYN+ACK, poi nmap manda RST | RST | Porta aperta/chiusa. Stealth: non logga nei servizi. |
| ACK scan (-sA) | ACK | RST (senza filtro) | RST (senza filtro) | Non rileva porte aperte - rileva se firewall e' stateful o stateless |
| FIN scan (-sF) | FIN | Silenzio (RFC 793) | RST | Elude firewall che filtrano solo SYN. Non funziona su Windows |
| XMAS scan (-sX) | FIN+PSH+URG | Silenzio | RST | Come FIN ma piu' riconoscibile. Illumina tutti i flag come un albero di Natale |
| NULL scan (-sN) | nessun flag | Silenzio | RST | Come FIN ma nessun flag. Elude IDS signature-based che cercano flag specifici |
ACK scan e stateful firewall: un firewall stateful tiene traccia della connection table. Un pacchetto ACK senza un corrispondente SYN precedente viene bloccato come "out of state". Un firewall stateless risponde con RST al pacchetto ACK perche' non ha memoria. Questo permette di determinare il tipo di firewall in uso.
SYN Cookies — Difesa al SYN Flood#
Il SYN Flood esaurisce la memoria del server riempiendo la tabella delle half-open connections. La difesa classica e' i SYN Cookies: il server non alloca memoria per ogni SYN ricevuto.
Come funziona:
- Server riceve SYN da un client
- Invece di allocare una entry nella connection table, il server calcola un sequence number crittografico (cookie) basato su IP sorgente, porta, timestamp
- Manda SYN+ACK con quel sequence number come ISN (Initial Sequence Number)
- Solo quando riceve l'ACK con il sequence number+1 corretto, il server verifica il cookie e alloca la connessione
Risultato: il server non alloca memoria finche' non riceve l'ACK finale. Un attaccante che manda milioni di SYN senza mai mandare ACK non consuma memoria del server.
# Verificare se SYN Cookies e' attivo su Linux
cat /proc/sys/net/ipv4/tcp_syncookies
# 1 = attivo (default su kernel moderni)
# Abilitare permanentemente
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf
sysctl -pTCP Reset Attack#
Il TCP Reset Attack inietta un pacchetto RST forgiato in una connessione TCP stabilita per interromperla bruscamente. Non richiede una posizione MITM completa: basta essere in grado di inviare pacchetti con IP spoofato.
Requisito critico: il sequence number del pacchetto RST deve essere nel range accettabile della connessione. Un attaccante che monitora il traffico puo' estrarre il sequence number attuale e forgiare un RST valido.
Usi documentati:
- Great Firewall of China: inietta RST per interrompere connessioni verso siti censurati. Wireshark mostra RST da IP che non appartengono alla connessione.
- Censura ISP: alcuni ISP iniettano RST per bloccare traffico peer-to-peer.
- Attacco DoS selettivo: interrompere sessioni SSH o VPN specifiche senza bloccare tutto il traffico.
Stateful Firewall e Connection Table#
Un firewall stateful non analizza ogni pacchetto in isolamento: mantiene una connection table con lo stato di ogni connessione TCP attiva.
stateDiagram-v2 [*] --> LISTEN : server in ascolto LISTEN --> SYN_RECEIVED : riceve SYN SYN_RECEIVED --> ESTABLISHED : riceve ACK (handshake completo) ESTABLISHED --> FIN_WAIT : riceve FIN FIN_WAIT --> [*] : chiusura completata note right of SYN_RECEIVED : Firewall: crea entry nella connection table note right of ESTABLISHED : Firewall: aggiorna stato connessione
Perche' il firewall stateful blocca i pacchetti fuori sequenza:
- Un ACK senza SYN precedente → no entry in connection table → bloccato
- Un FIN su una connessione non stabilita → fuori sequenza → bloccato
- Un RST su connessione inesistente → anomalia → bloccato (o loggato)
Questo e' il motivo per cui l'ACK scan non rileva porte aperte/chiuse su un firewall stateful: tutti i pacchetti ACK vengono bloccati indiscriminatamente perche' nessuno ha un SYN precedente registrato.
Dev parallel: Come il middleware di sessione in Express.js o Laravel: ogni request viene verificata contro la session table. Se arrivi con un cookie di sessione che non esiste nel session store, vieni rifiutato - anche se il cookie ha una struttura valida. Il firewall stateful fa la stessa cosa con i pacchetti TCP: "questa connessione esiste nella mia tabella? No? Bloccato."


