D'abord, un rapide rappel sur les notations :

  • K est la clé WEP (40 ou 104 bits)
  • IV est le vecteur d'initialisation de 24 bits
  • M est un message en clair
  • P est le payload chiffré correspondant à M
  • P = RC4(IV||K) XOR (M||ICV(M)), où || est l'opérateur de concaténation

Je vous ai déjà exposé une faille dans le mécanisme d'authentification permettant à un attaquant de récupérer la sortie de RC4 pour un IV donné, laquelle pourra lui servir ensuite à calculer une réponse à un challenge arbitraire de manière à s'authentifier sans pour autant être en possession de la clé WEP. Cependant, cette faille ne s'arrête pas là. La sortie RC4(IV||K) qu'il récupère est en effet longue de 144 octets, ce qui est largement suffisant pour chiffrer quelques requêtes, comme un requête ARP ou HTTP par exemple. L'attaquant est donc en mesure, à partir de l'observation d'une authentification, d'injecter des paquets cohérents dans le réseau, pouvant ainsi commencer à le stimuler pour faire de la découverte par exemple. Il sera également en mesure de déchiffrer les 144 premiers octets de tout paquet chiffré avec l'IV en question. C'est pas mal, mais on voudrait mieux. On voudrait pouvoir en particulier disposer d'une ou plusieurs sorties RC4 de longueur bien supérieure nous permettant de déchiffrer ou d'injecter des trames dont la longueur correspond à la MTU de lien.

Une voie très intéressante pour y parvenir est la fragmentation 802.11. Ceci permet d'éclater un payload quelconque sur plusieurs trames 802.11 distinctes. Comme chaque trame est chiffrée indépendamment des autres, nous pouvons chiffrer plusieurs fragments avec la même sortie RC4 pour injecter des paquets IP de taille supérieure. Mais l'intérêt de l'attaque ne s'arrête pas là. Lorsqu'un AP doit réémettre une trame fragmentée, il va la défragmenter ! Comme nous connaissons le contenu de cette trame défragmentée, nous pouvons récupérer la sortie RC4 correspondant à l'IV utilisé par l'AP sur la longueur complète de notre trame. Bingo ! 802.11 nous accorde 16 fragments, ce qui est largement suffisant pour atteindre la MTU. Mieux ! Les 8 premiers octets de toute trame 802.11 chiffrée sont connus. Il s'agit de l'entête LLC/SNAP, dont la valeur est souvent connue :

  • 0xAAAA030000000800 pour IP
  • 0xAAAA030000000806 pour ARP

L'immense majorité des réseaux parlent IP, et que les trames ARP sont faciles à repérer, nous pouvons aisément déduire 8 octet de sortie RC4, ce qui nous permet de chiffrer 4 octets de données[1], fois 16 fragments, moins 28 octets de header (LLC/SNAP + IP), ce qui nous permet d'envoyer 36 octets de données, sans rien avoir fait de plus que sniffer du trafic arbitraire. Si nous ajoutons de la fragmentation IP par dessus le tout, nous sommes très rapidement capable d'injecter sur un réseau WEP n'importe quel paquet IP.

Comment passer de notre capacité d'injecter des paquets arbitraires au cassage de WEP ? L'idée est assez simple en définitive. Nous savons que si nous possédons une sortie RC4 pour un IV donné de longueur N, alors nous pouvons déchiffrer tout payload chiffré de longeur N chiffré avec cet IV. L'idée est de construire une table associant à chaque IV la sortie RC4 correspondante sur la longueur maximale. L'injection de trafic sert alors à stimuler le réseau de toutes les manière possibles et imaginables pour récupérer ces données : faire défragmenter à l'AP, envoyer des requêtes à des stations de réseau, émettre des requêtes à destination de machines contrôlées à l'extérieur, tout est bon pour générer des trames dont nous sommes capables de prédire le contenu les plus longues possibles. Un telle table, une fois constituée, avoisine les 25 Go de données. C'est lourd, mais ça tient sur le disque dur de n'importe quel laptop du marché. Une telle table est par contre assez longue à constituer, les attaques les plus rapides étant annoncées à une vingtaine d'heures dans des conditions sympathiques. C'est pas mal, mais trop long pour attaquer un réseau dans la plupart des cas. Il faut donc trouver plus rapide.

Avant de passer à la récupération pure et simple de K, voyons comment on peut exploiter la linéarité du CRC32. Le principe est assez simple. Dans la mesure où XOR est également linéaire, nous pouvons manipuler l'équation produisant le payload chiffré lorsqu'on introduit une modification. Si nous considérons un message M' obtenu par modification d'un message M de la manière suivante :

M'= M XOR Mod

Nous pouvons alors tenter de calculer P' le chiffré de M' :

P' = RC4(IV||K) XOR (M'||ICV(M'))
   = RC4(IV||K) XOR (M XOR Mod||ICV(M XOR Mod))
   = RC4(IV||K) XOR (M||ICV(M)) XOR (Mod||ICV(Mod))
   = P XOR (Mod||ICV(Mod))

Ces équations ne sont pas tout à fait justes dans la mesure où il manque un facteur constant, dit CRC(0) qui représente le CRC32 de la chaîne nulle, donc sa valeur à l'origine. Dans le cas présent, CRC(0) n'est pas nul, mais[2] il ne change rien à la conclusion, dans la mesure où nous manipulons des fonctions affines[3]. Je l'ai donc volontairement omis par soucis de clareté. Bref, nous voyons que si nous disposons d'une trame chiffrée, le calcul d'une nouvelle trame modifiée, mais cohérente vis-à-vis de WEP, ne dépend que de la modification qu'on veut apporter. C'est évidemment le cas plus simple, à longueur constante, mais on sait obtenir le même genre de résultat en enlevant ou en rajoutant des données. L'utilisation la plus connue de cette faiblesse est l'attaque Chopchop, exposée par Korek. Elle consiste à capturer une trame et à la rejouer en supprimant le dernier octet. Pour que la modification apporté soit cohérente, nous avons besoin de connaître la valeur de cet octet. On construit donc 256 trames modifiées, une pour chaque valeur possible de l'octet, et on les soumet à l'AP pour voir s'il les relaie ou non. Si c'est le cas, on a la bonne valeur. On transforme donc notre AP en oracle. Sympa, non ? Ainsi, par itération, nous pouvons déchiffrer une trame complète. Évidemment, il est impensable de déchiffrer un flux à la volée en utilisant cette attaque. Mais elle permet de déchiffrer des paquets arbitraires lorsque le besoin se fait sentir.

Mais tout de même, le plus intéressant serait tout de même de récupérer tout simplement K. Pour se faire, revenons aux raisons qui motivent la deuxième règle d'utilisation de RC4 évoquée dans le billet précédent. En particulier, qu'est-ce que le problème des clés faibles ? Dès 1996, il a été montré que RC4 présentait des biais. En particulier, pour des clés spécifiques dites faibles. Un flux de données dont on connaitrait les premiers octets chiffré à l'aide d'une telle clé nous permettrait d'obtenir des informations sur l'état interne de RC4. Passons au 802.11... Nous avons vu que nous sommes capable de savoir si une trame est chiffrée avec une clé faible ; il suffit de regarder la valeur de l'IV. Mais nous avons vu aussi que les 7 premiers octets du payload sont également connus. Il n'en faut pas plus pour implémenter une attaque qui permet de casser purement et simplement la clé, c'est à dire récupérer K, à partir d'une capture de 1 à 2 millions de paquets chiffrés avec des clés faibles différentes, ce qui se traduit par l'utilisation d'IV qu'on appelera IV faibles. Cette attaque, qui date de 2001, porte le nom de ses inventeurs, à savoir Fluhrer, Mantin et Shamir. Un aspect intéressant de cette attaque est que sa complexité est presque linéaire avec le nombre de bits de clé, alors qu'elle est exponentielle pour une attaque en force brute. Ainsi, l'effort nécessaire pour casser une clé de 128 bits sera à peine plus du double de celui nécessaire à la récupération d'une clé de 64 bits. On peut d'ors et déjà constater que WEP a du plomb dans l'aile. La réaction évidente des constructeurs fut de supprimer les IV faibles, ce qui, combiné au temps nécessaire pour récupérer une capture utilisable, a longtemps confiné cette attaque aux laboratoires et aux démonstrations.

Plus tard, des gens comme H1kari ou Korek ont optimisé cette attaque, parvenant d'abord à l'étendre à de nouvelles classes d'IV puis finalement à tous les IV possibles, tout reposant sur le fait que les octets qu'on peut deviner avec une forte probabilité sont assez nombreux dans les entêtes. L'implémentation la plus connue de ces attaques est Aircrack, qui permet, à partir d'une capture réseau contenant suffisament de paquets chiffrés avec des IV différents, de casser une clé en une 10e de secondes. Le facteur limitant de l'attaque devient alors le temps nécessaire à réaliser la capture. Pour cela, on va tout simplement stimuler de réseau, soit par injection de trames arbitraires avec les techniques précédemment évoquées, soit par rejeu de trafic. C'est cette dernière technique qui est implémentée dans Aireplay : le logiciel repère des requêtes ARP et les rejoue en espérant déclencher des réponses qui vont alors alimenter notre capture en nouveaux IV. D'une part, le trafic ARP étant très particulier, il est facile à repérer. D'autre part, la faible tailles des paquets (28 octets) rend l'injection et la génération de trafic particulièrement rapide. En laboratoire, on parvient à casser des clés de 128 bits en 10 minutes. Dans la nature, on tourne autour de 30 minutes, voire une heure.

À partir du moment où un attaquant possède la clé du réseau, il y entre comme un utilisateur normal et peut donc lancer toute une collection d'attaques allant de l'injection directe de trafic à toutes les attaques ciblant les réseaux locaux (ARP cache poisoning, spoofing, DHCP snooping, DNS spoofing, etc.). On pourra jeter un coup d'œil à une collection de slides que j'ai présentés sur la question et à Wifitap, un outil de communication par injection de trafic. Il est aussi utile de se faire une idée quant à l'apport d'autres mécanismes de protection proposés et souvent conseillés :

  • le filtrage d'adresses MAC : la simple observation du trafic permet de repérer des adresses MAC autorisées et de les usurper, ce qui est trivial sur un réseau WiFi ;
  • le masquage de SSID : le nom du réseau est toujours présent en clair dans les requêtes d'association et n'est ni nécessaire pour casser une clé WEP, ni pour communiquer si on dispose d'une adresse MAC associée au même moment à usurper.

Il est donc clair que face à un attaquant qui a trente minutes à perdre et qui dispose des outils adaptés (qu'on trouve sur des CD Live), un réseau WEP ne tiendra pas longtemps. C'est pourquoi il est important à mon sens d'abandonner l'idée que mettre du filtrage d'adresses MAC, du SSID cloaking et un WEP suffit à décourager les attaquants. Il n'en est rien, et avec la mode de WEP cracking, ça en motiverait même certains. L'usage de ce protocole me semble à abandonner le plus rapidement possible au profit de solutions plus efficaces comme WPA, WPA2 ou, pour les plus motivés (paranoïaques), IPSEC. Comme ce billet commence à se faire long, je vous expliquerai dans un troisième et prochain billet comment marchent ces protocoles, ce qu'ils apportent, leurs conditions d'utilisation et les plate-formes qui les supportent.

Notes

[1] Les 4 derniers étant réservés pour le CRC

[2] Faites-moi confiance, ou refaites le calcul.

[3] Un changement et d'origine dans le repère, et hop.