- Objectifs de ce TP
- Outils logiciels
- Informations utiles
- Partie 1 : Implémentation d’un sniffer passif
- Partie2 : manipulation de sniffers
- Partie3 : remote sniffing
Les sniffers (appelé aussi « analyseurs de protocoles » ou « analyseurs de réseau ») sont des outils logiciels qui peuvent capturer les trames circulant sur un réseau local et afficher leurs contenus (entêtes des protocoles, identités des utilisateurs, mot de passe non cryptés, etc). Ces outils sont utilisés par les administrateurs pour analyser leurs réseaux et localiser les problèmes dans ces derniers. Ils sont aussi utilisés par les attaquants pour espionner les données circulant dans un réseau local.
- Implémenter un sniffer passif simple
- Manipuler des logiciels de sniffing
- Linux
- wireshark
- compilateur cc ou gcc
- Les cartes réseau fonctionnent en deux modes
- mode normal (mode par défaut) : permet à une carte de filtrer les trames reçus en fonction de l'adresse MAC destination
- mode promiscuous : consiste à accepter toutes les trames circulant dans un réseau, même ceux qui ne sont pas destinés à la carte.
- Sous Unix, la commande # ifconfig promisc permet d’activer le mode promiscuous.
- La plupart des logiciels sniffers permettent d’activer le mode promoscuous lors de leur lancement.
- Dans un réseau commuté, le sniffing passif de toutes les trames qui circulent dans le réseau est impossible à réaliser puisqu'un nœud ne peut recevoir que les trames qui lui sont destinées.
- Le sniffing actif (qui sera traité au niveau du TP2) permet de faire du sniffing sur un réseau même s'il est commuté.
- Le sniffer doit être sur le même réseau à sniffer. Sinon, il doit faire du « remote sniffing » en contrôlant à distance une machine qui se trouve sur le réseau à sniffer.
L'annexe 1 présente le code source d’un sniffer passif qui permet de récupérer les trames reçues par une interface réseau (exemple ETHERNET). Ce code source est écrit en langage C et peut être compilé et exécuté sur une machine Linux. Les fonctions les plus importantes de ce code sont (voir contenu de lafonction main):
- La fonction recvfrom qui permet de récupérer les trames reçues sur l’interface réseau.
- La fonction PrintPacketInHex qui permet d’afficher la trame sous format hexadécimal
- La fonction ParseEthernetHeader qui permet d’afficher quelques champs de l’entête ETHRNET
- La fonction ParseIpHeader qui permet d’afficher quelques champs de l’entête IP
- La fonction ParseTcpHeader qui permet d’afficher quelques champs de l’entête TCP
- La fonction ParseData qui permet d’afficher les données sous format hexadécimal
La Compilation du (cc -c sniffer_eth_ip_tcp_data.c).
La génération du (cc sniffer_eth_ip_tcp_data.c -o sniffer).
On execute le sniffer pour sniffer les 100 premieres trames reçues sur l’interface eth0.
Dans ce cas les trames sont affichées sous format hexadécimal.
Pour afficher le contenu de l’entête ETHERNET, il faut enlever le commentaire de la fonction ParseEthernetHeader. Aprés la compilation et l’execution nous obtenons le résultat suivant:
Pour Afficher le contenu des entêtes des protocoles des niveaux supérieurs, enlevez les commentaires des fonctions correspondantes (au niveau de la fonction main), on régénère l’executable et on l’execute:
La fonction qui affiche l’en-tête UDP :
ParseUdpHeader(unsigned char *packet , int len)
{
struct ethhdr *ethernet_header;
struct iphdr *ip_header;
struct udphdr *udp_header;
/* Check if enough bytes are there for TCP Header */
if(len >= (sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct
udphdr)))
{
/* Do all the checks: 1. Is it an IP pkt ? 2. is it TCP ? */
ethernet_header = (struct ethhdr *)packet;
if(ntohs(ethernet_header->h_proto) == ETH_P_IP)
{
ip_header = (struct iphdr *)(packet + sizeof(struct ethhdr));
if(ip_header->protocol == IPPROTO_UDP)
{
printf("UDP datagram (UDP num=%d)\n", ip_header->protocol);
udp_header = (struct udphdr*)(packet + sizeof(struct
ethhdr) + ip_header->ihl*4 );
/* Print the Dest and Src ports */
printf("Source Port: %d\n", ntohs(udp_header->source));
printf("Dest Port: %d\n", ntohs(udp_header->dest));
}
else
{
printf("Not a UDP packet\n");
}
}
else
{
printf("Not an IP packet\n");
}
}
else
{
printf("UDP Header not present \n");
}
}
Dans cette partie, nous nous intéressons à la manipulation de quelques sniffers existants. (Pour plus d’informations sur l’utilisation de wireshark (cliquez ici) et (ici)
On lance le logiciel Wireshark et on démarre la capture sur l’interface eth0:
Est-ce que vous pouvez capturer les trafics échangés entre les machines du reste du réseau?
Nous n’avons pas pu échanger de trafic entre d'autres machines et le reste du réseau. Car on est pas on mode promiscieux.
L'affichage du trames concernant le protocole: bootp, tcp, icmp,etc
L'affichage du trames dont l'adresse MAC destination est celle de votre machine
L'affichage du trames échangé entre deux machines d'adresse @IP1 et @IP2
L'affichage du trames dont la taille est supérieure à une taille donnée
Dans cette section, nous nous intéressons l'utilisation d'un sniffer à distance « remote sniffing » pour obtenir les données circulant sur un autre réseau que celui sur lequel nous sommes. Supposons que nous sommes sur le réseau RES1 et nous voulons sniffer le réseau voisin RES2 (nous sommes séparés par un routeur). Nous utilisons alors un client sniffer sur une machine du réseau RES2 qui va sniffer ce dernier et envoyer les données capturées à notre serveur sniffer sur le réseau RES1. Le réseau B qui, en principe, était impossible à sniffer est devenu donc très accessible. Nous utilisons le démon Rpcapd (plus de détails) qui capture le trafic sur une machine, et est capable d'envoyer les données récupérées à un sniffer comme wireshark qui facilite ainsi la lecture en différenciant les trames et les protocoles. Notons qu'il est utile d'exclure le trafic entre la machine locale et la machine distante en utilisant les filtres de wireshark.
Out Team - AIT EL KADI Ilyas - AZIZ Oussama - BENCHEDI Yahia
Project Link: https://github.com/IlyasKadi/Attaques_passives--sniffing_passif