Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere...

27
Sniffer D. Bonardi L. Pedrelli F.Bossi C.Gervanotti 9 Agosto 2012

Transcript of Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere...

Page 1: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

Sniffer

D. Bonardi L. Pedrelli F.Bossi C.Gervanotti

9 Agosto 2012

Page 2: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

Indice

0.1 Revisioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2 Novita di questa Release . . . . . . . . . . . . . . . . . . . . . 10.3 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4 Livelli di rischio . . . . . . . . . . . . . . . . . . . . . . . . . . 20.5 Wireshark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20.6 Tcpdump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30.7 Esempi di Tcpdump . . . . . . . . . . . . . . . . . . . . . . . 30.8 Altri Sniffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30.9 Modalita’ promiscua . . . . . . . . . . . . . . . . . . . . . . . 40.10 Socket Raw . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50.11 Struttura del codice sorgente . . . . . . . . . . . . . . . . . . 110.12 Librerie utili . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120.13 Protocolli a livello trasporto . . . . . . . . . . . . . . . . . . . 140.14 Handlers a livello trasporto . . . . . . . . . . . . . . . . . . . 140.15 Aggiungere protocolli a livello trasporto . . . . . . . . . . . . 150.16 Protocolli a livello applicazione . . . . . . . . . . . . . . . . . 150.17 Handlers a livello applicazione . . . . . . . . . . . . . . . . . . 160.18 Aggiungere protocolli a livello applicazione . . . . . . . . . . 160.19 Dettagli sui protocolli a livello applicazione . . . . . . . . . . 160.20 Protocollo http . . . . . . . . . . . . . . . . . . . . . . . . . . 160.21 Protocollo smtp . . . . . . . . . . . . . . . . . . . . . . . . . . 170.22 Note sull’ utilizzo di sniffer.c . . . . . . . . . . . . . . . . . . 200.23 Cosa possiamo aggiungere . . . . . . . . . . . . . . . . . . . . 25

0.1 Revisioni

1. 29 Febbraio 2005 [email protected]

2. 01 Aprile 2008 [email protected]

3. 16 Settembre 2008 [email protected]

4. 9 Agosto 2012 [email protected]

1

Page 3: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

0.2 Novita di questa Release

1. Verificare ed estendere la parte introduttiva: inquadrare gli sniffer nel-la network security, panoramica sugli sniffer disponibili , panoramicasugli strumenti di programmazione socket raw nei diversi linguaggi,motivazione e giustificazione del progetto.

2. revisione del progetto: ricompilare il codice e testare le funzionalita’,verificare/integrare la documentazione nella relazione riguardo l’ar-chitettura del codice, l’installazione , l’utilizzo e le future possibiliestensioni.

0.3 Introduzione

La pratica del packet sniffing (letteralmente annusamento di pacchetti) con-siste nel leggere tutti i pachetti che passano sull’ adattatore di un disposi-tivo introdotto in una rete. I pacchetti analizzati appartengono allo stratodi collegamento, e’ quindi possibile per un dispositivo analizzare anche pac-chetti di cui, secondo lo strato di rete e di trasporto, non dovrebbe essere aconoscienza o meglio che normalmente verrebbero scartati.

Si definisce sniffing l’attivita di intercettazione passiva di dati che transi-tano in una rete telematica. I prodotti software utilizzati per eseguire questeattivita vengono detti sniffer. Essi oltre a intercettare e memorizzare il traf-fico offrono funzionalita di analisi del traffico stesso. Gli sniffer intercettanoi singoli pacchetti e decodificano le varie intestazioni di livello applicativo,di trasporto, di rete e datalink. Inoltre possono offrire strumenti di analisiche ci permettono di valutare il comportamento del protocollo. Uno snifferserve generalmente agli amministratori per diagnosticare problemi sulle lororeti e per conoscere il traffico che li circonda. Gli Sniffer pero oltre ad averemolti aspetti positivi hanno anche un grosso aspetto negativo; puo essereusato, infatti, da una persona malintenzionata che ha accesso fisico alla reteper raccogliere informazione private. In una rete LAN viene utilizzato so-prattutto Ethernet. Il protocollo ethernet e stato sviluppato sul concetto dicondivisione: tutte le macchine di rete locale condividono la stessa connes-sione in modo tale da filtrare e ignorare tutto il traffico che non appartienealla LAN. Uno sniffer puo eliminare questo filtro e portare l’hardware inpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il trafficoche intercorre tra le macchine ’B’ e ’C’, sempre se condividono lo stesso cavoo lo stesso segmento di rete.

0.4 Livelli di rischio

I dati maggiormente a rischio sono le password personale utilizzate per ac-cedere agli svariati servizi poiche la rischiesta di accesso , cioe l’invio della

2

Page 4: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

password in rete , risulta nei primi pacchetti e quindi i primi riscontratidallo sniffer. Oltre alla password uno sniffer puo ricavare dati ad esempio ilnumero di carta di credito o messaggi mail privati.

0.5 Wireshark

Come abbiamo visto studiato a lezione uno sniffer molto diffuso e WireShark.WireShark e multipiattafomra e opensource, e viene usata da sistemisti,esperti di sicurezza , sviluppatori. Ha diverse Caratteristiche importanti:

1. permette di effettuare analisi di dati catturati anche a distanza ditempo.

2. dispone di un interfaccia grafica semplice da usare

3. e in grado di decifrare numerosi protocolli

4. puo essere generato in output in diversi formati ad esempio xML,POSTSCRIPT , TESTO NORMALE

5. supporta diversi tipi di rete (ethernet, 802.11, token ring)

6. consente di filtrare pacchetti

7. genera utili statistiche sul traffico analizzato

0.6 Tcpdump

Inoltre in classe abbiamo visto il tool di debug di rete tcpdump. Questo con-sente di intercettare pacchetti e trasmissioni che passano attraverso la retecollegata al computer ad esempio tramite TCP. E multipiattaforma, utilizzamodalita promiscua. Su Unix l’utente deve avere i privilegi da SuperUser.Tcpdump e uno strumento flessibile e diffuso nel mondo Linux. Tcpdump siappoggia alla libreria libcap, la libreria di base per la cattura dei pacchetti.La versione GUI e wireshark. Le opzioni sono diverse, e consentono oltreche selezionare l’interfaccia su cui eseguire lo sniffing, di catturare un certonumero di pacchetti, la porta o l’indirizzo IP come sorgente e destinazionedei pacchetti e utilizzare altri filtri che consentono di selezionare anche unospecifico protocollo.

0.7 Esempi di Tcpdump

1. tcpdump -i ppp0 -c 50

visualizza i primi 50 pacchetti sull’interfaccia ppp0.

3

Page 5: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

2. tcpdump -l | tee sniffer.log

analizza i pacchetti e li memorizza nel file sniffer.log

3. tcpdumo -e -n

visualizza gli indirizzi datalink ( -e) e tramite il comando -n fa larisoluzione automatica el DNS.

4. tcpdumo port 80

analizza i pacchetti relativi alla porta 80.

In Tcpdump possono anche essere utilizzate le espressioni. Le espressionisono composte da primitive che possono essere raggruppate per mezzo delleparentesi tonde e connesse tra loro tramite operatori booleani in modo taleche vengano considerate solo i pacchetti che soddisfano quelle condizioni. Sel’espressione manca vengono catturati tutti i pacchetti.

0.8 Altri Sniffer

1. NTOP (NETWORK TOP): E un programma che effettua monitoraggidi rete, e in grado di mostrare i computers attivi all’interno di una retee fornire info riguardo l’utilizzo dell’indirizzo IP e il traffico generato daogni computer. I protocolli supportati e configurabili sono ad esempioTCP/UDP/ICMP, ARP, IPX, DLC, decnet,fibre chanel. Per ottenerentop e sufficiente scaricare e installare il pacchetto ntop.

2. SMARTSNIFF: e un utility di monitoraggio della rete che permette dicatturare pacchetti, di tipo TCP/IP che passano attraverso la vostrascheda di rete, e visualizzare i dati acquisiti come una sequenza di con-versazioni tra client e server. E possibile visualizzare le conversazioniTCP/IP in modalita ASCII o esadecimale.

3. ETHERAPE: E un programma opensource usato per il monitoraggiodel traffico di rete, che grazie alla propria interfaccia grafica e in gradodi offrire un efficacia e semplice visione. CARATTERISTICHE:

• il traffico di rete viene rappresentato graficamente;

• i protocolli utilizzati vengono rappresentati tramite links con co-lorazione diversa;

• possono essere utilizzati filtri;

• la risoluzione dei nomi viene attivata ricorrendo alle funzioni dellalibreria libc standard;

• si possono effettuare statistiche globali del traffico per procollo

4

Page 6: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

• si possono effettuare statistiche globali del traffico per nodo Perfunzionare su piattaforma Linux si deve avere determianti requi-siti: libcap packete source library, GTK+, libgcode, GNOME.

4. COMMVIEW WIFI: raccoglie le info della scheda wireless e quindidecodifica i dati analizzati. Commview Wifi consente di visualizzarel’elenco di connessioni di rete e della statistiche IP piu importanti edesaminare i singoli pacchetti. E possibile decifrare i pacchetti tramitechiavi WEP o WAP-PSK definite dall’utente e decodificarli fino allivello inferiore con l’analisi completa dei protocolli piu diffusi. Utilizzafiltri per fare le ricerche piu mirate.

0.9 Modalita’ promiscua

Le due parti principali per la creazione di uno sniffer sono l’ utilizzo disocket raw e l’ impostazione in modalita’ promiscua dell’ interfaccia di retedel dispositivo su cui si vuole lanciare lo sniffer. Impostando l’ interfacciadi rete in pratica si dice al kernel di accettare tutti i pacchetti passanti alivello di collegamento (frame ethernet) sull’ interfaccia di rete.

In termini di programmazione, porre l’ interfaccia in modalita’ promiscuaconsiste nel settare un particolare flag. Tramite il seguente codice

device_controller = socket(PF_INET, SOCK_DGRAM, 0);

apro una socket che sara’ adibita alla gestione dell’ interfaccia di rete, orainizializzo device_configuration, variabile di tipo struct ifreq, che e’ unastruttura adibita alla lettura dei flags sull’ interfaccia. L’ inizializzazione vie-ne effettuata inserendo il nome del dispositivo (options.capture_device).

strncpy(device_configuration.ifr_name, options.capture_device,sizeof(device_configuration.ifr_name));

Ora tramite ioctl(), che mi permette le gestione di una generica perife-rica, vado a leggere in che modo e’ settato il dispositivo di rete.

(ioctl(device_controller, SIOCGIFFLAGS, &device_configuration);

Avendo tutto cio’ che mi interessa per porre il dispositivo in modalita’promiscua nella struttura in

device_configuration

agisco su di essa e imposto le flags del dispositivo.

device_configuration.ifr_flags |= IFF_PROMISC;ioctl(device_controller, SIOCSIFFLAGS, &ifr);

Ora Possiamo iniziare la ricezione tramite una socket raw. Alla fine delleoperazioni toglieremo il flag per la promiscuita’ della scheda di rete.

5

Page 7: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

0.10 Socket Raw

Ogni applicazione che usa il protocollo TCP per trasmettere dei dati crea uncanale di comunicazione, definito socket. La socket si colloca ad un livellopiu alto rispetto ad una socket raw utilizzata da uno sniffer, semplicementeperche con uno sniffer dobbiamo andare a leggere tutti i dati trasmessi daaltri programmi, quindi altre socket.

Una socket di tipo raw non solo permette di leggere tutti i pacchetti maanche di forgiarne altri a nostro piacere.

Con una socket di tipo raw riusciamo a leggere l’header di ogni pacchettoricevuto, inteso come intestazione di ogni pacchetto TCP. Una socket raw sicolloca a livello piu basso di una socket normale. La socket cruda permettenon solo di leggere senza filtro un frame ethernet ma anche di creare a nostropiacere nuovi pacchetti construendoli pezzo per pezzo.

Per la creazione di uno sniffer ci serve solamente una lettura di tutto ilframe ethernet. La creazione di una socket raw e’ semplice e analoga allacreazione di una semplice socket:

socket_raw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

Parte interessante di una socket raw e’ l’ interpretazione dei dati. Per lalettura mi affido ad un buffer (packet) di dimensione 1500 che e’ la massimaestensione in byte di un frame ethernet.

recvfrom(socket_raw, packet, sizeof(packet), 0, NULL, NULL);

Per interpretare in modo corretto i dati e sopprattutto le intestazionipresenti sul pacchetto ci affidiamo a due strutture per la lettura del proto-collo di collegamento (nel mio caso Ethernet) e di quello di rete (nel miocaso IP), mentre ne avremo tre differenti per la lettura del protocollo ditrasporto (UDP, ICMP, e TCP).

La prima struttura da analizzare e’ ethhdr, questa contiene le pocheinformazioni sull’ header Ethernet. Possiamo utilizzarla nel seguente modo.

struct ethhdr *ethernet_header = (struct ethhdr *)&packet[0];

Questo perche’ so che i primi dati contenuti sul buffer riguardano Ether-net. Il passaggio seguente e’ esaminare IP, questo avverra’ in modo simile:

struct iphdr *ip_header = (struct iphdr *)&packet[sizeof(struct ethhdr)];

Per IP consideriamo sempre i dati sul buffer con un spiazzamento datodalla dimensione dell’ intestazione Ethernet. Come e’ facile intuire l’ impac-chettamento inteso come pratica di aggiungere informazioni ad un pacchetto

6

Page 8: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

dati man mano che quest scende la pila protocollare e’ visibile da come e’strutturato il buffer e da come noi andremo ad estrapolarne i dati. Quindie’ intuibile che per un pacchetto TCP, potremo far riferimento al suo headertramite

struct tcphdr *tcp_header = (struct tcphdr *)

&packet[sizeof(struct ethhdr) +ip_header->ihl*4];

Per come e’ strutturato il mio sniffer si decide a seconda del procollo ditraspoto indicato dall’ header IP, quale struttuta utilizzare per quel livello(tcphdr, udphdr, icmphdr).

• Struttura header IP ( /usr/include/netinet/ip.h )

struct iphdr{#if __BYTE_ORDER == __LITTLE_ENDIANu_int8_t ihl:4; /* lunghezza preambolo 4 bit*/u_int8_t version:4; /* versione 4 bit */#else __BYTE_ORDER == __BIG_ENDIANu_int8_t version:4; /* versione 4 bit */u_int8_t ihl:4; /* lunghezza preambolo 4 bit */#endifu_int8_t tos; /* tipo di servizio 8 bit */u_int16_t tot_len; /* lunghezza totale 16 bit */u_int16_t id; /* identificazione 16 bit */u_int16_t frag_off; /* offset di frammentazione 16 bit*/u_int8_t ttl; /* tempo di vita del pacchetto 8 bit */u_int8_t protocol; /* protocollo di livello trasporto 8 bit */u_int16_t check; /* checksum 16 bit */u_int32_t saddr; /* indirizzo sorgente 32 bit */u_int32_t daddr; /* indirizzo destinazione 32 bit *//* Le opzioni iniziano qui */};struct ip_options{u_int32_t faddr; /* indirizzo del primo router */u_int8_t optlen;u_int8_t srr;u_int8_t rr;u_int8_t ts;u_int8_t is_setbyuser:1;u_int8_t is_data:1;

7

Page 9: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

u_int8_t is_strictroute:1; /* opzione di source routing */u_int8_t srr_is_hit:1;u_int8_t is_changed:1; /* IP checksum non ~A¨ valido */u_int8_t rr_needaddr:1; /* record route */u_int8_t ts_needtime:1; /* ogni router registra un timestamp al pacchetto (debug)*/u_int8_t ts_needaddr:1; /* record route di timestamp */u_int8_t router_alert;u_int8_t __pad1;u_int8_t __pad2;#ifdef __GNUC__u_int8_t __data[0];#endif};

La struttura iphdr rappresenta l’header IP di un pacchetto, innanzitut-to si puo osservare la distinzione tra LITTLE_ENDIAN e BIG_ENDIAN chedistinguono il modo in cui viene trasmesso il pacchetto, BIG_ENDIANda sinistra a destra, con il bit piu significativo del campo Version ; nellemacchine LITTLE_ENDIAN invece e necessaria una conversione softwaresia in trasmissione che in ricezione (Lo SPARC e di tipo big endian,mentre il PENTIUM e di tipo little endian). Passiamo ora a descriverei vari campi dell’header IP:

VERSION: Descrive la versione del protocollo utilizzato dal datagramipv4 (4 bit).

LUNGHEZZA DELL’HEADER: Siccome la lunghezza dell’header none constante in questo campo e contenuta la lunghezza dell’header inparole di 32 bit il valore minimo e 5 (nessuna opzione header=20 byte)il massimo e 15. (header uguale a 60 byte) (4 bit).

TIPO DI SERVIZIO: Consente agli host di comunicare alla rete iltipo di servizio desiderato in base ai parametri: ritardo, capacita ditrasmissione affidabilita (8 bit).

LUNGHEZZA DEL PACCHETTO: Riguarda l’intero pacchetto lamassima lunghezza e di 65.536 byte(16 bit).

IDENTIFICAZIONE: E necessario per permettere all’host di destina-zione di determinare a quale datagram appartiene un frammento ap-pena arrivato.Tutti i frammenti di un datagram contengono lo stessonumero di identificazione (16 bit).

OFFSET DI FRAMMENTAZIONE DEL PACCHETTO: Indica inquale posizione del datagram corrente si trova questo frammento, tuttii frammenti tranne l’ultimo devono essere multipli di 8 byte, il campo

8

Page 10: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

e di 13 bit , avro quindi un massimo di 8192 frammenti (8192 x 8 =65536 byte al massimo(IP packet))(13 bit).

TEMPO DI VITA DEL PACCHETTO: E un contatore utilizzato perlimitare il tempo di vita dei pacchetti sulla rete:256 ; quando il con-tatore raggiunge lo 0 il pacchetto viene scartato e viene inviato alladestinazione un messaggio di avvertimento (8 bit).

PROTOCOLLO: Campo che indica il protocollo che viene usato allivello trasporto (TCP, UDP e altri) la numerazione dei protocolli eglobale ed e descritta nel RFC 1700.

INDIRIZZO SORGENTE E DESTINAZIONE: Sono rispettivamentegli indirizzi del mittente e del destinatario del pacchetto composti da32 bit ognuno.

CHECKSUM: Verifica solamente il preambolo IP, e utilizzato per ve-rificare gli errori generati dai router.L’algoritmo consiste nel sommaretutte le parole di 16 bit che arrivano usando l’aritmetica di complemen-to a 1 e quindi prendendo il complemento a 1 del risultato. Il risultatofinale deve essere 0. Da notare che l’algoritmo deve essere cambiatoad ogni salto perche c’e almeno un campo che cambia il TTL(time tolive).

La seconda struttura illustra le opzioni che si possono aggiungere a unpacchetto IP le piu usatesono descritte di seguito:

SECURITY: Descrive il grado di segretezza delle informazioni, in teo-ria un router militare dovrebbe utilizzare questo campo per richiederedi non attraversare paesi considerati a rischio.

STRICT SOURCE ROUTING: Fornisce il percorso completo da se-guire.

LOOSE SOURCE ROUTING: Richiede che il pacchetto attraversi unalista di router specificati nell’ordine specificato ma e possibile che passiattraverso altri router lungo il percorso.

RECORD ROUTE: Forza i router lungo il cammino ad aggiungere illoro indirizzo IP al campo opzione.

TIMESTAMP: e simile all’opzione record route a parte il fatto cheoltre a registare l’indirizzo a 32 bit ogni router regista un timestampdi 32 bit (motivi diagnostici).

• struttura header TCP (/usr/include/netinet/tcp.h)

struct tcphdr{u_int16_t source; // porta sorgente 16 bitu_int16_t dest; // porta destinazione 16 bit

9

Page 11: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

u_int32_t seq; // numero di sequenza 32 bitu_int32_t ack_seq; // numero di ack 32 bit#if __BYTE_ORDER == __LITTLE_ENDIANu_int16_t res1:4; //u_int16_t doff:4;u_int16_t fin:1; // flag FINu_int16_t syn:1; // flag SYNu_int16_t rst:1; // flag RSTu_int16_t psh:1; // flag PSHu_int16_t ack:1; // flag ACKu_int16_t urg:1; // flag URGu_int16_t res2:2;#elif __BYTE_ORDER == __BIG_ENDIANu_int16_t doff:4;u_int16_t res1:4;u_int16_t res2:2;u_int16_t urg:1;u_int16_t ack:1;u_int16_t psh:1;u_int16_t rst:1;u_int16_t syn:1;u_int16_t fin:1;#else#error "Adjust your defines"#endifu_int16_t window;u_int16_t check;u_int16_t urg_ptr;};

La struttura precedente rappresenta i vari campi che compongonol’header di un pacchetto TCP il preambolo fisso di 20 byte piu unaparte opzionale. I vari campi sono descritti di seguito:

SORGENTE E DESTINAZIONE:

Rispettivamente porta sorgente e porta destinazione identificano gliestremi locali di una connessione, ogni host deve decidere come allo-care le propie porte successive alla 256. Il punto di accesso del livel-lo trasporto sara quindi identificato dall’indirizzo formato ADDRESSIP:PORTA.

NUMERO DI SEQUENZA: Il numero di sequenza viene assegnato adogni pacchetti durante la connessione tra 2 host e composto da 32 bit.

NUMERO ACK: E uguale a 1 per indicare che il numero di ack e

10

Page 12: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

valido, se ack=0 il segmento non contiene ack e il campo numero diack viene ignorato.

PSH: ndica dati di tipo push, in questo modo si richiede al mittentedi consegnare i dati dell’applicazione al momento dell’arrivo, evitandoche siano salvati in un buffer di attesa.

RST: Viene utilizzato per reinizializzare una connessione che e diven-tata instabile a causa del guasto di un host o per qualche altro motivo.Viene anche utilizzato per rifiutare l’apertura di una connessione.

SYN: Viene utilizzato per creare una connessione. la richiesta di con-nessione e caratterizzata da SYN=1 ACK=0 la risposta sara’ SYN=1ACK=1.

FIN: Viene utilizzato per chiudere una connessione.Specifica il mitten-te non ha altri dati da spedire, tuttavia dopo aver chiuso una connes-sione, un processo puo continuare a rivcevere dati indefinitivamente.

WINDOW: Il controllo di flusso TCP e gestito utilizzando un protocol-lo slinding window a dimensione variabile. Il campo window specificaquanti byte possono essere spediti a partire dal byte confermato.

CHECKSUM: Per garantire l’affidabilita e presente anche un campochecksum, che verifica il preambolo i dati e lo pseudopreambolo. Quan-do viene eseguito il calcolo, il campo checksum viene posto uguale a0, e il campo dati viene completato con un 0 se la lunghezza e unnumero dispari. L’algoritmo di checksum somma tutte le parole di 16bit in complemento a 1 e quindi prende il complemento a 1 della som-ma. Come conseguenza quando il ricevente esegue il calcolo sull’interosegmento (compreso il checksum) il risultato deve essere 0.

• struttura udp header (/usr/unclude/netinet/udp.h)

struct udphdr {u_int16_t source;u_int16_t dest;u_int16_t len;u_int16_t check;};

Questa struttura rappresenta i campi dell’header di un pacchetto UDP,a differenza di un collegamento TCP dove viene instaurata una con-nessione inziale nella comunicazione UDP il pacchetto viene speditoed e indipendente dagli altri.

SORGENTE E DESTINAZIONE: Indirizzi sorgente e destinazione delhost mittente e destinatario 32 bit ognuno.

11

Page 13: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

LUNGHEZZA: Lunghezza del preambolo udp.

CHECKSUM: Campo checksum del preambolo udp. I diffeenti proto-colli di trasporto fanno variare l’ indirizzo del campo dati all’ internodel buffer. Comunque per i dati si usa una tecnica di spiazzamentoanaloga a quelle viste per i vari header con la sola differenza che questacambia a seconda del protocollo a livello trasporto.

Per capire la dimensione del campo dati di un pacchetto, si utilizza unaproprieta’ del protocollo IP, o meglio un campo del suo header.

application_data_size = htons(ip_header->tot_len) -(ip_header->ihl*4 + tcp_header->doff*4);

Tramite la variabile

{tot_len}

che e’ la lunghezza complessiva del pacchetto ip, e’ possibile sottraendoglila dimensione dell header IP e dell’ header di trasporto (nell’esempio TCP),ottenere la dimensione effettiva del campo dati.

0.11 Struttura del codice sorgente

I file piu’ importanti del codice sorgente vengono descritti nel seguito:

1. main.c

contiene la funzione principale, la quale si limita essenzialmente a chia-mare delle funzioni definite in altri file per leggere l’input dell’utente,avviare la cattura dei pacchetti e terminarla. Le funzioni principali delmain sono parse_user_input(argc, argv) che analizza quanti pa-rametri passiamo tramite riga di comando (argc) e quali sono (argv),start_capture() e end_capture che permettono di creare e chiudereun socket raw, capture packets() che e’ la funzione principale catturae stampa a video i pacchetti.

2. capture.c

E’ il cuore del programma. La funzione start_capture si occupadella creazione del socketraw, end_capture si preoccupa viceversadella sua chiusura. La funzione piu’ importante dell’intero program-ma e’ capture_packets, la quale si occupa dell’analisi complessivadei pacchetti catturati. Il file contiene anche una funzione ausiliariamake_printable che rimuove i caratteri non stampabili dalla stringache le viene passata come argomento.

12

Page 14: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

3. interface.c

la funzione parse_user_input si occupa di interpretare le opzioni scel-te dall’utente tramite riga di comando. Le preferenze dell’utente ven-gono memorizzate nella struct options che e’ di tipo user_options.Per maggiori informazioni a riguardo si vedano l’ultima sezione di que-sto documento e i commenti nel sorgente Il file interface.h include den-tro di esso i file transport_procol e application_protocol i qualisi occupano della creazione dei pacchetti, e della costruzione dei rela-tivi handlers. Per ogni tipo di pacchetto viene creata un file: tcp.h ,udp.h, icmp.h , http.h, smtp.h.

0.12 Librerie utili

la libreria utilizzata per la gestione dei socket e socket.h Per quanto riguardala programmazione in java la libreria che si occupa dei socket e java.net,invece per la programmazione in python e sufficiente il comando

import socket

In C potremmo anche utilizzare un altro tipo di libreria che si chiamalibdnet. Questa libreria fornisce una versione semplificata per le operazionidi basso livello come manipolazione di indirizzo di rete, ricerca dell’interfac-cia di rete, trasmissione dei frame Ethernet e raw packet IP. Questa libreriasupporta i linguaggi C, python,Perl, Ruby. La libreria LibNet Tra i principalivantaggi offerti dalla libreria si possono annoverare :

• Un’interfaccia ad alto livello : LibNet e infatti stata sviluppata con ilpreciso obbiettivo di astrarre, dal punto di vista del programmatore,gran parte dei dettagli specifici dell’architettura sottostante.

• Flessibilita : completo controllo su ogni campo degli header dei pac-chetti supportati.

• Robustezza : supporto per oltre 30 protocolli, e numerosi link layercome ad esempio Ethernet, Token Ring, FDDI

Sfruttando questa libreria, la costruzione e l’invio di un pacchetto di re-te arbitrario diventa un’operazione relativamente semplice, che puo’ essereriassunta nei tre passi successivi :

1. Initialization2. Packet construction3. Packet injectionPer prima cosa e necessario creare un descrittore da utilizzare nelle ope-

razioni successive, ovvero un puntatore di tipo libnet_t, che punta ad unastruttura dati, dove viene mantenuto lo stato dell’intera sessione di creazione

13

Page 15: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

dei pacchetti. L’operazione viene effettuata per mezzo di una chiamata allafunzione libnet_init, che ha inoltre il compito di inizializzare la libreria,specificando l’interfaccia da utilizzare e l’injection type ovvero un intero cheindica alla libreria l’interfaccia da utilizzare per la costruzione e l’invio deipacchetti.

Infatti, secondo l’injection type specificato la LibNet puo’ inizializzare leinjection primitives per l’interfaccia link-layer o raw-socket. Il primo injec-tion type, LIBNET_LINK, permette allo sviluppatore di costruire i pacchettipartendo dal datalink layer, consendendo quindi una maggiore granularita’nel controllo rispetto all’interfaccia raw socket, che lavora invece sul terzolivello del modello ISO/OSI. Per le raw socket sono inoltre previste due inter-facce distinte: LIBNET_RAW4 per il protocollo IPv4 e LIBNET_RAW6 per il piu’recente IPv6. Esistono infini tre ulteriori injection types: LIBNET_LINK_ADV,LIBNET_RAW4_ADV, e LIBNET_RAW6_ADV. Essi permettono di inizializzare lalibreria in modalita’ avanzata, consentendo l’utilizzo di alcune funzioni ag-giuntive. Avvenuta l’inizializzazione e creato il descrittore e’ possibile pas-sare alla costruzione dei pacchetti. Tale operazione avviene in maniera mo-dulare, sfruttando le Packet Builder Functions per i vari protocolli messe adisposizione dalla libreria. Ogni fuzione del tipo libnet_build_xxx puo’ es-sere utilizzata per costruire una parte di pacchetto (solitamente un header).Generalmente e’ necessario chiamare piu’ funzioni differenti per la costruzio-ne dell’intero pacchetto, poiche’ esso e’ costituito da piu’ parti incapsulateOgni funzione riceve una serie di argomenti, che corrispondono ai valori daassegnare ai vari campi dell’header. Sebbene un simile prototipo di funzio-ne sia estremamente intuitivo, ha lo svantaggio di avere una lunga serie diparametri e l’elevata dimensione dei frames di attivazione sullo stack. E’inoltre fondamentale sottolineare come l’ordine con cui vengono chiamate lefunzioni sia essenziale, per collegare correttamente tra loro le diverse partidel pacchetto. Tali funzioni devono infatti essere chiamate nell’ordine checorrisponde a come i vari header siano incapsulati nel pacchetto, partendoda quello di piu’ alto livello e scendendo verso il basso nel modello ISO/OSI.Questo processo di costruzione e’ molto intuitivo, poiche’ imita cio’ che real-mente accade nel kernel del sistema operativo. Ad esempio, per costruireun pacchetto TCP utilizzando l’interfaccia link-layer andranno chiamate lebuild functions nel seguente ordine :

1. libnet_build_tcp2. libnet_build_ipv43. libnet_build_ethernetSe anziche’ il link-layer si fossero utilizzate come injection type le raw soc-

ket, sarebbero state sufficienti solo le prime due chiamate per la costruzionedel pacchetto.

L’ultimo passo da eseguire e’ l’invio in rete del pacchetto costruito con lafunzione libnet_write, che provvedera’ ad inviarlo tramite l’interfaccia rawsocket o link-layer, a seconda di quanto specificato nella struttura libnet_t

14

Page 16: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

puntata dal descrittore precedentemente creato e passatole all’invocazione.Si sottolinea inoltre come l’utilizzo dell’interfaccia link-layer garantisca unamigliore portabilita’, ma essendo caratterizzata da una complessita’ mag-giore richieda piu’ lavoro da parte del programmatore. Terminato l’invio deipacchetti e’ buona norma liberare la memoria usata dalle strutture associateal descrittore utilizzato, con la funzione libnet_destroy.

0.13 Protocolli a livello trasporto

Le informazioni sui protocolli a livello trasporto supportati sono contenutenel file transport_protocols.c in supported_transport_protocols chee’ un array di struct di tipo transport_protocol. Ciascun elemento del-l’array corrisponde a un protocollo a livello trasporto supportato. I campidella struct sono tre: name e’ il nome del protocollo, corrispondente allastringa che l’utente puo’ fornire come argomento all’opzione -t se vuole fil-trare rispetto al protocollo a livello trasporto. identifier e’ il valore che ilcampo protocol dell’header IP del pacchetto deve avere per poter ricono-scereil protocollo di trasporto. Infine handler e’ un puntatore alla funzionehandler del protocollo, ovvero quella che si occupa di estrarre dai pacchettile informazioni relative al protocollo.

0.14 Handlers a livello trasporto

Oltre ad estrarre le informazioni sul protocollo, gli handlers a livello tra-sporto DEVONO controllare che il filtraggio dei pacchetti rispetto alle porteabbia successo: in caso affermativo devono restituire il valore 1, altrimentiDEVONO restituire il valore 0.

Gli argomenti che un handler riceve sono dieci (vedere il file tcp.c peravere un esempio completo).packet e’ il puntatore all’inizio del pacchet-to. Se il pacchetto contiene dati applicativi da analizzare, l’handler DEVEimpostare il puntatore a cui punta application_datain modo che pun-ti all’inizio dei dati applicativi sul pacchetto. Se source_port_filtervale uno, allora l’handler DEVE accettare solo i pacchetti che hanno co-me porta sorgente selected_source_port. Analogamente DEVE avvenirecon destination_port_filter e selected_destination_port per quan-to riguarda la porta di destinazione. Se disjuncted_port_filtering valeuno, allora l’handler DEVE accettare solo i pacchetti che hanno come por-ta sorgente source_port OPPURE che hanno come porta di destinazionedestination_port e le opzioni source_port_filter e destination_port_filtervanno ignorate. verbose_mode e’ 1 se e’ impostata la modalita’ verbosa (silascia a chi scrive l’handler la liberta’ di scegliere quali eventuali informazio-ni aggiuntive fornire in questa modalita’). Le informazioni sul protocollo che

15

Page 17: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

devono essere mostrate all’utente nel caso in cui il filtraggio abbia successovanno inserite nella stringa transport_info (si consiglia l’uso di sprintf).

0.15 Aggiungere protocolli a livello trasporto

Per aggiungere un nuovo protocollo e’ necessario aggiungere un file sorgentecontenente una funzione handler che rispetti le specifiche di cui sopra emodificare transport_protocols.c aggiungendo la direttiva di inclusionedel nuovo file, aumentando di 1 il valore della costante

num_supported_transport_protocols e infine aggiungendo all’arraysupported_transport_protocols un elemento corrispondente al nuovo pro-tocollo (in particolare il campo handler dovra’ essere un puntatore alla nuovafunzione handler).

0.16 Protocolli a livello applicazione

Le informazioni sui protocolli a livello applicazione supportati sono contenu-te nel file application_protocols.c in supported_application_protocolsche e’ un array di struct di tipo application_protocol. Ciascun elemen-to dell’array corrisponde a un protocollo a livello applicazione supportato.I campi della struct sono tre: name e’ il nome del protocollo, corrispon-dente alla stringa che l’utente puo’ fornire come argomento all’opzione -Lse vuole filtrare rispetto al protocollo a livello applicazione.port e’ la portacaratteristica del protocollo. Infine handler e’ un puntatore alla funzionehandler delprotocollo, ovvero quella che si occupa di estrarre dai pacchettile informazioni relative al protocollo.

0.17 Handlers a livello applicazione

Gli handlers a livello applicazione DEVONO restituire il valore 1 se ricono-scono il pacchetto come contenente dati applicativi validi per il protocollo,altrimenti DEVONO restituire 0. Ogni handler a livello applicazione ri-ceve tre parametri: application_data e’ il puntatore ai dati applicativisul pacchetto, mentre application_data_size e’ la lunghezza dei suddet-ti dati applicativi. Infine application_info e’ la stringa in cui l’handlerpuo’ mettere le informazioni sul protocollo applicativo che saranno mostrateall’utente (si consiglia l’uso di sprintf).

0.18 Aggiungere protocolli a livello applicazione

Per aggiungere un nuovo protocollo e’ necessario aggiungere un file sorgentecontenente una funzione handler che rispetti le specifiche di cui sopra e mo-

16

Page 18: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

dificare application_protocols.c aggiungendo la direttiva di inclusionedel nuovo file, aumentando di 1 il valore della costante

num_supported_application_protocols e infine aggiungendo all’arraysupported_application_protocols un elemento corrispondente al nuovoprotocollo (in particolare il campo handler dovra’ essere un puntatore allanuova funzione handler).

0.19 Dettagli sui protocolli a livello applicazione

All’ interno dello sniffer e’ possibile filtrare alcuni pacchetti appartenti a pro-tocolli applicativi (http, ftp,...). Le vie per fare questo sono due, il controllotramite le porte su cui solitamente un protocollo agisce (e.g 80 per httt o 20e 21 per ftp) oppure cercarre di interpretare il contenuto del campo dati diun pacchetto.

La prima opzione non e’ sempre efficace, avvero le porte standard di unprotocollo possono cambiare (basti pensare per quando riguarda ad http l’introduzione di un proxy che agisce sulla porta 8080). Il secondo metodoe’ quindi piu efficace. Nei successivi paragrafi analizzero l’ analisi fatta dame per stabilire l’ appartenenza di un pacchetto al protocollo http e comeintrodurre nel codice nuovi controlli.

0.20 Protocollo http

Analizzare http e’ un procedimento abbastanza semplice, brevemente ognipacchetto http di richiesta avra’ questa forma:

GET www.iksnet.it/index.php HTTP/1.0Accept: text/htmlUser-Agent: Netscape 1.1N PPC]]> </programlisting>

naturalmente puo’ essere piu’ o meno ricco di contenuti e di richieste maquello che interessa e’ la prima riga, se il campo dati inizia con GET oPOST. Un pacchetto di risposta ha questa forma

HTTP/1.0 200 OKDate: Fri, 31 Dec 1999 23:59:59 GMTContent-Type: text/htmlContent-Length: 1354

Anche in questo caso quello che mi interessa e’ la prima riga.Selezionando tutti i pacchetti che contengono nella prima riga del campo

dati le parole GET o POST avremo tutti i pacchetti di richiesta http, se ilpacchetto non rientra in questa categoria ma contiene la parola HTTP allorapossimo dedurre che sia una risposta.

17

Page 19: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

0.21 Protocollo smtp

Da utente per filtrare i pacchetti smtp e guardarne nei dati, bisogna utilizzarel’opzione ’-L smtp’.

Avviato il programma con l’opzione ’-L’, lo sniffer, nel caso di questoprotocollo, usa tre modi per capire se un pacchetto e’ smtp. Il primo e’controllare se la porta, sorgente o di destinazione, e’ uguale alla porta didefault del protocollo (in questo caso la 25). Il secondo metodo e’ trovare,se vi sono nei dati, dei comandi smtp mandati dal client (tipo ’HELO’).Il terzo metodo consiste di cercare nei dati, controllando se sono presenticodici di controllo mandati dal server smtp (ad esempio il 250).

Per controllare se il pacchetto e’ relativo all’invio di comandi smtp daparte del client, controllo se nei dati e’ presente un’occorrenza di alme-no una delle stringhe presenti nella prima colonna della matrice di default’commands’.

// matrice contenente i possibili comandi inviati da client con lerelative descrizionichar *commands[SMTP_NUM_COMMANDS][2]={"ATRN", "Authenticated TURN.","AUTH", "Authentication.","BDAT", "Binary data.","BURL", "Remote Content.","DATA", "Data.","EHLO", "Extended Hello.","ETRN", "Extended Turn.","EXPN", "Expand","HELO", "Hello","HELP", "Help","MAIL", "Mail","NOOP", "No operation","ONEX", "One message transaction only.","QUIT", "Quit","RCPT", "Recipient","RSET", "Reset","SAML", "Send and mail.","SEND", "Send.","SOML", "Send or mail.","STARTTLS", " ","SUBMITTER", "SMTP Responsible Submitter.","TURN", "Turn.","VERB", "Verbose.","VRFY", "Verify."};

18

Page 20: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

Ad esempio posso avere un pacchetto contenente:

HELO www.gmail.com

Eseguendo il confronto tra la stringa precedente e le stringhe della pri-ma colonna della matrice, trovo l’occorrenza di ’HELO’, poi estrapolo ’w-ww.gmail.com’, e stampo la descrizione del comando presente nella secondacolonna della matrice.

Per controllare se il pacchetto e’ relativo all’invio di codici di rispostada parte del server smtp, controllo se nei dati e’ presente un’occorrenzadi almeno una delle stringhe presenti nella prima colonna della matrice didefault ’codes’.

// matrice contenente i possibili messaggi in codiceinviati dal server con i relativi significatichar *codes[SMTP_NUM_CODES][2]= {"211", "System status,or system help reply.","214", "Help message.","220", "Domain service ready. Ready to start TLS.","221", "Domain service closing transmission channel.","250", "OK, queuing for node node started. Requested mail action okay,completed.","251", "OK, no messages waiting for node node.User not local,will forward to forwardpath.","252", "OK, pending messages for node node started.

Cannot VRFY user (e.g., info is not local), but willtake message for this user and attempt delivery.","253", "OK, messages pending messages for node node started.","354", "Start mail input; end with <CRLF>.<CRLF>.","355", "Octet-offset is the transaction offset.","421", "Domain service not available, closing transmission channel.","432", "A password transition is needed.",

"450", "Requested mail action not taken: mailbox unavailable.ATRN request refused.","451", "Requested action aborted: local error in processing.Unable to process ATRN request now","452", "Requested action not taken: insufficient system storage.","453", "You have no mail.","454", "TLS not available due to temporary reason.Encryption required for requested authentication mechanism.","458", "Unable to queue messages for node node.","459", "Node node not allowed: reason.",

19

Page 21: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

"500", "Command not recognized: command. Syntax error.","501", "Syntax error, no parameters allowed.","502", "Command not implemented.","503", "Bad sequence of commands.","504", "Command parameter not implemented.","521", "Machine does not accept mail.","530", "Must issue a STARTTLS command first.Encryption required for requested authentication mechanism.","534", "Authentication mechanism is too weak.","538", "Encryption required for requested authentication mechanism.","550", "Requested action not taken: mailbox unavailable.","551", "User not local; please try forwardpath.","552", "Requested mail action aborted: exceeded storage allocation.","553", "Requested action not taken: mailbox name not allowed.""554", "Transaction failed."

};

Ad esempio posso avere un pacchetto contenente:

250 OK

Eseguendo il confronto tra la stringa precedente e le stringhe della pri-ma colonna della matrice, trovo l’occorrenza di ’250’, poi estrapolo ’OK’,e stampo la descrizione del codice presente nella seconda colonna dellamatrice.

Per trovare i messaggi veri e propri di posta, stampo direttamente ilcampo dati dei pacchetti che: hanno o la porta sorgente o di destinazionedi default per smtp, non hanno nei dati ne occorrenze di comandi mandatidal client, ne codici mandati dal server smtp. Quindi vi e’ la possibilita dicatturare pacchetti, con dati vuoti, che usano la porta ’25’.

Nel caso invece il pacchetto contenga dei messaggi di posta veri e propril’output sara:

*****SMTP Packet Found************************DATA : ciao qui tutto bene, e te come stai?

UDP-> destination : 192...1:25 source : 192...2:2..3**********************************************

0.22 Note sull’ utilizzo di sniffer.c

Per installare il nostro sniffer dobbiamo prima di tutto installare il compi-latore linguaggio c, in quanto e stato scritto in c. Una volta installato ilcompilatore, eseguiamo e compiliamo da terminale il nostro codice

20

Page 22: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

gcc -W -Wall main.c -o sniffer

una volta compilato lo lanciamo con il comando

sudo sniffer -(hvicdfgbnm)

I comandi che possiamo inserire sono i seguenti: Come primo puntoe bene precisare la neccessita dell’ opzione -i nome dispositivo per il fun-zionamento dello sniffer. Questo e cio che si presenta tramite l’ opzione-h.

sniffer-h :Help-v :Modalita’ verbosa, informazioni aggiuntive (Ip/Tcp/Mac)-i device :Device su cui eseguire lo sniffing-c num :Limite al numero di pacchettia controllare-d ip :Indirizzo Ip (Ipv4/Ipv6) di destinazione-s ip :Indirizzo Ip (Ipv4/Ipv6) della sorgente-x ip :Indirizzo Ip (Ipv4/Ipv6) di destinazione o sorgente-p port :Porta di destinazione-P port :Porta della sorgente-X port :Porta di destinazione o porta della sorgente-t type :Protocollo di trasporto (Tcp,Udp e Icmp)-a type :Protocollo di applicazione (http,smtp),controllo effettuato a livello di porte-L <type> :Protocollo di applicazione (http,smtp),controllo sui dati del pacchetto, e interfaccia di output

Senza considerare nel dettaglio le voci (poiche’ l’ elenco e’ auto-esplicativo),porro’ l’ attenzione sul comportamento con composizioni particolari di voci.

Comporre in seguenza -p 1 e -P 2 comporta la selezione di tutti i pacchettiche hanno come destinazione 1 o sorgente 2. Componendo -p 1 -P 2 con -X3, l’ ultima istruzione ha la precedenza sulle precedenti. Il comportamentoe’ analogo anche per -I, -i e -x.

Nel caso in cui le selezioni un numero di porta e’ seguito da -a, questaultima opzione annulla i precendenti comandi sulle porte. Allo stesso modose si pone -a seguito da -p o -P queste ultime opzioni ne annulleranno l’effetto di -a. Ogni volta che si seleziona una porta o l’ opzione -L vengonoesclusi a priori i pacchetti icmp dalla selezione.

21

Page 23: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

Analizziamo ora tutte le possibili operazioni che possiamo effettuare.MODALITA VERBOSA:

STAMPA DI UN DETERMINATO NUMERO DI PACCHETTI:

22

Page 24: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

STAMPA DEI PACCHETTI DI UNA DETERMINATA INTERFAC-CIA:

FILTRAGGIO PACCHETTI TCP:

23

Page 25: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

FILTRAGGIO PACCHETTI UDP:

FILTRAGGIO PACCHETTI ICMP:

24

Page 26: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

FILTRAGGIO DEI PACCHETTI HTTP:

0.23 Cosa possiamo aggiungere

1. Realizzare un parser per semplici comandi tcpdump.Un parses permet-te di analizzare un file e estrarre da esso informazioni utili.Il parsing e

25

Page 27: Sniffer - unipr.italfieri/sniffer.pdfpromiscuous mode permettendo alla macchina ’A’ di vedere tutto il traffico che intercorre tra le macchine ’B’ e ’C’, sempre se condividono

il processo atto ad analizzare uno stream continuo in input (letto peresempio da un file o una tastiera) in modo da determinare la sua strut-tura grammaticale grazie ad una data grammatica formale. Un parsere un programma che esegue questo compito. Aggiungere il supportodelle espressioni and, or, not analoghe alle espressioni supportate datcpdump.

2. Risoluzione automatica dei nomi DNS, inibita dall’opzione -n

3. Aggiungere il timestamp di ogni pacchetto,in modo tale da fornirepiu informazioni, e mantenerle in memoria. Aggiungere quindi unafunzione che calcoli il timestamp assoluto nel file capture.h; in questomodo oltre a stampare il numero progressivo di ogni pacchetto vienestampata anche la data con i relativi millesimi di secondo. Il risultatodovrebbe essere molto simile a quello di Tcpdump:

4. Cambiare la stampa a video in modo tale che gli indirizzi abbiano ilseguente formato: 192.168.1.1.ssh oppure 192.168.1.1.22

5. Gestire il campo Opzioni del pacchetto IP(I campi da gestire vengo-no spiegati nella Struct ip_option dell’Ip Header nella sezione 0.10Socket Raw)

26