Cosa fa#
Analizza traffico di rete da terminale usando lo stesso motore di Wireshark. Legge file .applica filtri display identici a Wireshark GUI, estrae campi specifici in output pipeable. Indispensabile su server remoti senza display grafico e per automatizzare analisi con script bash.
Installazione#
sudo apt install tshark -y
# Durante l'installazione: seleziona YES per permettere cattura a utenti non-root
# Aggiungi il tuo utente al gruppo wireshark
sudo usermod -aG wireshark barno
# Rieffettua il login per applicare il gruppo
# Verifica
id | grep wiresharkSintassi#
tshark [opzioni] [filtro]
Comandi essenziali#
| Comando | Flag | Significato flag | Cosa fa |
|---|---|---|---|
tshark -r file.dfir | -r | read | Legge un file .dfir |
tshark -i eth0 | -i | interface | Cattura live sull'interfaccia |
tshark -r file.dfir -Y "filtro" | -Y | display filter | Applica filtro display (stessa sintassi di Wireshark) |
tshark -r file.dfir -T fields | -T fields | fields output | Output solo i campi specificati con -e |
tshark -r file.dfir -e ip.src | -e | extract field | Specifica il campo da estrarre (usato con -T fields) |
tshark -r file.dfir -w out.dfir | -w | write | Salva output filtrato in nuovo dfir |
tshark -G fields | -G fields | generate fields | Lista tutti i campi disponibili |
tshark -r file.dfir -q -z io,phs | -q -z | quiet — statistics | Sopprime output pacchetti, mostra solo statistiche |
Man online: https://www.wireshark.org/docs/man-pages/tshark.html
Statistiche con -z#
Il flag -z genera statistiche aggregate sul dfir. Si usa sempre con -q per silenziare l'output riga per riga.
| Comando | Cosa mostra |
|---|---|
tshark -r file.dfir -q -z io,phs | Gerarchia protocolli — frames e bytes per protocollo |
tshark -r file.dfir -q -z conv,tcp | Conversazioni TCP — IP:porta sorgente/destinazione, bytes scambiati |
tshark -r file.dfir -q -z expert | Expert info — errori, warning, note rilevati automaticamente |
tshark -r file.dfir -q -z follow,tcp,ascii,0 | Contenuto completo dello stream TCP numero 0 |
tshark -r file.dfir -q -z io,stat,1 | Traffico per intervallo di 1 secondo — identifica burst e gap |
tshark -r file.dfir -q -z http,stat | Statistiche HTTP — metodi e codici risposta |
tshark -r file.dfir -q -z http_req,tree | Albero richieste HTTP per host e URI con conteggi |
io,phs = I/O Protocol Hierarchy Statistics — punto di partenza obbligatorio per qualsiasi analisi dfir: mostra subito cosa c'e' dentro.
io,stat,N richiede obbligatoriamente l'intervallo N (secondi). tshark -q -z io,stat senza intervallo da' errore.
Per trovare i burst: tshark -r file.dfir -q -z io,stat,1 > /tmp/stat.txt && grep "<>" /tmp/stat.txt | grep -v "| 0 |"
Filtri display — identici a Wireshark#
# Flag TCP
tshark -r file.dfir -Y "tcp.flags.syn == 1"
tshark -r file.dfir -Y "tcp.flags.syn == 1 && tcp.flags.ack == 0"
tshark -r file.dfir -Y "tcp.flags.reset == 1"
# Per IP
tshark -r file.dfir -Y "ip.src == 192.168.64.200"
tshark -r file.dfir -Y "ip.addr == 192.168.64.3"
# Per porta
tshark -r file.dfir -Y "tcp.port == 22"
# Combinazioni
tshark -r file.dfir -Y "tcp.flags.syn == 1 && ip.src == 192.168.64.200"Triage SOC & Estrazione Utenti#
Tshark e' perfetto per estrarre rapidamente chi e' loggato senza aprire la GUI:
# Estrai username Kerberos (Authentication Service Request)
tshark -r file.dfir -Y "kerberos.CNameString" -T fields -e kerberos.CNameString | sort | uniq
# Estrai username NTLM
tshark -r file.dfir -Y "ntlmssp.auth.username" -T fields -e ntlmssp.auth.username | sort | uniq
# Estrai Hostname NBNS
tshark -r file.dfir -Y "nbns" -T fields -e nbns.name | sort | uniqEstrazione campi — la potenza di tshark#
Con -T fields -e campo estrai colonne specifiche pipeable con altri tool:
# Estrai solo IP sorgenti
tshark -r file.dfir -T fields -e ip.src
# Estrai IP sorgente e destinazione
tshark -r file.dfir -T fields -e ip.src -e ip.dst
# Estrai porte
tshark -r file.dfir -T fields -e tcp.srcport -e tcp.dstport
# Estrai flag TCP
tshark -r file.dfir -T fields -e tcp.flagsNomi dei campi disponibili:
# Cerca tutti i campi IP
tshark -G fields | grep "^F\tip\."
# Cerca tutti i campi TCP
tshark -G fields | grep "^F\ttcp\."Scoprire il nome esatto di un campo#
La terza colonna di tshark -G fields è il nome del campo da usare in -Y e -e:
# Trovare tutti i campi che contengono "hostname"
tshark -G fields | grep -i hostname | awk -F'\t' '{print $3}'
# Trovare tutti i campi che iniziano per "ip"
tshark -G fields | awk -F'\t' '$3 ~ /^ip/ {print $3}'I nomi trovati con -G fields funzionano sia in -Y (filtro) che in -e (estrazione) — sono gli stessi identificatori.
Espandere un frame completo#
-V mostra la "matrioska" completa del frame: Ethernet → IP → TCP → protocollo applicativo.
# Vedere tutto il contenuto di un frame specifico
tshark -r file.pcap -Y "frame.number == 14417" -V
# Versione selettiva: solo i campi che ti servono
tshark -r file.pcap -Y "frame.number == 14417" \
-T fields \
-e frame.number \
-e frame.len \
-e ip.src \
-e ip.dst \
-e _ws.col.Protocol \
-e _ws.col.Info-V è utile per esplorare; -T fields -e campo è utile quando sai già cosa cercare.
-Y "kerberos" vs grep#
-Y "kerberos" non è un grep sul testo — usa il motore di decodifica di Wireshark:
- decodifica ogni frame fino al livello applicativo
- restituisce solo i frame dove il protocollo è effettivamente Kerberos
- puoi usare campi specifici:
-Y "kerberos.CNameString",-Y "kerberos.msg_type == 10"
# Username da Kerberos (authentication request)
tshark -r file.pcap -Y "kerberos.CNameString" \
-T fields -e kerberos.CNameString | sort | uniqtshark come SQL#
-Y e -T fields -e si comportano come clausole SQL:
| SQL | tshark | Funzione |
|---|---|---|
WHERE | -Y "filtro" | Seleziona solo i pacchetti che matchano |
SELECT | -T fields -e campo | Estrae le colonne che vuoi |
GROUP BY + COUNT + ORDER BY | | sort | uniq -c | sort -rn | Aggrega, conta, ordina |
I nomi dei campi di -G fields funzionano sia in -Y che in -e — sono gli stessi identificatori.
# SELECT method, uri FROM packets WHERE method IS NOT NULL ORDER BY uri
tshark -r file.dfir \
-Y "http.request.method" \
-T fields -e http.request.method -e http.request.uri-q e -T fields si escludono: -q sopprime l'output pacchetto, -T fields lo mostra strutturato. Non usarli insieme.
Campi HTTP utili#
| Campo | Cosa estrae |
|---|---|
http.request.method | Metodo HTTP (GET, POST, PUT...) |
http.request.uri | Path + query string richiesti |
http.host | Header Host della richiesta |
http.response.code | Codice risposta (200, 302, 404...) |
# Ricostruisci tutte le richieste HTTP: metodo + host + uri
tshark -r file.dfir \
-Y "http.request.method" \
-T fields -e http.request.method -e http.host -e http.request.uriPer i DNS (dfir con traffico reale verso internet):
# Query DNS richieste
tshark -r file.dfir -Y "dns.flags.response == 0" -T fields -e dns.qry.name
# Query DNS con IP risposta (A record)
tshark -r file.dfir -Y "dns.flags.response == 1" -T fields -e dns.qry.name -e dns.aPattern C2 — rilevare traffico Command & Control#
Tre pattern principali che un SOC analyst cerca in un pcap sospetto.
Beaconing#
Il malware chiama casa a intervalli regolari. Si riconosce con io,stat: se vedi picchi di traffico periodici verso lo stesso IP, e' beaconing.
Regola rapida:
io,statti dice quando — picchi regolari nel tempoconv,tcpti dice chi — la tabella delle conversazioni
# 1. Trova il ritmo — RST regolari ogni 30 secondi = beaconing fallito (C2 offline)
tshark -r file.pcap -q -z io,stat,30,"tcp.flags.reset==1"
# 2. Trova il bersaglio
tshark -r file.pcap -q -z conv,tcpOutput sospetto in conv,tcp — stesso IP, stessa porta, frame e byte identici:
| # | Address A | Address B | Frames | Bytes |
|----|------------------------|----------------------|--------|-------|
| 0 | 192.168.1.10:443 | 10.0.0.5:52341 | 8420 | 1.2MB |
| 2 | 185.220.101.5:4444 | 10.0.0.5:39211 | 4 | 240B | ←
| 3 | 185.220.101.5:4444 | 10.0.0.5:51092 | 4 | 240B | ←
| 4 | 185.220.101.5:4444 | 10.0.0.5:61203 | 4 | 240B | ←Workflow completo:
io,stat,30 → RST regolari ogni 30s → sospetto beaconing
conv,tcp → piu' connessioni brevi stesso IP:porta → confermato
whois IP → Tor exit node / hosting anonimo → C2 identificatoSegnali di allarme: stesso IP esterno contattato ogni N secondi, traffico basso e costante, porta non standard (4444, 8080, 1337). RST regolari = beaconing con C2 offline.
DNS tunneling#
I dati vengono nascosti dentro le query DNS: il malware codifica il payload nel sottodominio e lo manda al nameserver controllato dall'attaccante.
# Conta query DNS per dominio — cerca domini con centinaia di query
tshark -r file.pcap -Y "dns.flags.response == 0" \
-T fields -e dns.qry.name | sort | uniq -c | sort -rn
# Estrai lunghezza subdomini — nel tunneling sono molto lunghi
tshark -r file.pcap -Y "dns.flags.response == 0" \
-T fields -e dns.qry.name | awk '{print length, $0}' | sort -rn | head -20Segnali di allarme: sottodomini casuali e lunghi (es. a3f8bc12d.evil.com), molte query allo stesso dominio root, record TXT o MX insoliti in risposta.
HTTP POST verso C2#
Il malware riceve comandi via risposta HTTP e manda risultati via POST. Il traffico sembra normale ma e' diretto verso IP sconosciuti o con User-Agent anomali.
# POST ripetuti — identifica host e URI
tshark -r file.pcap -Y "http.request.method == \"POST\"" \
-T fields -e ip.dst -e http.host -e http.request.uri \
| sort | uniq -c | sort -rn
# User-Agent — C2 spesso usa stringhe strane o default di tool
tshark -r file.pcap -Y "http.user_agent" \
-T fields -e http.user_agent | sort | uniq -c | sort -rnSegnali di allarme: POST verso IP numerici (no hostname), URI con path casuali, User-Agent non standard, intervalli regolari.
Flusso triage C2: prima io,stat per vedere i burst, poi conv,tcp per isolare gli IP sospetti, poi filtri mirati su DNS o HTTP per quel singolo IP.
Pattern Blue Team — analisi port scan#
# Conta SYN per IP sorgente — rileva chi sta scansionando
tshark -r file.dfir \
-Y "tcp.flags.syn == 1 && tcp.flags.ack == 0" \
-T fields -e ip.src \
| sort | uniq -c | sort -rn
# Output:
# 1001 192.168.64.200 ← port scan — 1001 SYN in 2 secondi
# 11 192.168.64.1
# Conta RST per IP — porte chiuse vs scan
tshark -r file.dfir \
-Y "tcp.flags.reset == 1" \
-T fields -e ip.src \
| sort | uniq -c | sort -rntshark vs tcpdump vs Wireshark#
tcpdump → cattura live, filtri BPF, output testo grezzo
veloce, scriptabile, nessuna dipendenza grafica
tshark → stesso motore di Wireshark
filtri display potenti (stessi di Wireshark GUI)
estrazione campi strutturata
pipeable con Unix tools
Wireshark → GUI, colori, Follow TCP Stream, click
analisi visiva di dfir complessi
non automatizzabileFlusso tipico in un SOC:
server remoto: sudo tcpdump -i eth0 -w /tmp/capture.dfir
scp capture.dfir ~/
analisi rapida: tshark -r capture.dfir -Y "filtro" | sort | uniq -c
analisi visiva: Wireshark → File → Open → capture.dfirScript — analisi port scan da dfir#
#!/bin/bash
# analizza.sh — estrae IP sorgenti SYN e conta frequenza
file=$1
if [ -z "${file}" ]; then
echo "file mancante"
exit 1
fi
out=$(tshark -r "$file" \
-Y "tcp.flags.syn == 1 && tcp.flags.ack == 0" \
-T fields -e ip.src \
| sort | uniq -c)
echo "$out"
echo "---"
echo "IP distinti: $(echo "$out" | wc -l)"
echo "SYN totali: $(echo "$out" | awk '{sum += $1} END {print sum}')"Output su dfir con nmap -sS:
1001 192.168.64.200
---
IP distinti: 1
SYN totali: 1001Scenario Reale#
Un analista SOC riceve un dfir da un firewall — 50MB di traffico delle ultime 6 ore. Deve rispondere: c'è stato un port scan? Da chi?
# Risposta in 3 secondi
tshark -r firewall.dfir \
-Y "tcp.flags.syn == 1 && tcp.flags.ack == 0" \
-T fields -e ip.src \
| sort | uniq -c | sort -rn | head -10Se un IP appare centinaia di volte in pochi secondi — port scan confermato. Senza tshark avrebbe dovuto aprire Wireshark, applicare filtri a mano, contare visivamente.
Dove l'ho usato#
- Settimana 6 — analisi dfir port scan nmap -sS
- Settimana 6 — script bash per contare SYN per IP sorgente
- Settimana 9 — network-defense reconstruction da dfir HTTP redirects (statistiche -z, estrazione campi HTTP)
Note personali#
tshark -G fields | grep "^F\t" lista tutti i campi disponibili — utile quando non ricordi il nome esatto di un campo da estrarre con -e o con -Y.
Regola mentale: quando fai tshark -G fields, prendi sempre la terza colonna come chiave del display filter.
Le virgolette doppie in bash preservano i newline nelle variabili.
echo "$var" mantiene il formato, echo $var comprime tutto su una riga.
Critico quando usi tshark in script bash con output multiriga.
Su server remoti senza GUI: cattura con tcpdump, scarica con scp, analisi rapida con tshark, analisi visiva con Wireshark in locale. Questo e' il flusso standard in un SOC reale.
Expert info vuota non e' un errore — significa traffico sano, nessuna anomalia di protocollo rilevata. Su dfir con problemi reali (retransmit, reset anomali, malformed packets) questa sezione e' ricca.
-z help scrive su stderr. Per filtrare le statistiche disponibili con grep:
tshark -z help 2>&1 | grep -i "http" — senza 2>&1 grep non vede nulla.
Collegato a#
file-descriptor —
2>&1per filtrare-z helpcon greplog — categoria
incidents — categoria
system — categoria
wireshark — stessa sintassi filtri, versione GUI
tcpdump — cattura il .dfir che tshark analizza
tcp-handshake — i flag che tshark filtra
nmap — genera il traffico che tshark analizza




