Skip to content

Fonctionnement des attaques DHCP Starvation/Rogue et protections

Nous allons aujourd’hui étudier d’un peu plus près un angle d’attaque des services DHCP qui se nomme le DHCP Starvation, nous étendrons ensuite notre attaque vers le DHCP Rogue et verrons la différence, de but et de procédure, entre ces deux attaques. Nous arriverons ensuite au but de ce billet qui est de voir les techniques de protection envisageables pour se protéger de ce genre d’attaque.

DHCPATTACK
Afin de comprendre l’attaque en profondeur, nous l’étudierons en utilisant la librairie Python nommée Scapy, celle-ci nous permet en effet de former nos paquets couche par couche, option par option. C’est une manière très intéressante d’étudier une attaque en détail. On étudiera également des analyses de trame capturées via Wireshark lors des attaques afin de mieux comprendre ce que nous sommes en train de faire.

Le DHCP

Le service DHCP est destiné au sein des réseaux à fournir une adresse IP aux hôtes arrivant sur le réseau et désirant communiquer et échanger sur celui-ci. C’est l’une des premières choses que fait un hôte en arrivant sur un nouveau réseau. Pour rappeler brièvement le fonctionnement des échanges DHCP :

  • DHCP Discover : Le client envoie cette trame avec l’adresse source 0.0.0.0, car il n’a pas encore d’adresse IP, vers l’adresse de broadcast 255.255.255.255
  • DHCP Offer : En réponse à cette requête, le serveur DHCP va émettre une réponse proposant à l’hôte une IP ainsi que des informations de base concernant sa configuration réseau. Le but est alors de rendre l’hôte apte à communiquer sur le réseau via cette IP. À ce stade, si plusieurs serveurs DHCP ont reçu la requête émise en broadcast, plusieurs réponses peuvent être faites en même temps à l’hôte demandeur.
  • DHCP Request : L’hôte va alors sélectionner une des offres reçues (généralement la première à être arrivée) et en informer le DHCP en question, l’hôte demande au serveur DHCP la validation de cette IP pour qu’il soit informé qu’elle n’est plus libre ainsi que des informations supplémentaires sur le réseau. Les offres faites pas d’autres DHCP tombent dans l’oubli au bout d’un certain temps.
  • DHCP Ack : Le serveur va confirmer la validation de l’IP prise par le client et envoyer les dernières informations de configuration à l’hôte s’il y en a (Passerelle, DNS, WINS,…). Voici donc un schéma récapitulant la situation d’une demande d’IP via DHCP :
fonctionnement dhcp
Schéma du fonctionnement d’une demande d’IP via DHCP

Théorie du DHCP Starvation

En attendant une validation du client via une DHCP Request, le ou les serveurs DHCP ayant émis des offres (DHCP Offer) considèrent que l’IP ne peut être prise par une autre machine et va donc mettre cette IP proposée en réserve pour ne pas qu’elle soit de nouveau proposé à une autre machinee, il serait en effet dangereux qu’une IP en attente de validation soit également proposée à un autre hôte, deux acceptations de la même IP pourrait alors se faire, amenant à un conflit d’IP.

Le fait est que si le serveur propose un pool d’adresse de 254 IP et que l’on effectue 254 demandes sur une très courte période, il va nous proposer ces 254 IP et les mettre en attente de confirmation. Si un client légitime arrive sur le réseau à ce moment-là, il ne pourra avoir d’IP car le serveur DHCP aura déjà proposé les 254 IP qu’il pouvait distribuer, on parle alors de « famine« , ou plus généralement de DHCP Starvation, il s’agit bien là d’une attaque de type Déni se service (DOS) car le serveur DHCP ne remplit plus du tout son rôle.

L’attaque par DHCP Starvation, un terme qui peut plus ou moins maladroitement se traduire par « famine« , va donc avoir pour but d’effectuer un déni de service au niveau du service DHCP d’un réseau.

Fonctionnement technique

Techniquement, les requêtes que l’on va envoyer au serveur seront de type DHCP Discover et seront donc envoyées par un hôte n’ayant pas encore d’adresse (0.0.0.0) au broadcast, un client venant d’arriver sur un réseau ne connaît pas l’IP du serveur dhcp, donc il le cherche en broadcast : 255.255.255.255.

Il est également à souligner que l’attribution, même temporaire, d’une adresse IP à un hôte se fait via son adresse MAC, si un même hôte demande plusieurs adresses IP à un serveur, une seule sera validée car il ne peut y avoir qu’une seule association MAC <–> IP dans le DHCP, ceci libérant de fait les autres adresses IP demandées.

Pour effectuer notre attaque DHCP Starvation, nous allons nous servir de Scapy qui permet de forger des trames et des paquets de tout protocole option par option, on va utiliser également une génération aléatoire d’adresse MAC, ce qui fera que les paquets sembleront venir d’hôtes différents aux yeux du serveur, il réservera donc une IP pour chaque paquet reçu en attendant une validation ou un refus de cette IP.

Pour mettre en place notre attaque, nous allons suivre le schéma suivant :

dhcp client serveur
Schéma d’un échange DHCP entre une client et un serveur

Il s’agit bien entendu d’un schéma de base simplifié afin de mettre en pratique le fonctionnement de l’attaque, en temps normal, les réseaux sont plus complexes. Nous disposons donc :

  • D’un serveur DHCP Windows Server 2012 qui sera notre cible pour le DHCP Starvation
  • D’un client sous Linux en ligne de commande qui sera là pour tester la fonction de service DHCP de notre serveur
  • D’une machine Pirate sous KaliLinux

Note : Le serveur DHCP et le client auraient pu se trouver sur d’autres OS, l’attaque est ici faite sur le service DHCP et non sur le système d’exploitation le faisant tourner. L’un ne dépendant pas forcément de l’autre. Ainsi le fonctionnement de l’attaque marche aussi bien sous dhcp3-server ou isc-dhcp-server sous Linux.

Comme nous l’avons vu, le but de l’attaque va être de réserver l’ensemble des adresses IP que peut distribuer le serveur DHCP pour que notre client ne trouve pas de réponse à ses requêtes DHCP. Depuis notre poste pirate, nous allons donc ouvrir Scapy et forger notre paquet. Pour que l’on sache ce que l’on fait et que nous comprenions bien les paquets DHCP générés pour effectuer l’attaque, nous allons voir le paquet en entier puis le décomposer couche par couche à partir de la couche 2. On commence donc par lancer Scapy :

scapy

Puis on désactive la vérification par Scapy des adresses IP dans les paquets envoyés étant donné que nous allons falsifier ces adresses :

conf.checkIpAddr = False

On va ensuite construire notre paquet :

tramedhcp = Ether(src=RandMAC(),dst="ff:ff:ff:ff:ff:ff")/ IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/BOOTP(chaddr=RandString(12,'0123456789abcdef'))/DHCP(options=[("message-type","discover"),"end"])

Étudions un peu tout cela, j’ai donc clairement les différentes couches de mon paquet :

  • Couche 2 : Ether(), pour Ethernet

On indique ici les adresses MAC source et destination de nos paquets, notre hôte n’étant pas supposé connaître l’IP et la MAC du serveur DHCP ciblé, on utilisera l’adresse MAC de broadcast « ff:ff:ff:ff:ff:ff« , nous avons précédemment vu qu’une seule liaison MAC <–>IP ne pouvait être faite à la fois dans un DHCP, même s’il s’agit d’une IP mise en attente de validation. Pour que plusieurs relations MAC <–> IP soient stockées dans le serveur DHCP, nous allons utiliser une fonction intégrée à Scapy, RandMac(), qui génère des adresses MAC aléatoires :

 Ether(src=RandMAC(),dst="ff:ff:ff:ff:ff:ff")
  • Couche 3 : IP(), pour Internet Protocol et BootP(), pour Bootstrap Protocol

On va ensuite s’occuper de la couche 3 c’est-à-dire IP et BootP qui est un protocole un peu vieux sur lequel se base DHCP, ce qu’il faut retenir est que le serveur BOOTP utilise le port 67 et le client BOOTP utilise le port 68. Le seul champ qui doit être rempli doit être le chaddr (client hardware address), soit l’adresse MAC de notre client. Pour l’IP, on a vu que le client diffusait une trame de broadcast depuis une adresse 0.0.0.0 pour la partie IP :

IP(src="0.0.0.0",dst="255.255.255.255")/.../BOOTP(chaddr=RandString(12,'0123456789abcdef'))

Comme nous venons de le voir, on doit spécifier le port source en 68 car il provient d’un client vers le port destination 67 car il va vers un serveur :

UDP(sport=68,dport=67)
  • Couche 7 : DHCP()

Enfin, nous devons spécifier quel type de message  nous allons envoyer, si vous avez bien lu tout ce qui précède cette ligne, il s’agit donc de paquets Discover qui vont faire que le serveur DHCP va nous réserver et nous proposer une adresse :

 DHCP(options=[("message-type","discover"),"end"])

Maintenant que nous avons créé notre paquet, il nous suffit de l’envoyer. Afin de mieux comprendre ce qu’il se passe, nous allons effectuer une écoute du réseau sur notre serveur Windows 2012 qui est le serveur DHCP. Voici la commande que l’on utilise dans Scapy en Python pour envoyer notre paquet

sendp (tramedhcp,loop=1)

On utilise dans la fonction « sendp() » en précisant le paquet à envoyer, celui que nous venons de construire, en mettant l’option « loop » à 1, ce qui permettra d’envoyer le paquet en boucle :

python scapy dhcp
Exécution du code Scapy

Sur le serveur Windows, on peut donc remarquer les paquets Discover arrivés :

wireshark dhcp réseau
Sniff réseau lors de l’envoie des paqutes DHCP

Si on regarde l’intérieur de ces paquets, toujours avec Wireshark, on y retrouvera tout simplement ce que nous avons demandé à Scapy d’y mettre :

wireshark dhcp
Étude d’un paquet DHCP forgé capturé dans Wireshark
  • En Orange : La couche 2, Ether(), qui contient le Broadcast MAC en destination et une adresse MAC randomisée qui sera différente à chaque paquet
  • En Rouge : IP(), IP source en 0.0.0.0 car l’hôte n’a pas d’IP et destination en broadcast.
  • Le protocole UDP en Bleu qui détermine les ports source et destination et qui annonce le protocole BootP en Violet avec une adresse MAC aléatoire, différente de celle en couche 2 car il s’agit de celle du client ayant initié la requête et non du dernier hôte à l’avoir relayé (dans le cas d’ip-helper par exemple) ainsi que le type de paquet DHCP (ici « Discover »).

Bien, maintenant que nous avons vu le fonctionnement DHCP ainsi que la procédure d’attaque, nous savons que le serveur DHCP va réserver une adresse IP par paquet dans son pool d’adresse disponible et envoyer des DHCP Offer. La réception des DHCP Offers par notre pirate ne nous importe pas du tout, ce qui est important dans l’attaque, c’est qu’une IP soit réservée à chaque réception de DHCP Discover. Si on envoie des DHCP Discover de façon massive et continue, aucune IP ne restera disponible pour les hôtes légitimes.

Si l’on regarde le contenu des baux DHCP attribués dans le DHCP Windows, nous ne verrons pas les réservations d’adresses effectuées :

dhcp attaque
Vue des baux DHCP dans un serveur Windows

Cela vient du fait que les IP ne sont pas attribuées, pour cela il faudrait que l’on envoie un DHCP Request à notre DHCP pour chaque IP. Elles sont seulement en attente de réponse, on pourra voir que les IP sont indisponibles en faisant un clique doit sur notre étendue puis « Afficher les statistiques » :

dhcp starvation
On voit ici dans les statistiques DHCP que 100 % des adresses IP sont utilisées

On peut aussi plus simplement le vérifier en faisant une demande d’IP depuis un client, sous Linux :

dhclient -v eth0
dhcp starvation python
On voit ici que la demande de bail DHCP n’aboutit pas car le seul DHCP en place n’a plus d’adresse IP à distribuer

Extension de l’attaque : DHCP Rogue

Nous avons vu les dégâts que peut causer une attaque DHCP Starvation, on voit bien qu’il s’agit d’une attaque DOS, c’est à dire une attaque où le service visé ne fait plus son travail à cause de notre attaque. Une extension de cette attaque peut alors être faite, le DHCP Rogue, « Rogue » pouvant être traduit par « voyou » dans le sens « illégitime ».

Nous savons en effet que le client ayant émis un DHCP Discovery se servira du premier serveur DHCP lui répondant comme de son DHCP. Sachant que dans une attaque DHCP Starvation, le DHCP est déjà très occupé et qu’il met du temps à répondre aux requêtes des clients légitimes (voire parfois il n’y répond plus du tout), si notre Pirate monte un serveur DHCP sur son poste, celui-ci pourra donner aux clients les informations qu’il souhaite. On pourra alors avoir un DHCP Rogue, c’est-à-dire un serveur DHCP qui agit à la place du DHCP « officiel » qui est lui surchargé :

dhcp starvation rogue
Schéma d’une attaque DHCP Starvation + Rogue

L’intérêt n’est alors plus d’effectuer une attaque de type DOS, mais une attaque de type Man in the Middle (MITM). En effet, le pirate faisant office de serveur DHCP, il pourra en profiter pour fournir aux clients des informations faussées comme un serveur DNS interne qui répondra de fausses informations aux utilisateurs ou encore pire, se positionner en tant que routeur pour que tout le trafic des clients  passe par lui. Je ne détaillerais pas ici la configuration du serveur DHCP à effectuer car celle-ci est basique, il suffit de fournir des baux sur la même plage IP que le DHCP officiel puis de mettre en gateway l’adresse IP de notre propre pirate :

dhcp rogue stravation python
Schéma d’un DHCP Rogue + Starvation

Le fait de pouvoir faire transiter des paquets à travers un poste sous Linux se fait très rapidement avec la commande suivante et cela fonctionne même si notre Routeur « voyou » ne possède qu’une interface, il se contentera de rejouer les requêtes qu’il reçoit vers la passerelle :

echo 1 > /proc/sys/net/ipv4/ip_forward

Le pirate n’aura alors plus qu’à ouvrir Wireshark ou autre sniffeur réseau aussi puissant pour voir tout ce que les clients vont faire à l’extérieur du réseau. Le pire dans le DHCP Rogue est que le client ne se rend compte de rien, bien souvent l’administrateur non plus car le système informatique continue de fonctionner pour tout le monde. C’est ce qui fait que ce genre d’attaque est particulièrement dangereuse.

Protections envisageable : Mitigations

J’espère que vous êtes à présent convaincu de la nécessité de surveiller la sécurité des serveurs DHCP, même si leur rôle est des plus basiques, ils peuvent constituer une première vulnérabilité dans un réseau, que ce soit pour les attaques de type DOS ou les MITM. Voici quelques pistes de sécurisation et de détection des attaques DHCP Starvation et DHCP Rogue :

  • Superviser les baux DHCP libres/attribués

Nous l’avons vu dans ce billet, le nombre de baux libres et de baux attribués peuvent être un élément nous permettant de détecter une attaque DHCP, il serait donc intéressant de superviser ces éléments sur votre serveur DHCP et de mettre en place des alertes en cas de comportement anormal ou de dépassement d’un certain seuil. Je ne me suis pas renseigné sur l’existence de plug-in type Nagios permettant de faire cela, mais il est possible d’en développer un facilement en Powershell (pour Nagios) ou en bash (pour Linux)

  • Écouter le réseau

L’écoute du réseau, totale ou partielle, par des NIDS (Network Intrusion Detection System) peut permettre de détecter des envois massifs de paquet DHCP DISCOVER ou même l’envoi de paquet DHCP OFFER ou ACK par d’autres IP/ MAC que celles du serveur DHCP « officiel ». Même si ces dernières informations peuvent être usurpées facilement via Scapy. Les NIPS (Network Intrusion Prevention System) peuvent également permettre de lancer par eux-mêmes des actions protectrices sur le réseau, mais il faut être prudent quant à ces actions afin qu’elles ne causent pas plus de dommage que l’attaquant.

  • Port Security sur les Switch

Nous avons vu que pour que l’attaque soit un succès, il faut générer des paquets ayant une adresse MAC source différente à chaque fois. La technologie Port-Security (comme elle se nomme sur les éléments Cisco), permet de fixer un seuil d’adresse MAC source par interface puis de bloquer cette interface ou d’émettre une alerte en cas de dépassement du nombre MAC par interface indiqué. Cela permettra par exemple de bloquer un port automatiquement en cas d’attaque DHCP Starvation.

  • Opter pour des flux chiffrés

Une fois qu’un attaquant a effectué une attaque DHCP Rogue et que celle-ci n’est pas détectée, le chiffrement peut tout de même protéger les flux clients car même si le pirate les capture (les sniffe), il ne pourra les déchiffrer et les lire, rendant ainsi l’attaque inutile.

  • Anti DHCP Snooping

Les switchs Cisco Catalyst possèdent une technologie permettant de contrer les DHCP snooping/spoofing comme nous venons d’en voir. Cela permet d’autoriser les flux DHCP à transiter selon les ports spécifiés uniquement ou d’autoriser seulement certaines adresses IP ou MAC à émettre ou recevoir du flux DHCP. On peut également spécifier un ratio par seconde de message DHCP accepté. Si l’attaquant émet plus de 5 paquets DHCP par seconde, une alerte sera faite et un blocage de port peut être effectué.

Si vous avez, vous aussi, réfléchi à des pistes pour sécuriser vos serveurs DHCP, n’hésitez pas à partager vos idées dans les commentaires.

 

Partager :
Published inAttaques

6 Comments

  1. Merci de cet article très instructif!

  2. rugaba jean pierre

    merci bcp pour l’article

  3. Abadi

    merci pour l’article

  4. Steve

    Article extrêmement intéressant. je vais avoir du travail demain Merci 🙂

  5. reader

    bon article. les methodes de protection envisagees ici ne s’occupe que d’un reseau filaires (blocage de ports, port security), qu’en est-il du sans fil qui estr de plus en plus répandu ??

  6. fccagou

    Bon article.
    Dans le paragraphe juste avant le titre « écouter le réseau » je pense que l’exemple pour powershell doit être « windows » et pas « nagios »

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *