Tutorial TCPdump

Date: 23/02/2007 | Catégories: Reseau | Tags:

TCPdump est un outil en ligne de commande pour écouter ce qui se passe sur une interface réseau. Il est disponible sur la plupart des operating system (Linux, Mac, Wins...). Comme son nom ne l'indique pas il est capable de déchiffrer tout les paquets IP.

Comment lancer TCPdump

Il est préférable de lancer TCPdump en mode super user. En effet, il passe votre interface réseau en "promiscuous mode" (c'est à dire que votre interface va accepter tous les paquets IP, même ceux qui ne lui sont pas destinés), ce qui nécessite certain priviléges.

Voici une première commande pour écouter ce qui se passe sur l'interface par défaut de botre système:

# tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size 96 bytes
11:21:49.128471 802.1d unknown version
11:21:50.629554 arp who-has 192.168.29.149 tell 192.168.29.179
11:21:51.116336 IP 192.168.29.11.34236 > broadcasthost.34235: UDP, length 186
11:21:51.129803 802.1d unknown version
11:21:51.543959 IP 192.168.29.157.49575 > 192.168.29.1.domain: 5186+ PTR? 149.29.168.192.in-addr.arpa. (45)
11:21:51.616221 IP 192.168.29.1.domain > 192.168.29.157.49575: 5186 NXDomain* 0/1/0 (142)
11:21:51.617724 IP 192.168.29.157.49576 > 192.168.29.1.domain: 55735+ PTR? 179.29.168.192.in-addr.arpa. (45)
11:21:51.618069 IP 192.168.29.1.domain > 192.168.29.157.49576: 55735 NXDomain 0/1/0 (122)
11:21:51.619695 IP 192.168.29.157.49577 > 192.168.29.1.domain: 34419+ PTR? 11.29.168.192.in-addr.arpa. (44)
11:21:51.691880 IP 192.168.29.1.domain > 192.168.29.157.49577: 34419 NXDomain* 0/1/0 (141)
11:21:52.693682 IP 192.168.29.157.49578 > 192.168.29.1.domain: 10774+ PTR? 1.29.168.192.in-addr.arpa. (43)
11:21:52.766304 IP 192.168.29.1.domain > 192.168.29.157.49578: 10774 NXDomain* 0/1/0 (140)
11:21:53.131204 802.1d unknown version
11:21:53.770691 IP 192.168.29.157 > 224.0.0.251: igmp v2 report 224.0.0.251
11:21:53.847442 arp who-has 192.168.29.175 tell 192.168.29.1
11:21:54.768652 arp who-has 192.168.29.1 tell 192.168.29.157
11:21:54.768916 arp reply 192.168.29.1 is-at 00:0d:61:60:3b:2f (oui Unknown)
11:21:54.768942 IP 192.168.29.157.49580 > 192.168.29.1.domain: 35687+ PTR? 251.0.0.224.in-addr.arpa. (42)
11:21:54.769366 IP 192.168.29.1.domain > 192.168.29.157.49580: 35687 NXDomain 0/1/0 (100)
11:21:54.770771 IP 192.168.29.157.49581 > 192.168.29.1.domain: 47393+ PTR? 175.29.168.192.in-addr.arpa. (45)
11:21:54.843466 IP 192.168.29.1.domain > 192.168.29.157.49581: 47393 NXDomain* 0/1/0 (142)

TCPdump génére une ligne par paquet IP. Avec les options par défaut, une ligne ressemble à:

11:21:54.768942 IP 192.168.29.157.49580 > 192.168.29.1.domain
-> Heure d'arrivée du paquet sur l'interface réseau
11:21:54.768942 IP 192.168.29.157.49580 > 192.168.29.1.domain
-> Type de protocole (ici IP, peut être aussi ARP, IGMP, GRE ...)
11:21:54.768942 IP 192.168.29.157.49580 > 192.168.29.1.domain
-> Adresse réseau source
11:21:54.768942 IP 192.168.29.157.49580 > 192.168.29.1.domain
-> Port réseau source
11:21:54.768942 IP 192.168.29.157.49580 > 192.168.29.1.domain
-> Adresse réseau destination
11:21:54.768942 IP 192.168.29.157.49580 > 192.168.29.1.domain
-> Port réseau destination (domain = requête DNS UDP/53)

Remarque: pour trouver le numero de port correspondant au nom du port, il faut chercher dans le fichier /etc/services. Par exemple:

# grep domain /etc/services
domain 53/udp # Domain Name Server

Je veux plus d'informations

(ok ok ...). Si vous souhaitez avoir plus d'information, vous pouvez utiliser le tag -v:

# tcpdump -v
...
11:34:23.480144 IP (tos 0x0, ttl 64, id 10784, offset 0, flags [DF], proto: UDP (17), length: 67) 192.168.29.246.32794 > 192.168.29.1.domain: 8576+ A? ftp.redhat.ikoula.com. (39)
...

On peut alors voir les informations supplémentaires suivantes:

(tos 0x0, ttl 64, id 10784, offset 0, flags [DF], proto: UDP (17), length: 67)

Associés au champs IP, elle fournie des informations sur le protocole (flags, protocole UDP, taille du paquet...).
8576+ A? ftp.redhat.ikoula.com. (39)
Donne un apercu du champ data (dans notre exemple, on peut voir que c'est une requête DNS qui demande l'adresse IP du serveur ftp.redhat.ikoula.com)

Si vous voulez encore plus d'informations (coquin va...), vous pouvez utiliser les options -vv et même -vvv (mais ou s'arrêteront t'ils ?).

Si vous souhaité avoir un dump du contenu du de chaque paquet, vous pouvez utiliser l'option -A, par exemple:

# tcpdump -v -A
11:46:00.607145 IP (tos 0x0, ttl 64, id 33771, offset 0, flags [DF], proto: TCP (6), length: 765) 192.168.29.157.49659 > mu-in-f104.google.com.http: P 1543672215:1543672940(725) ack 1290089933 win 65535
E.....@.@.}......U.h...P\...L.5.P...9...GET / HTTP/1.1
Host: www.google.fr
User-

Ce paquet correspnd donc à une requette HTTP sur le site www.google.fr.

Mon dieu, il y a trop d'informations !!!

(faut savoir ce que tu veux....). Heureusement, TCPdump inclut un système de filtrage très pointu.

Quelques exemples (consulter le man tcpdump pour une liste exhaustive):

# tcpdump host www.google.fr
Affiche seulement les paquets qui ont pour adresse source ou destination www.google.fr

# tcpdump dst www.google.fr
Affiche seulement les paquets qui ont pour adresse destination www.google.fr

# tcpdump port http
Affiche seulement les paquets HTTP (web)

# tcpdump proto gre
Affiche seulement les paquets GRE (utilisés lors de tunnel ipsec)

Il est bien sur possible de mixer plusieurs filtres:

# tcpdump dst 192.168.29.10 and port domain
Affiche tous les paquets DNS (domain) à destination de l'adresse 192.168.29.10

J'en veux encore !

(ben voila, on donne la main il prend le bras...). Imaginons que l'on souhaite capturer les paquets transitant sur une interface réseau afin de les analyser plus tard, sur une autre machine ou dans un autre logiciel (par exemple dans Ethereal...). C'est possible et très simple avec l'option -w:

# tcpdump -w capture.dump
tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 96 bytes
656 packets captured
676 packets received by filter
0 packets dropped by kernel

Cette commande va capturer les paquets et sauvegarder le tout dans le fichier capture.dump.
Si vous souhaitez maintenant afficher le contenu de ce fichier avec l'option -r, il faut taper la commande:

# tcpdump -v -r capture.dump
reading from file capture.dump, link-type EN10MB (Ethernet)
13:28:09.495897 IP (tos 0x0, ttl 64, id 47730, offset 0, flags [DF], proto: TCP (6), length: 52) 192.168.29.246.49084 > ftp.fu-berl
in.de.60772: ., cksum 0x13d0 (correct), ack 1339443207 win 2003
13:28:09.503376 IP (tos 0x0, ttl 64, id 47731, offset 0, flags [DF], proto: TCP (6), length: 52) 192.168.29.246.49084 > ftp.fu-berl
in.de.60772: ., cksum 0x0e1d (correct), ack 1449 win 2003
13:28:09.506374 IP (tos 0x0, ttl 64, id 47732, offset 0, flags [DF], proto: TCP (6), length: 52) 192.168.29.246.49084 > ftp.fu-berl
in.de.60772: ., cksum 0x0872 (correct), ack 2897 win 2003

Voila une première initiation à la capture réseau. Vous pouvez toujours consulter le man de TCPdump pour exploiter les nombreuses options de ce logiciel.

Quelques options en bonus:
-n : ne pas faire de résolution de nom (affiche seulement les adresses IP).
-i : Force l'utilisation de l'interface (par exemple -i eth0)

Partager ce billet