====== Wireshark ====== ===== Intro ===== Di seguito alcuni appunti sull'utilizzo di Wireshark e sul protocollo TCP. ===== Interfaccia di rete ===== Conviene avviare la //capture// su di un'interfaccia che non faccia traffico; ad es. su di un notebook si può settare la porta RJ45 così: /etc/network/interfaces # Setta l'interfaccia di rete usata da Wireshark come passiva auto enp1s0 iface enp1s0 inet manual up ip link set $IFACE promisc on arp off up down ip link set $IFACE promisc off down post-up ethtool -G $IFACE rx 512; for i in rx tx sg tso ufo gso gro lro; do ethtool -K $IFACE $i off; done post-up echo 1> /proc/sys/net/ipv6/conf/$IFACE/disable_ipv6 ===== IPv4 TTL ===== Nell'header IPv4 viene specificato il **TTL (Time to Leave)**; è un contatore che parte da un valore che è quasi sempre **255, 128 o 64** e che decrementa ad ogni transito da un router. Da ciò si può desumere da che versante il trace di Wireshark è stato preso; tale lato infatti presenterà un valore integro (o quasi) di TTL: {{:wireshark:wireshark-ttl02.png?700|//Trace effettuato vicino l'host 192.168.64.44 (TTL integro, supponendo sia partito a 64)//}} Di seguito un TTL decrementato: [{{:wireshark:wireshark-ttl01.png?700|//TTL dell'host remoto (TTL decrementato e transitato da alcuni router, supponendo sia partito a 64)//}}] ===== IPv4 Don't Fragment (DF) ===== Per evitare la frammentazione dei pacchetti IP si usa la **[[#MSS|MSS]]**, spiegata sotto. Questo meccanismo però funziona solo tra i due //endpoint// di una connessione TCP; se tra gli //endpoint// esistono apparati intermedi con una MTU più piccola, la frammentazione avverrebbe comunque. In questo caso interviene il **Path MTU Discovery (PMTUD)**; è attivo di default su tutti gli host, vale solo per i //transport layer// TCP e UDP ed è il **responsabile che setta il flag DF sui pacchetti IP**: [{{:wireshark:wireshark-df.png|//Il flag DF viene settato dal PMTUD//}}] Se un router cerca di inoltrare un //datagram// IP che ha il bit DF su di un link con una MTU più bassa, il router effettua il //drop// del pacchetto ed **invia al mittente un messaggio (ICMP) "Destination Unreachable fragmentation needed and DF set"**, indicando nello stesso messaggio anche la **MTU desiderata** per il //next hop//. Il **mittente aggiorna la sua //routing table// aggiungendo il valore di MTU per quella destinazione**. Una volta che la fase di 3-way handshake è passata indenne, si può stare relativamente certi che quei valori di MSS e MTU rimarranno per tutta la durata della comunicazione (a meno di reinstradamenti) ===== TCP 3-way handshake ===== Durante questa fase vengono stabiliti quelli che possono essere assimilati ai //termini iniziali// della futura comunicazione TCP. Di seguito vengono evidenziati alcuni particolari di questa fase. ==== Quale lato? ==== Da un'analisi della //3-way handshake// si può immediatamente capire da che lato (se vicino al client o al server) è stata effettuata la cattura di un //trace//. Qui di seguito si vede la stessa conversazione da ambo i lati. === Dal server === {{:wireshark:wireshark-syn-ack-01b.png|}} Il server riceve una SYN e, immediatamente dopo (18 microsecondi), invia i flag di SYN-ACK al client. Dopo poco (1 millisecondo) riceve l'ACK dal client. === Dal client === {{:wireshark:wireshark-syn-ack-02a.png|}} Il client invia una SYN e, dopo poco (quasi 2 millisecondi), riceve il SYN-ACK dal server. Immediatamente dopo il client risponde con ACK. ==== Latenza ==== Già dalla //3-way handshake// si può stabilire la **latenza** di una rete. Nel caso di un trace effettuato dal client, dopo il SYN, c'è il SYN-ACK del server, che quindi dà un valore di latenza tra client-server prima e tra server-client poi. E' il cosiddetto **iRTT (initial round trip time)**. ==== Ghost byte ==== Durante la //3-way handshake//, anche se **non** c'è scambio di dati, l'ACK viene comunque settato a 1 in entrambi i versi. Tale payload (inesistente) viene definito //ghost byte//: {{:wireshark:wireshark-3-way-handshake-phantom-byte.png|}} ==== MSS ==== Il **MSS (Maximum Segment Size)** corrisponde al //payload//, cioè la parte dei **dati, di un segmento TCP** che l'host che l'annuncia, in fase di //3-way handshake//, si aspetta di **ricevere**. Dipende dalla **MTU (Maximum Transfer Unit)**, cioè dal //payload// di un //frame//. Di seguito un esempio classico con un //frame// Ethernet: {{:wireshark:wireshark-tcp-mtu-mss.jpg|}} Quindi: ^Parametro^Rappresenta^Valore tipico^ |**MTU** |Payload del **frame layer 2 (Ethernet)**| 1500| |**MSS** |Payload del **segmento layer 4 (TCP)**| 1460| Come detto, il MSS viene stabilito durante la fase di //3-way handshake//, da parte di ciascuno dei due host (client e server); può essere diverso nei due casi e, anzi, solitamente lo è. Nel caso del server, che deve spedire i dati richiesti dal client, il MSS dovrebbe corrispondere alla lunghezza (**//Len//**) del payload dei segmenti TCP successivi da parte del server. In realtà si vede che, in questo caso, il MSS è 1452: {{:wireshark:wireshark-3-way-handshake-mss.png|}} mentre //Len// dallo stesso host è 1440: {{:wireshark:wireshark-len.png|}} Quindi il //Len// è inferiore di 12 bytes, come spesso capita; si spiega perchè quei 12 bytes corrispondono agli //Enhanced Timestamps// nelle **TCP Options**, che vanno a diminuire il //payload// TCP: {{:wireshark:wireshark-options-bytes.png|//Si vede che le TCP Options occupano 12 byte//}} Nelle **TCP Options** ci possono essere un massimo di **40 byte**. Solitamente tale valore si raggiunge quando ci sono i **//timestamps//** (sempre) e quando ci sono i **//SACK block//** (in presenza di //Dup ACKs//; max 28 byte per tre SACK blocks) Il **valore minimo di MSS** che deve essere implementato dagli //stack// TCP, secondo gli RFC, è **536** === TSO/LRO === Bisogna prestare particolare attenzione a **dove si effettua la //capture//**; se la si effettua su di un host che vogliamo monitorare possono insorgere alcuni problemi. In casi come questi può succedere di vedere **valori di MSS**, cioè del //payload// TCP, di questo tipo: {{:wireshark-banda:wireshark-tso00.png|}} Com'è possibile che ci siano questi **valori doppi o tripli rispetto all'MSS** di cui il server ha fatto l'//advertisement//, supponendo che questi abbia annunciato un MSS da 1452, che tolti i 12 byte dei //timestamps//, corrisponde a 1440 byte? In questi casi entrano in gioco il **TCP Segmentation Offload (TSO)** (detto anche **Large Send Offload**) e il **Large Receive Offload (LRO)**, che sono meccanismi che lavorano a livello di scheda di rete (NIC), quindi hardware, per sgravare la CPU dell'host nell'esecuzione di alcune operazioni TCP/IP. Supponiamo appunto di avere un server che annuncia un MSS di 1452 byte (1440 effettivi); i pacchetti transitano sulla rete per raggiungere il client; ma passano prima dal driver della NIC di questi, che si attiva per assemblare in autonomia alcuni di questi segmenti, senza farlo fare allo //stack// TCP/IP dell'O.S. Ne verranno fuori dei segmenti da 2880 o 4320 byte. Siccome Wireshark usa le librerie Pcap, che si mettono in mezzo tra NIC e //stack// TCP/IP, **Wireshark vedrà i pacchetti solo dopo che sono stati manipolati dal driver della NIC**. Quindi alcuni di questi, in Wireshark, risulteranno doppi o tripli rispetto all'MSS, grazie all'intervento del **LRO** [{{:wireshark-banda:wireshark-tso01.png|//Il LRO interviene tra NIC e librerie PCAP, assemblando i segmenti TCP provenienti dal server//}}] Il meccanismo del **TSO (TCP Segmentation Offload) / LSO (Large Send Offload) agisce nel verso opposto**: supponiamo che un'applicazione (ad esempio un browser), che gira su di un host (ad es. il client in figura sopra), debba **spedire uno //stream// di dati** (un comando GET) all'applicazione sua omologa sul server (un web server). In questi casi solitamente il TCP si preoccupa di spezzettare lo //stream// in segmenti TCP, ciascuno con un MSS pari a quanto stabilito dal server durante la //3-way handshake//; **con il TSO questo compito viene demandato alla NIC**, per cui se vedessimo i pacchetti transitare in Wireshark sul client, li vedremmo più grandi del MSS. Per avere una situazione dei pacchetti catturati attendibile è quindi preferibile avviare una **capture non sugli host interessati, ma su di un client esterno (TAP)** Qui di seguito viene evidenziato lo stesso pacchetto (perchè ha lo stesso Sequence nr.) come viene catturato sull'host interessato (a sinistra) e su di un pc con Wireshark che si frappone (**TAP**): {{:wireshark-banda:wireshark-from-client-and-from-tap.png|//La stessa cattura, fatta dall'host (a sx) e da un client TAP (a dx)//}} A sinistra, sull'host, il pacchetto con Seq 15288403 ha una TCP Length di 5760 (perchè è intervenuto l'LRO della NIC), mentre a destra lo stesso pacchetto contiene 1440 byte, che sono quelli effettivamente spediti dal server. ==== SACK ==== La **SACK (Selective Acknowledgement)** è un parametro stabilito in fase di //3-way handshake//. E' necessario che venga negoziato da **entrambi gli host**, altrimenti non viene utilizzato: {{:wireshark:wireshark-3-way-handshake-sack.png|}} Tramite esso, a seguito di una perdita di uno o più segmenti TCP, un host può effettuare l'ACK dei segmenti ricevuti anche dopo quelli persi. Se il SACK viene usato, in presenza di una rete instabile, si avranno **meno ritrasmissioni** e quindi un aumento di banda. In Wireshark le perdite di pacchetti vengono evidenziate come **'TCP Dup ACK'** dal ricevente (per maggiori dettagli sul funzionamento del SACK vedi **[[wireshark_banda|qui]]**). ===== TCP Windows Size ===== E' un **buffer indipendente** per l'host client o server, con dimensioni che possono variare dinamicamente nel corso di tutta la comunicazione TCP, quindi non solo durante la //3-way handshake//. La **Windows Size** rappresenta la quantità di byte che ciascun host è disposto, in un dato momento, a **ricevere**. Tale quantità è indipendente dal MSS. Può essere pensato come ad un secchio, col fondo che si abbassa o si solleva, per tenere, rispettivamente, più o meno dati; ciò è fatto **in funzione di quanto velocemente gli strati applicativi superiori (livelli OSI 5-7) 'pescano' i dati da esso**: {{:wireshark:mss-window-size.png|}} Nell'immagine sopra i **tubi** rappresentano i valori di **MSS**, cioè il payload che un host può ricevere in un singolo **segmento TCP**. I **secchi** invece sono i buffer riceventi di ciascun host, che servono gli strati OSI applicativi superiori. Se la window size si riduce fino a diventare più piccola del MSS, il server interromperà l'invio di dati al client. Di seguito è stata aggiunta una colonna custom per la //Calculated window size//. Si vede come questa continua a decrescere fino ad arrivare a zero: {{:wireshark:wireshark-window-size-zero.png|}} In questa condizione il client non può più ricevere! E ci resta per più di 32 secondi (vedi //time reference// a sinistra)! Una condizione di **//zero window//** sta ad indicare un host (in questo caso client) sovraccarico. Gli strati applicativi superiori al TCP non riescono ad attingere e svuotare la //window size// perchè impegnati in altro L'aggiunta di colonne custom **rallenta** Wireshark, perchè deve estrapolarle dal contenuto dei pacchetti, quindi è una //feature// da usare con parsimonia Andando in **Statistics - TCP Stream Graphs - (tcptrace)** si può ottenere un grafico in cui c'è una prima curva in alto che rappresenta la dimensione della window size e quella in basso che rappresenta i bytes inviati; tra la prima e la seconda curva dovrà sempre esserci un //gap//, non si dovranno mai incontrare. ==== Window Update ==== Di seguito un //trace// in cui si vede che la //window size// del client si riduce progressivamente fino a raggiungere i 536 byte. Dopodichè la comunicazione si interrompe per 2,7 secondi, fino a quando il client non avvisa il server tramite **due //TCP Window Update//**: {{:wireshark:wireshark-window-update.png|}} ===== HTTP ===== Dopo una richiesta **HTTP** solitamente **non** segue il traffico HTTP, ma quello **TCP**; infatti l'HTTP si appoggia al TCP, sfruttando le sue caratteristiche per inviare **//stream//** di dati in maniera affidabile e orientata alla connessione. Il motivo è la risposta del server sarà divisa tra più segmenti TCP: {{:wireshark:wireshark-http01.png|//L'ultima riga HTTP 200 in basso è il riassemblaggio dei precedenti pacchetti TCP che gli sono sopra//}} ==== Reassembled PDU ==== Nell'immagine sopra si vede nel segmento 28 la **richiesta //'HTTP GET / HTTP/1.1'// dal client** e successivamente lo stream TCP dal server, con i suoi SEQ che incrementano, in funzione dei dati spediti al client. L'indicazione //"TCP segment of a reassembled PDU"// significa che Wireshark sa qual è il protocollo che gira sopra al TCP (è l'HTTP) e che quel segmento TCP non contiene tutto il **PDU (Protocol Data Unit)**, dove //protocol// sta per il protocollo applicativo superiore HTTP. Ad esempio, una HTTP //response// **non** sta solitamente in un singolo segmento TCP, quindi sarà divisa tra segmenti multipli, ciascuno marcato come //"TCP segment of a reassembled PDU"//. Nell'immagine la //response// HTTP (//'HTTP/1.1 200 OK'//) è al segmento 85, ed è proprio data dal riassemblaggio dei precedenti segmenti TCP, come indicato anche da Wireshark: [{{:wireshark:wireshark-http03.png|//Segmento 85 evidenziato, con l'indicazione dei '12 reassembled segments' e la conversione in ASCII della richiesta//}}] === Disattivare il reassembling PDU === Questo comportamento di default si può modificare andando in **Edit - Preferences... - Protocols - TCP** e togliendo il flag da **'Allow subdissector to reassemble TCP stream'**. Così facendo, in una connessione HTTP, dopo una request GET si ha subito l'HTTP 200 OK, con i successivi pacchetti TCP che la compongono: {{:wireshark:wireshark-http-dont-reassemble.png|}} Solitamente, per effettuare il **troubleshooting di HTTP e di SMB(2)**, conviene disattivare il **reassembling del TCP stream**; ciò è utile per avere un riscontro più attendibile delle latenze. Usare il //reassembling// solo in quei casi in cui si vuole riassemblare gli oggetti (immagini, ecc...) di cui si sta facendo il browsing, per un successivo salvataggio degli stessi su disco. ==== Immagini ==== In altri casi, quando i **dati da spedire sono pochi**, invece dopo una request HTTP segue subito una response. Evidentemente il payload di quest'ultima sta nel MSS stabilito all'inizio: [{{:wireshark:wireshark-http04.png|//Ad ogni request GET segue subito una response HTTP OK, perchè sono file piccoli//}}] Quelle sopra infatti sono request di immagini di piccole dimensioni; le **immagini si possono visualizzare** così: * espandendo la **response**, andando sul protocollo HTTP e facendo **tasto dx** sul suo payload, in questo caso un file immagine PNG: {{:wireshark:wireshark-http05.png|}} * selezionando la voce **'Show Packet Bytes...'**. Comparirà un'anteprima dell'immagine (in questo caso un quadrato nero, che è un elemento decorativo della pagina web): {{:wireshark:wireshark-http06.png?600|}} che corrisponde a quanto servito dal server e che sarà anche possibile salvare. La stessa procedura ovviamente si può seguire anche per le response HTTP riassemblate da vari segmenti TCP. Di seguito un esempio; l'immagine JPEG risultante (visibile in basso a destra) è più grossa: {{:wireshark:wireshark-http07.png|}} ==== File non immagine ==== Nel caso di un response HTTP 200 relativa ad un **file, ad es. PDF** bisognerà fare **tasto destro su 'Media Type' e poi 'Export Packet Bytes...'**: {{:wireshark:wireshark-http08.png|}} e salvare il file per successiva visualizzazione col programma predefinito: {{:wireshark:wireshark-http09.png?600|}} ===== GeoIP ===== Può essere utile sapere l'indicazione della **provenienza geografica di un pacchetto** elencato in Whireshark. Per avere questa informazione si può procedere così: * scaricare e scompattare in una cartella i file, reperibile dal sito MaxMind, **GeoLite** * configurare Wireshark perchè recuperi i file da questa cartella, andando in **Edit - Preferences - Name Resolution - MaxMind database directories** * dopodichè nei **dettagli IP** di ogni pacchetto sarà presente un **campo source GeoIP**: {{:wireshark:wireshark-geoip02.png|}} ===== Multicast Addressing ===== Spesso capita di vedere connessioni verso questi indirizzi IPv4 (e protocolli) nei //trace//: ^Range ^Layer4^Proto^Src ^Dst ^ |239.255.255.250|UDP |MDNS |1900|1900| |224.0.0.251 |UDP |SSDP |5353|5353| In entrambi i casi si tratta di **indirizzi multicast**; l'IP multicast è un **metodo per inviare pacchetti IP a più host in una singola trasmissione** (uno-a-molti). L'indirizzamento avviene per **gruppi**; gli host mittenti usano l'indirizzo di destinazione di gruppo (ad esempio 224.0.0.251) per inviare pacchetti; gli host riceventi interessati informeranno la rete che sono interessati a ricevere pacchetti inviati al gruppo 224.0.0.251. I riceventi effettuano un //join// al gruppo 224.0.0.251, usando anche il protocollo **IGMP**. ==== mDNS ==== E' un servizio di DNS zero-configuration, per mappare host name e indirizzi IP. In Windows 10 viene usato per scoprire le stampanti in rete. ==== SSDP ==== Il protocollo SSDP può effettuare il discover di dispositivi Plug & Play, tramite uPnP (Universal Plug and Play). Si tratta di un protocollo //HTTP-like//, che lavora con metodi NOTIFY e M-SEARCH. ===== Ricerche ===== Si può **ricercare un testo** all'interno di un //trace// così. ==== Pulsante Cerca ==== Cliccando sul **pulsante con la lente** compare una **barra di ricerca**: {{:wireshark:wireshark-cerca.png|}} Qui si può stabilire: * in quale //pane// effettuare la ricerca: Packet list, Packet details o Packet bytes * che tipo di ricerca effettuare: in questo caso //**String**// (il default è //Display filter//) * e ovviamente cosa ricercare ("netflix") Il cursore si posizionerà sulla prima occorrenza nel //trace//. ==== Comando ==== La seguente ricerca avviene **ignorando il case** (quindi fornisce i risultati anche per //"Pippo"//, //"PIPPO"//, ...): frame matches "pippo" Questo comando invece ricerca esattamente //"pippo"//, **tenendo conto di maiuscole/minuscole**: frame contains "pippo" Per le ricerche conviene usare il comando **//matches//** ===== Tool a riga di comando ===== Può essere utile eseguire la **cattura di un trace da riga di comando**, perchè ad es. Wireshark può essere sovraccarico e possono comparire errori tipo **[[#tcp_acked_unseen_segment|questi]]**. Sui **server Linux installare Tshark al posto di Wireshark, che installa anche dumpcap** ==== Dumpcap ==== In questi casi si può usare **dumpcap**; l'eseguibile di strova nella directory di Wireshark. Di seguito un esempio di cattura: dumpcap -c 100 -i Ethernet Capturing on 'Ethernet' File: C:\Users\carraror\AppData\Local\Temp\wireshark_Ethernet_20190822104208_a21048.pcapng Packets captured: 100 Packets received/dropped on interface 'Ethernet': 100/0 (pcap:0/dumpcap:0/flushed:0/ps_ifdrop:0) (100.0%) Un altro esempio in cui si stabilisce di creare un **ringbuffer** di 3 trace file, in cui i più vecchi vengono cancellati (in questa maniera non si satura il disco): dumpcap -i3 -w SI-7066-trace.pcapng -b filesize:102400 -b files:3 File: SI-7066-trace_00001_20190919181518.pcapng Packets: 127355 File: SI-7066-trace_00002_20190919181955.pcapng Packets: 231459 File: SI-7066-trace_00003_20190919182012.pcapng Packets: 334589 File: SI-7066-trace_00004_20190919182022.pcapng ... Tramite **dumpcap -h** vengono visualizzate varie altre opzioni. ==== Tshark ==== **Tshark** offre alcune funzionalità in più, rispetto a dumpcap. === Elencare le interfacce === >tshark -D 1. \Device\NPF_{85F53E5B-0751-44A4-AD59-6C44F3AA039F} (Npcap Loopback Adapter) 2. \Device\NPF_{D0D26550-D456-41ED-9E05-8E81747E530F} (Connessione alla rete locale (LAN)* 7) 3. \Device\NPF_{63E09439-4973-441A-B51E-C7750914A09F} (Connessione alla rete locale (LAN)* 6) 4. \Device\NPF_{BF7D7277-5E9A-43C1-A5F7-4A326E5DE1CD} (Ethernet) 5. \Device\NPF_{B4AC505B-8D96-46A3-AB58-4EB4C81E04F2} (Connessione alla rete locale (LAN)* 8) 6. \Device\NPF_{FBEF1017-DE34-4CE1-B24F-77F983AE5857} (VirtualBox Host-Only Network) === Avviare la capture === >tshark -i4 -w "m:\capture-tshark.pcapng" Capturing on 'Ethernet' 9619 317 packets dropped from Ethernet **dumpcap** è il **motore**, che viene richiamato anche da **tshark** ===== VMware ===== E' meglio **evitare di installare Wireshark direttamente sulla v.m.** di cui si vuole catturare il traffico Per catturare il traffico in una rete VMware bisogna settare il **//Port Group// del //vSwitch// in modalità //Promiscuous//**: {{:wireshark:wireshark-vmware02.png|}} Solitamente è una cattiva idea farlo per tutto il //Port Group// di produzione, perchè trasforma il //vSwitch// a tutti gli effetti in un **Ethernet hub**; è quindi possibile **creare un nuovo //Port Group// di test** con gli **stessi parametri** di quello di produzione e inserirvi: * la v.m. di cui si vuole effettuare lo //sniffing// * la v.m. con Wireshark {{:wireshark:wireshark-vmware01.png|}} Tratto da **[[https://blog.packet-foo.com/2013/04/capturing-packets-of-vmware-machines/|qui]]**. ===== Packet analysis ===== ==== Host che effettuano più traffico ==== Solo **dopo** aver catturato il traffico, **abilitare la risoluzione dei nomi da 'View - Name Resolution - Resolve Network Addresses'**. L'aggiunta della risoluzione DNS riempie il //trace// di traffico DNS, quindi deve essere attivata solo **dopo** che si è effettuato una //capture// (durante la visualizzazione) Andare su **'Statistics - Conversations'**; sulla finestra che si apre abilitare nuovamente 'Name Resolution'. Adesso cliccando sull'intestazione **'Bytes'** due volte in testa comparirà la 'conversazione' che ha utilizzato più byte: {{:wireshark:wireshark-packet-analysis01.png|}} Facendo tasto dx su di essa e poi **'Apply as a filter - Selected - A<->B'** il filtro sulla finestra principale di Wireshark sarà relativo a questa conversazione, di cui si potrà analizzare il traffico. ==== Delta Time ==== Di default la colonna **'Time'** è impostata per visualizzare i secondi dopo che è iniziata una //capture//. Per effettuare un'analisi conviene visualizzare il cosiddetto **//'delta time'//**, cioè la differenza di tempo rispetto al precedente pacchetto. Tale valore si può ottenere in due modi. === View === Si può attivare tale visualizzazione andando in **'View - Time Display Format - Seconds Since Previous Displayed Packet'**; converrà quindi filtrare la conversazione con **'Analyze - Follow - TCP Stream'**, in modo che il pacchetto precedentemente sia relativo alla conversazione a cui siamo interessati. === TCP Timestamps === Un'alternativa è quella di espandere la selezione di qualsiasi segmento TCP e selezionare **'Time since previous frame in this TCP stream'**: {{:wireshark:wireshark-paket-analysis-delta-time001.png|}} Conviene inoltre aggiungere tale parametro **come colonna** (tasto dx, 'Apply as a column'). Così facendo si avrà l'indicazione del tempo trascorso dal precedente pacchetto per **tutti i TCP stream**, non solo per lo //stream// selezionato con il precedente metodo di 'View'. Sarà ad esempio possibile ordinare i pacchetti per questo valore e verificare se qualche TCP //stream// impiega troppo tempo: [{{:wireshark:wireshark-paket-analysis-delta-time002.png|//Delta time ordinati per colonna TCP Timestamps; i valori elevati non sono preoccupanti, in quanto dovuti a KeepAlives//}}] == Stream == Per ulteriore chiarezza, conviene aggiungere anche la **colonna che identifica il TCP stream**, espandendo la selezione di qualsiasi segmento TCP e facendo tasto dx su **'[Stream Index: x]'** e 'Apply as a column'. Si avrà così un elenco degli //stream// nel //trace//. ==== TCPtrace ==== Un //tool// di analisi molto potente è il **//tcptrace//**; si può eseguire da **Statistics - TCP Stream Graphs - (tcptrace)**. Si aprirà il seguente grafico: [{{:wireshark:wireshark-packet-analysis-tcptracegraph.png|//L'asse delle x rappresenta il tempo, quello delle y il sequence number, che è equivalente al numero di bytes//}}] In questo caso la direzione, come indicata dal titolo del grafico, è **dal server 94.130.73.100 verso il client 192.168.64.44**. Inoltre la legenda è come segue: * riga **blu in basso**: byte inviati dal server * riga **beige in basso**: byte di cui il client ha inviato l'//acknowledge// * riga **verde** in alto: la **Window size del client (ricevente)** Se non si vede una **linea ascendente** bisognerà probabilmente cliccare sul pulsante del grafico **//Switch Direction//** Zoomando il grafico si notano diversi particolari. Di seguito alcuni esempi. === Window Size === Nel grafico sopra la **Windows size del ricevente** è rappresentata dalla **differenza tra la linea blu dei dati inviati dal server e la linea verde**. E' importante che la linea **verde della Windows size** sia sempre ben distanziata dalla linea **blu dei dati**, altrimenti il traffico si può interrompere === Slow Start === {{:wireshark:wireshark-packet-analysis-slow-start.png|}} Questo zoom è effettuato **all'inizio della comunicazione TCP**. Dal grafico si riconosce il seguente pattern: * il server manda (in blu) **pochi pacchetti** e, dopo l'ACK del client, attende un **certo tempo** prima di inviarne altri * poi manda **più dati** e, dopo l'ACK del client, attende un **tempo inferiore** rispetto a prima * poi manda **ancora più dati** e, dopo l'ACK del client, attende un **tempo ancora inferiore** * tale pattern si ripete, fino a che le attese sostanzialmente si azzerano e il grafico cresce secondo una **linea retta** Tale comportamento è voluto ed è l'implementazione del meccanismo di **//slow start//**, tramite il quale viene effettuato il **controllo della congestione**: un host mittente, in questa fase, verifica che il ricevente non invii pacchetti con indicazione del fatto che la sua //Window size// è piena e quindi tara l'invio iniziale di pacchetti, aumentandolo progressivamente. Di seguito un grafico di un **altro trace**, ottenuto con **//iperf3//**, in cui è visibile lo //slow start// iniziale, dove vengono inviati 10 byte, poi 20, poi 40, poi circa 80 (quindi andamento esponenziale), per proseguire poi con andamento lineare: {{:wireshark:wireshark-slowstart01.png|}} === 2 SEQ 1 ACK === {{:wireshark:wireshark-packet-analysis-tcptracegraph002.png|}} Le due **barre blu verticali** corrispondono a due pacchetti inviati **dal server**; il client ne fa l'**//acknowledge// cumulativo** con la barra, successiva temporalmente, **beige**. Cliccando sul grafico vengono visualizzati i pacchetti corrispondenti nel //trace//. Da qui si vede che quello che visualizza il grafico corrisponde al //trace//; infatti i pacchetti 156 e 157 vengono inviati dal server e ne viene effettuato l'//acknowledge// dal client nel pacchetto 158: [{{:wireshark:wireshark-packet-analysis-tcptracegraph003.png|//Il client nel pacchetto 158 fa l'acknowledge di 11625+2880=14505//}}] ==== Display Filters ==== Per trovare il proverbiale ago nel pagliaio è utile predisporre dei filtri ed eventualmente associarli a pulsanti, come di seguito spiegato. === Le righe nere === Nel //trace// compaiono spesso righe nere con scritte rosse; si tratta di pacchetti che Wireshark vuole evidenziare, perchè potrebbero indicare problemi di **perdita di pacchetti** o legati alla window size. All'inizio di un'analisi di un //trace// conviene evidenziarle. Si può preparare un filtro così. Digitare sulla finestra di testo intitolata 'Apply a display filter...' la stringa **'tcp.analysis.flags'** e premere sul **pulsante '+'** a destra. Si potrà nominare questo nuovo pulsante ('Bad TCP' nell'immagine), che sarà poi possibile richiamare successivamente: [{{:wireshark:wireshark-filters01.png|//Le righe nere solitamente indicano problemi. Le 'Keep-Alive' si possono però trascurare//}}] Per **togliere** dal filtro le segnalazioni dei **Keep-Alive** (maggiori info su questi pacchetti **[[#tcp_keep-alive|sotto]]**) si può editare il filtro non considerandoli. Il filtro **'Bad TCP'** diventerà quindi: (((tcp.analysis.flags)) && !(tcp.analysis.keep_alive)) && !(tcp.analysis.keep_alive_ack) dando come risultato: {{:wireshark:wireshark-filters03.png|}} === Latenze === Conviene tenere d'occhio se il traffico TCP e HTTP supera certi valori e quindi creare filtri appositi. Ad esempio conviene creare due filtri/pulsanti che misurano **'tcp.time_delta > 1'** e **'http.time > 1'**; con essi vengono evidenziati ritardi **superiori a 1 secondo** all'interno di una comunicazione. Per l'**HTTP** si possono **ignorare latenze elevate per le GET, POST, FIN, e RST**; mentre sono da approfondire sicuramente le **risposte HTTP 200** con latenze elevate === Contenuto === Per **cercare una stringa** in qualsiasi punto del trace digitare: tcp contains stringa_da_cercare Wireshark visualizzerà i pacchetti che la contengono. Ad esempio nel seguente //trace// viene ricercata la stringa 'admin', digitata durante un logon: {{:wireshark:wireshark-filters-contains03.png|}} Il primo pacchetto evidenziato è un HTTP POST dal client; dovrebbe corrispondere all'input di credenziali per l'accesso ad un sito. Infatti espandendo il contenuto HTML del pacchetto si possono visualizzare lo username 'admin' e la **password**, solitamente **codificata in base64** (che non vuol dire criptata!). Possiamo quindi fare tasto dx sulla riga della password, e fare **Copy - Value**. ==== Evidenziare SYN ed ACK ==== A volte può essere utile **seguire il flusso dei SYN ed ACK**, soprattutto quando bisogna analizzare **[[wireshark_banda|problemi di banda]]**. Si può quindi aggiungere delle colonne con questi parametri: {{:wireshark:wireshark-syn-ack-len.png|}} Di seguito viene estrapolato parte di una connessione per spiegare il **meccanismo dei sequence/acknowledge**: Partendo dal pacchetto 287, l'host 192.168.64.44 invia una richiesta HTTP GET che: * parte dal Seq (relativo, non assoluto) nr. 1 * invia 335 byte di dati (TCP Len 335) * il suo Next Seq sarà quindi 336 * fa l'Ack del Next Seq del precedente pacchetto (286) dall'host 192.168.64.253; cioè il .44 si aspetterà di ricevere dal .253 un Next Seq pari a 1 Nel successivo pacchetto 288 l'host .253, non avendo byte da inviare al momento: * parte dal proprio Seq 1 * non ha dati (TCP Len 0) * quindi il prossimo Seq resterà 1 * fa l'Ack del Next Seq del precedente pacchetto (287) dall'host .44; cioè il .253 si aspetterà di ricevere dal .44 un Next Seq pari a 336 Nel successivo pacchetto 289 l'host .253 invia una HTTP Response: * parte dal proprio Seq 1 * invia 504 byte di dati * il suo Next Seq sarà quindi 505 * fa l'Ack del Next Seq (sempre 336) che si aspetterà dall'host .44 ... e così via. E' da evidenziare come i numeri di SYN ed ACK sono numeri **relativi**; è anche possibile visualizzare gli **assoluti** (può essere utile in fase di analisi avanzata, dove un firewall, ad es., cambia questi valori) andando in **'Edit - Preferences - Protocols - TCP'** e facendo l'//uncheck// di **'Relative sequence numbers'**. ==== “TCP spurious retransmission” ==== Prima il //trace//: {{:wireshark:wireshark-spurious-retransmission.png|}} Il pacchetto 69286 viene marcato come **“TCP spurious retransmission”**. Innanzitutto è da sottolineare il fatto che la //capture// è stata effettuata **lato host 192.168.64.44**; tale host aveva già ricevuto questi byte, nel pacchetto 69260. Quindi per lui si tratta di un doppione, che viene marcato come //spurious retransmission//. L'host .44 ne prende atto e, nel pacchetto successivo 69287, re-invia un ACK (l'aveva già fatto nel 69260) per 5308; tale comunicazione viene sottolineata da Wireshark come **"TCP Dup Ack"**. **E' un problema? In questo caso no**, perchè dopo la comunicazione riprende normalmente. Bisognerebbe capire lato host 52.94.240.125 cosa è successo (e quindi avere il //trace// lato suo); probabilmente il server non ha ricevuto un ACK per 5308 e quindi ha reinviato il segmento. ==== "TCP Keep-Alive" ==== Di seguito un //trace// in cui compaiono dei **keep-alive**: {{:wireshark:wireshark-keepalive01.png|}} Come si vede, l'host 192.169.64.44 nel pacchetto 2714 invia 397 byte e incrementa il proprio Next Sequence nr. a 398; l'altro host ne fa l'Acknowledge (398). Fino a qui tutto ok. Poi però passiamo al pacchetto 2766; **trascorrono 10 secondi** e ciò **fa scattare il //TCP Keep-Alive//** da parte dell'host .44, che consiste in * l'host .44 **non invia byte e setta il proprio Next Sequence a 397, cioè un byte di meno rispetto a prima** * l'host remoto **fa l'ACK del 398 (non del 397)** e questo è il **//TCP Keep-Alive ACK//** * dopo altri 10 secondi c'è un altro scambio di //TCP Keep-Alive//-//TCP Keep-Alive ACK// * ... Quanto sopra descritto è proprio il **comportamento del Keep-Alive**. E' un //poll// effettuato da un host per verificare che l'altro host sia ancora in ascolto sul //socket//. Solitamente **non indica un problema** di cui preoccuparsi Di seguito un altro esempio: {{:wireshark:wireshark-keepalive.png|}} Ma **a cosa serve** il TCP Keep-Alive? Ogni host periodicamente manda un pacchetto TCP di questo tipo alla sua controparte nella comunicazione per sollecitare una sua risposta (ACK). Se un host A manda un certo numero di Keep-Alive e l'host remoto B non invia l'ACK allora l'host A terminerà la connessione dal suo lato. Se l'host B alla fine manda un pacchetto riusando la vecchia connessione, l'host A invierà un **reset (RST)** per indicare che la vecchia connessione non è più attiva; questo forzerà l'host B a terminarla anche lato suo, in modo che una nuova connessione possa essere stabilita. ==== 'TCP ACKed unseen segment' ==== Se viene visualizzato **'TCP ACKed unseen segment'** dipende probabilmente dal fatto che l'interfaccia di rete da cui si esegue il //capture// non è abbastanza veloce per catturare tutti i pacchetti. Non è indice quindi di un **problema** lato comunicazione TCP in sè, quanto piuttosto **dell'host da cui si è effettuato il //capture// (TAP client)**. Può anche essere un problema di **GUI di Wireshark**, che non riesce a stare dietro alla //capture//; in questi casi si può provare ad usare i **[[#tool_a_riga_di_comando|tool a riga di comando]]**, che sono meno pesanti dal punto di vista computazionale per l'host su cui viene eseguito Wireshark. ==== 'TCP Out-Of-Order' ==== Di seguito un //trace//: {{:wireshark:wireshark-tcp-out-of-order.png|}} Si può notare come l'info del pacchetto 5713 dia **'TCP Out-Of-Order'**; sembra proprio quello che è successo, cioè l'invio di un **pacchetto fuori sequenza**. Infatti, si può vedere come, nel pacchetto 5710, l'host .41 fa l'ACK del prossimo valore che si aspetta dalla sua controparte, cioè 1269860. In realtà da essa riceve il 1271228, che viene quindi marcato come //TCP previous segment not captured'//; allora l'host .41 invia un Dup ACK sempre di 1269860. Magicamente il 1269860 compare, dopo pochissimo, al 5713; **non si tratta di una Retransmission**, ma del fatto che il pacchetto sia rimasto 'imbottigliato' per qualche centinaio di microsecondi e abbia impiegato un po' di più ad arrivare rispetto a quello che lo avrebbe dovuto seguire. Morale: in questo caso nessun problema di cui preoccuparsi. ==== Cavo scollegato ==== Di seguito parte di un trace preso tra un client e un host remoto via TAP, dopo che è stato **scollegato il link verso Internet**: [{{:wireshark:wireshark-cavo-scollegato.png|//Questo trace mostra l'effetto di un cavo scollegato//}}] Si vede che il client (.31) attende 7.4 secondi prima di inviare un pacchetto; si è evidentemente accorto che il server non risponde più. Poi invia una serie di pacchetti con **flag PSH** (Push) secondo un //pattern//: inizia da 230 ms, per poi **attendere un tempo che che è il doppio di quello precedente** e reinviare il pacchetto al server. Alla fine manda un **flag FIN** per interrompere ordinatamente la connessione, ma il server non può rispondere, in quanto il cavo è scollegato. Ne rimanda un altro e, se avessimo aspettato ancora prima di chiudere il //trace//, avremmo visto che il client avrebbe inviato un **flag RST** (Reset), per interrompere del tutto la connessione e liberare così risorse. ==== Protocol Hierarchy ==== Per farsi un'idea dei protocolli che girano sulla rete può essere utile eseguire il comando **Statistics - Protocol Hierarchy**: {{:wireshark:wireshark-protocol-hierarchy.png|}} Portare particolare attenzione se compare un generico //Data//; questo succede quando l'host è compromesso e su di esso girano protocolli non riconosciuti dai //dissectors// di Wireshark. ==== IO Graphs ==== Andando in **Statistics - IO Graphs** si apre questo grafico: {{:wireshark:wireshark-iographs.png|}} Sono state aggiunte delle righe custom con //display filter// per alcuni IP ed è stata abilitata anche la **scala logaritmica (Log scale)**; questo perchè tramite essa si sono potuti evidenziare i //TCP errors// che altrimenti sarebbero stati troppo bassi ed invisibili. Così facendo si è evidenziato la contemporaneità di errori TCP in corrispondenza del traffico verde. === Traffico broadcast === Nel seguente grafico viene messo a raffronto, tramite righe con due //display filter//, traffico broadcast (tipicamente ARP) e tutto l'altro traffico. Il primo è nettamente minoritario: {{:wireshark:wireshark-iographs01.png|}} ==== Catturare il traffico wifi ==== === Interfaccia di rete === L'interfaccia di rete wi-fi deve consentire il **monitoring**. Non tutti i chipset lo supportano; le schede migliori in questo campo sono le **Alfa Network**. === airmon === Abilitare il monitoring sulla scheda di rete così. Prima di tutto **individuare** il nome dell'interfaccia: $ iwconfig wlx00c0ca980771 IEEE 802.11 ESSID:off/any Mode:Managed Access Point: Not-Associated Tx-Power=20 dBm Retry short limit:7 RTS thr:off Fragment thr:off Power Management:off enp7s0 no wireless extensions. lo no wireless extensions. Abilitare quindi il monitoring con: # airmon-ng start wlx503eaa267e9b Found 5 processes that could cause trouble. If airodump-ng, aireplay-ng or airtun-ng stops working after a short period of time, you may want to run 'airmon-ng check kill' PID Name 1004 avahi-daemon 1011 avahi-daemon 1024 wpa_supplicant 1026 NetworkManager 1500 dhclient PHY Interface Driver Chipset phy0 wlx00c0ca980771 ath9k_htc Atheros Communications, Inc. AR9271 802.11n === airodump === Verificare le reti wi-fi visibili con: # airodump-ng wlx00c0ca980771 per ottenere: CH 5 ][ Elapsed: 18 s ][ 2019-10-14 19:36 BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID B4:A5:EF:42:15:8B -47 65 8 0 1 54e WPA2 CCMP PSK TIM-10963318 AE:E2:D3:BD:73:61 -39 13 0 0 1 54e WPA2 CCMP PSK DIRECT-61-HP OfficeJet Pro 8210 90:35:6E:86:BD:88 -77 35 1 0 6 54e WPA2 CCMP PSK Vodafone-30134944 CC:40:D0:68:5C:6F -65 15 6 2 13 54e WPA2 CCMP PSK NETGEAR01 C4:A8:1D:39:80:EC -81 6 0 0 6 54e WPA2 CCMP PSK LANEROSSI 60:E3:27:79:63:EC -85 6 0 0 11 54e WPA2 CCMP PSK 60:31:97:0E:B9:FC -86 5 2 0 6 54e WPA2 CCMP PSK Home&Life SuperWiFi-B9FC B0:2A:43:DB:AE:38 -88 5 0 0 11 54e. WPA2 CCMP PSK Googlewifi E0:E6:2E:49:00:E1 -87 8 0 0 8 54e. WPA2 CCMP PSK WebPocket-00E1 A4:91:B1:21:E4:C7 -88 4 0 0 6 54e WPA2 CCMP PSK TIM-18998471 90:35:6E:B1:D5:28 -88 6 0 0 7 54e WPA2 CCMP PSK Vodafone-30340170 E4:8F:34:C1:8A:CE -87 3 0 0 5 54e OPN Vodafone-WiFi E4:8F:34:C1:8A:CC -88 4 0 0 5 54e WPA2 CCMP PSK Vodafone-44848483 C8:3A:35:FE:0C:30 -90 2 0 0 7 54e WPA CCMP PSK Telemar_WiFi 00:1E:2A:F6:41:7A -90 6 0 0 11 54e WPA TKIP PSK INTERNET 30:91:8F:4F:34:EC -91 3 0 0 11 54e WPA2 CCMP PSK Telecom-56849132 BSSID STATION PWR Rate Lost Frames Probe (not associated) DA:A1:19:95:85:42 -69 0 - 1 17 19 (not associated) 44:07:0B:5D:56:90 -84 0 - 1 0 4 Googlewifi B4:A5:EF:42:15:8B 00:04:20:2B:1F:A9 -56 36e- 1e 0 9 TIM-10963318 CC:40:D0:68:5C:6F D4:11:A3:58:F7:A7 -1 0e- 0 0 6 Ci interessa la prima rete, quindi rilanciamo il comando con i seguenti parametri: # airodump-ng -c 1 -w wpa2 --bssid B4:A5:EF:42:15:8B wlx00c0ca980771 Riavviando un client si dovrebbe riuscire ad ottenere la **//WPA handshake//** (in alto a destra): CH 1 ][ Elapsed: 1 min ][ 2019-10-14 19:41 ][ WPA handshake: B4:A5:EF:42:15:8B BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID B4:A5:EF:42:15:8B -13 0 876 1639 33 1 54e WPA2 CCMP PSK TIM-10963318 BSSID STATION PWR Rate Lost Frames Probe B4:A5:EF:42:15:8B 54:25:EA:59:27:F3 -37 0e- 0e 539 680 B4:A5:EF:42:15:8B AC:E2:D3:BD:F3:61 -37 0e- 0e 0 28 B4:A5:EF:42:15:8B A8:0C:63:1E:CF:20 -56 1e- 6 0 275 B4:A5:EF:42:15:8B A8:0C:63:1E:C9:E9 -59 0e- 6 189 559 B4:A5:EF:42:15:8B 00:04:20:2B:1F:A9 -73 24e-54e 0 88 Ciò significa che si è catturato una //four-stage handshake//. Il tool dovrebbe quindi generare un file **wpa2-01.cap**, che può essere aperto da Wireshark; verificare che sia presente la //four-stage handshake// usando il seguente **filtro**: {{:wireshark:wireshark-eapol.png|}} === Visualizzare il traffico === Per visualizzare il traffico è necessario inserire la **password WPA**, andando su di un frame 802.11 e facendo **tasto dx-Protocol Preferences-Decryption keys...**. Bisongerà quindi **aggiungere una chiave WPA-Pwd**, specificando la password wi-fi così: **:**. Dopodichè si potrà decodificare il traffico in Wireshark.