mercredi 7 janvier 2009

Attaque ChopChop

Premier article que j'écris en rapport avec la norme 802.11 plus connue sous le nom de WiFi. Pour bien comprendre cet article il est conseillé d'avoir déjà des connaissances sur le fonctionnement du protocole WEP (Wired Equivalent Privacy). Je vais parler d'une attaque relativement connue qui s'appelle l'attaque ChopChop qui a déjà fait ses preuves notamment contre le protocole WEP et qui depuis peu a été utilisé pour mettre en évidence les faiblesses du protocole TKIP (Temporal Key Integrity Protocol). Ce billet est le premier d'une série qui a pour objectif justement d'expliquer cette faille dans TKIP.

Historique


En 2004, alors que le WEP est déjà cassé depuis officiellement 2001, Korek publie la première version d'un outil appelé chopchop qui permet de décrypter n'importe quel paquet chiffré sans connaître la clef[1] WEP. Un nouveau coup dur pour le WEP qui n'en n'avait vraiment pas besoin. Ce n'était ni le premier et encore moins le dernier. Cette attaque probablement moins connue que les attaques FMS ou encore PTW (car elle ne permet pas de trouver la clef WEP) revient sur le devant de la scène grâce à la présentation de Erik Tews faite à la PacSec sur les faiblesses du protocole TKIP.

Fonctionnement de l'attaque


Pour commencer un tout petit rappel sur le fonctionnement du WEP s'impose. Très grossièrement chaque paquet est constitué de deux parties : les données et le CRC32[2] qui permet d'assurer l'intégrité de ces données. Le tout est ensuite envoyé à l'algorithme de chiffrement WEP c'est à dire RC4 : le paquet chiffré envoyé sur le réseau est le résultat du xor entre la concaténation du message et de son CRC32 et le keystream qui est fonction de la clef WEP et du vecteur d'initialisation courant. Si D est le message en clair, ICV l'opération de CRC32 (Integrity Check Value), C le message chiffré, K la clef WEP, IV le vecteur d'initialisation courant et || l'opérateur de concaténation alors ce que je viens d'écrire peut se résumer de cette façon :

C = RC4(IV || K) xor (D || ICV(D))

Ici tout ce qui est en vert est connu par une personne qui n'a pas la clef et qui écoute le réseau et tout ce qui est en rouge est inconnu.

Le CRC32 a à la base était écrit pour assurer l'intégrité des données et en aucun cas pour assurer leur sécurité. L'attaque ChopChop va donc utiliser plusieurs faiblesses de cet algorithme pour injecter des données sur le réseau.

Si l'on souhaite injecter des données dans le réseau à partir d'un paquet chiffré capturé alors nous avons les relations suivantes :

C = RC4(IV || K) xor (D || ICV(D)) est le paquet capturé.

D' représente les données que l'on va injecter dans le réseau tel que : D' = D xor Mod

Nous avons donc :

C' = RC4(IV || K) xor (D' || ICV(D'))

Ici comme nous ne connaissons pas D, nous ne connaissons pas non plus D'.

D' || ICV(D') = (D || ICV(D)) xor (Mod || ICV'(Mod)) ou ICV' est un CRC32 modifié

donc

C' = RC4(IV || K) xor (D || ICV(D)) xor (Mod || ICV'(Mod))

C' = C xor (Mod || ICV'(Mod))

Cette relation montre qu'à partir d'un paquet chiffré valide, il est possible d'injecter n'importe quelle modification de ce paquet. C' qui était inconnu est en définitif seulement fonction d'élément connu.

L'attaque ChopChop utilise une autre vulnérabilité du CRC32. Si le message C est tronqué de son dernier octet de données, le message devient donc invalide car le CRC32 ne correspond plus. Cependant si on xor C avec une certaine valeur Mod, alors le paquet redevient valide. Une démonstration mathématique[3] montre que Mod ne dépend que de la valeur en clair de l'octet tronqué.

On peut donc écrire que Mod = f(X) où X est la valeur en clair de l'octet tronqué.

L'attaque coule maintenant de source. Etant donnée qu'il y a 256 valeurs possibles pour X, il suffit de toutes les tester.

On prend donc notre paquet capturé C, on lui enlève le dernier octet de données. On prend comme hypothèse que la valeur non chiffrée X de cet octet tronqué est 0 et on génère notre modification :

C' = C xor f(x) avec x=0

On envoie C' et si C' est rejoué par l'Access Point alors c'est que notre paquet C' était valide, donc notre hypothèse sur X était bonne. On vient donc de trouver un octet en clair de C (donc un octet de D), et donc un octet du keystream utilisé pour chiffrer cet octet. Si le paquet C' n'est pas rejoué par l'Access Point, alors c'est que notre paquet C' n'est pas valide, donc notre hypothèse sur X était fausse. On retente en incrémentant X, jusqu'à que le paquet C' soit rejoué. En moyenne il faudra donc envoyer 128 paquets pour décrypter un octet.

La suite est évidente, on réitère la même méthode pour trouver tous les octets de D, donc octet par octet.

Outils Implémentant l'attaque


Le premier outil implémentant cette attaque est bien entendu la preuve de concept de Korek.

Le deuxième outil est aireplay-ng de la très célèbre suite aircrack-ng. N'hésitez pas à vos référer à cette page pour la mise en oeuvre de chopchop avec aireplay.

Liens


Voilà une liste de liens qui m'ont permis d'écrire cet article, n'hésitez pas à me corriger si vous avez trouvé des erreurs !

chopchop (Experimental WEP attacks)
Thread initial de Korek sur la preuve de concept. Le contenu du fichier zip que l'on peut avoir directement ici contient plein d'informations très utiles, notamment le fichier DOC.

ChopChop Theory
L'explication de l'attaque faite par le site aircrack-ng

Byte-Sized Decryption of WEP with Chopchop, Part 1
Byte-Sized Decryption of WEP with Chopchop, Part 2
Explications supplémentaires sur le fonctionnement de l'attaque.

Fameuses faiblesses de tkip
Pourquoi c'est pourri le wep part-2
L'explication du fonctionnement de ChopChop sur le blog de Cédric Blancher qui est une mine d'informations sur la sécurité des réseaux WiFi entre autres.

Notes


[1] C'est ici un pléonasme ! Décrypter veut dire trouver le texte en clair à partir du texte chiffré sans la clef.
[2] Le CRC32 comme son nom l'indique fait 32 bits, soit 4 octets.
[3] Cette démonstration mathématique se trouve dans le fichier DOC de la preuve de concept de Korek chopchop-0.1.zip.

4 commentaires:

  1. Bonjour,

    Je ne comprend pas pourquoi il s'agit d'un CRC32 modifié. En quoi ce CRC est-il modifié et pourquoi utilise-t-on un CRC32 modifié ?

    [quote]
    "D’ || ICV(D’) = (D || ICV(D)) xor (Mod || ICV’(Mod)) ou ICV’ est un CRC32 modifié
    [/quote]


    Martin

    RépondreSupprimer
  2. "Ici tout ce qui est en vert est connu par une personne qui n'a pas la clef"
    Tu peux en dire plus sur le vecteur d'initialisation courant ? Comment est-ce qu'on le connait ? On peut le choisir arbitrairement ?

    Merci

    RépondreSupprimer
  3. Le vecteur d'initialisation est envoyé avec le paquet en clair.

    RépondreSupprimer