KRACK : Review
Salut tout le monde
Bon, toute personne ayant suivi un minimum l’actu sécu ces jours ci aura forcément entendu parler de KRACK, la nouvelle vulnérabilité contre le WPA2.
Découverte et rendue publique par Mathy Vanhoef, cette attaque permet en gros, d’exploiter une faiblesse dans l’implémentation de WPA2.
Mais ici, pas de buzzword comme “WPA2 est cassé”, “Le protocole WPA n’est plus” ou autre trucs de marketeux.
Nan, ici, on va parler technique et expliquer un peu plus en détails le fonctionnement d’une des attaques. Parce que oui, en fait, il y en a plusieurs. Je vais donc expliquer la méthode la plus basique (en espérant ne pas avoir dit trop de bêtises; si c’est le cas, il ne faut pas hésiter à me corriger :) )
Pour tout comprendre, il faut déjà garder en tête une des finalités de KRACK : pouvoir faire un “Man In The Middle” (on notera les guillemets, j’expliquerai plus bas pourquoi).
Maintenant, place aux explications !
Back to basics
Avant même de parler de la vulnérabilité en elle même, il faut comprendre le fonctionnement d’un “Nonce” : c’est un message (nombre, lettres, peut importe), qui doit être utilisé une seule et unique fois, afin d’éviter des attaques par rejeu. Par exemple, si un serveur envoie un Nonce de “54321”. Le client enverra une réponse contenant “54321”. Le serveur doit ensuite considérer que “54321” n’est plus valide et générer un nouveau Nonce. Ainsi, si un attaquant essaie de relancer le message du client (qu’il a obtenu via une écoute du réseau par exemple), le serveur voyant le Nonce de “54321” saura qu’il y a attaque par rejeu et rejettera le paquet.
Le coeur de la faiblesse : le 4 way handshake.
Bon, maintenant, comment fonctionne exactement une connexion wifi en WPA2 ?
La phase d’authentification s’appelle le 4 Way Handshake, tout simplement parce qu’il y aura un échange de quatre paquets entre le client (le supplicant en VO) et le point d’accès wifi (l’authenticator en VO).
Lorsqu’un client effectue une demande de connexion, il se passe (entre autres) ces étapes :
-
l’AP (point d’accès) va envoyer un premier message qui contiendra un compteur et ce qu’on appelle un ANonce (Authenticator Nonce, qui est juste un nombre ici)
-
Grâce à cela, le client va pouvoir calculer une PTK (pour Pairwise Transient Key). Cette PTK est basée sur la clé Wifi, le ANonce, le SNonce (qui est le Supplicant Nonce, généré à la réception du ANonce), et les adresse MAC de l’AP et du client. En gros, le calcul est hash(ANonce+SNonce+Clé wifi+MAC AP+Mac supplicant).
-
Une fois la PTK calculée, le client va envoyer un deuxième message, vers le serveur. Ce message contiendra le même compteur que précédemment, et le SNonce.
-
Coté AP, la PTK va être calculée exactement de la même manière que précédemment. Ainsi, le client et l’AP auront la même PTK. A ce point du handshake, même si un attaquant espionne les connexions, il ne pourrait pas casser la connexion, puisque même s’il a pu capturer le ANonce et le SNonce, la PTK est basée en partie sur la clé Wifi.
-
Une fois la PTK connue des deux cotés, l’AP envoie dans le troisième message ce qui s’appelle une GTK (Group Transient Key), ainsi que le compteur, incrémenté de 1. La GTK est une clé envoyée de manière chiffrée grâce à la PTK et sert pour envoyer de messages en multicast et broadcast.
-
Le client envoie enfin le 4ème et dernier message, qui est juste un accusé de réception du troisième. Dans le même temps, il valide la PTK et la GTK, qui sont donc considérés comme valides.
-
A la réception de l’accusé, l’AP va de son coté valider la PTK
Voilà pour la partie détaillée. Pour faire plus simple, ça fait quelque chose comme :
“Salut client, on s’authentifie ? Tiens, un message secret : poulpe”
“Coucou AP, ok pour s’authentifier. Voilà mon message secret : epluop”
“OK, tout est correct, voilà une clé chiffrée que tu dois déchiffrer pour discuter en multicast : cbhycr”
“Nickel, j’ai bien reçu ta clé chiffrée.”
Une fois que ce 4 way handshake est passé, le client et l’AP peuvent discuter de manière chiffrée.
Schématiquement, ça ressemble à ça :
Pourquoi tout-il-est-cassé ?
En soi, le design est (presque) correct. Ce qui pose problème, c’est (en partie) l’implémentation par les différents constructeurs de ce handshake. L’implémentation dans une utilisation classique est correcte (encore heureux, sinon, on pourrait pas utiliser de WPA2 ^^)
Bon. Imaginons maintenant qu’on puisse se mettre ENTRE le client et l’AP, que pourrait-il se passer ? Juste comme ça, absolument rien : même si on récupère le ANonce et le SNonce, on ne pourrait pas récupérer la PTK, celle ci étant créée grâce à la clé WIFI (et donc pas la GTK non plus, mais c’est pas grave) ce qui rendrait impossible le déchiffrement des trames suivantes.
Cela dit, et c’est là que le bas blesse, la méthode de validation de ce 4way handshake est un peu foireuse selon les cas.
L’attaque fonctionne ainsi :
Entre le client et l’AP, un rogue AP est créé par l’attaquant. Il sera donc en position de Man In The Middle et pourra voir passer tous les paquets. Lors du 4way handshake, voilà ce qui va se passer :
- l’AP envoie son ANonce. L’attaquant le laisse passer et le renvoie donc au client
- le client envoie son SNonce. Comme précédemment, l’attaquant le voie et le laisse passer vers l’AP
- le serveur va donc envoyer sa GTK, avec son compteur, incrémenté de 1. L’attaquant ne touche à rien et le paquet arrive au client
- enfin le client envoie son ACK final. C’est ici que tout se joue : l’attaquant bloque ce paquet.
La suite est un peu plus tricky :
- A ce stade, tout semble OK pour le client, il installe sa PTK et GTK. Sauf que l’AP n’ayant pas reçu le ACK du client, il va renvoyer la GTK, avec un compteur incrémenté encore une fois de 1.
- le client reçoit ce paquet. Que fait il ? Bêtement, il voit un paquet contenant une GTK, il se dit, “OK je réinstalle ma GTK, ma PTK, et je réinitialise mon compteur”
A ce niveau, que s’est-il passé ? Le serveur à envoyé deux messages contenant la GTK : celui contenant compteur+1, et celui contenant compteur+2 (en soi, la GTK on s’en fout, c’est le compteur qui est important)
Le client a envoyé un ACK contenant compteur+1, qui a été bloqué par l’attaquant, puis un autre message, contenant compteur+2.
Sauf que l’AP n’a reçu que celui contenant compteur+2, le message ayant compteur+1 étant tombé aux oubliettes.
Un bon schéma des familles pour mieux comprendre :
Dans un flux “normal”, n’importe quel message contenant compteur+1 devrait être rejeté par l’AP. Cependant, la RFC définit ceci :
“On reception of message 4, the Authenticator verifies that the Key Replay Counter field value is one that it used on this 4-way handshake”
Autrement dit, puisque l’AP a envoyé des messages compteur+1 et compteur+2 AVANT de recevoir le ACK du client (contenant compteur+2, tout le monde suit ?), il accepte des messages contenant compteur+1 ET compteur+2.
Enfin, puisque le client a réinitialisé son compteur, il va donc renvoyer un message contenant compteur+1. Ainsi, il fait exactement ce qu’il ne faut pas faire : du Nonce reuse. L’AP considérera ce compteur comme valide, puisqu’envoyé avant réception du ACK final.
Il est possible que certains soient perdus (c’est mon cas par exemple), mais c’est pas encore fini ^^’.
Très bien, on peut effectuer des attaques par rejeu. Mais bon, que peut on en faire ? Selon les protocoles, les résultats sont différents, mais on se base au final sur des attaques connues :
- sur TKIP, il est possible de déchiffrer et injecter des paquets. Cela est possible car le chiffrement est faible. En gros, le chiffrement des paquets se fait en RC4, avec une clé de 128 bits basé sur la PTK, la MAC de la source et le Nonce. Comme on connait la MAC, et le Nonce, on peut casser facilement le RC4 et donc injecter des paquets. (ce qui ne signifie pas qu’on récupère la clé wifi, juste la clé temporaire.)
- pour le CCMP, c’est basé sur AES. Donc, c’est un peu poil plus chaud. Mais comme on est aussi basé sur le Nonce, on peut à priori déchiffrer plus facilement.
- pour le GCMP, le Nonce reuse fait des massacres ici : “If a nonce is ever repeated, it is possible to reconstruct the authentication key used by the GHASH function”. Mais pour comprendre ça, il faut lire un autre paper, et il est déjà 23H
On notera que selon les techniques d’attaque, il est possible d’effectuer du rejeu/déchiffrement/injection dans un sens ou l’autre (client vers AP ou l’inverse).
Mais au fait, comment on fait un MITM AP sinon ?
Alors, pour cette partie, c’est plus simple. c’est également une attaque connue, mais c’est rigolo.
Le but est donc de créer un Roque AP, et que le client se connecte dessus. Pour cela, va donc falloir créer un AP qui possède le même nom et la même adresse MAC que l’AP original, mais sur un canal différent.
Si le client se connecte directement sur notre AP, il suffit de forwarder les paquets à l’AP réel et tout est bon. Mais il y a aussi des chances pour qu’il tente de se connecter à l’AP d’origine.
Du coup, pour être sur que le client se connecte sur notre AP, on va faire ce qu’on appelle du jamming. En gros, on envoie un max de signaux pourrie à la véritable AP, qui va plus pouvoir répondre. Comme notre AP répond au même nom et à la même MAC que la véritable, le client va tout simplement se connecter sur notre Rogue AP. Juste après ça, on arrête le jam pour pouvoir retransmettre les paquets.
C’est ce qu’on appelle un Channel Attack.
La question, c’est pourquoi un Channel Attack ?
La réponse est simple : si on créé un AP n’ayant pas la même MAC, le calcul de la PTK sera éronné et l’attaque ne fonctionnera tout simplement pas. Du coup, on est obligé d’avoir la même MAC. Mais évidemment, on ne peut pas se mettre sur le même channel, sinon le client ferait la gueule ^^
Pour résumer, KRACK, c’est une combinaison de plusieurs attaques :
- Rogue AP, avec un Channel Attack
- Une fois en position de MITM, on va sélectionner des paquets à renvoyer ou non vers le client
- Suite à ça, le client va réinitialiser son compteur
- le compteur étant utilisé comme Nonce, il sera réutilisé
- ce qui nous permet de faire des attaques par rejeu
- et dans certains cas de pouvoir injecter des paquets
Pour info, j’ai honteusement copié le post que j’ai créé sur Newbie Contest. Du coup, ça fait un peu réchauffé (avec des schémas en plus quand même), mais ça m’a au moins motivé à lancer LsdSecDaemon :)
Enjoy
The lsd
Liens utiles :
Paper : https://papers.mathyvanhoef.com/ccs2017.pdf
Site de KRACK Attacks : https://www.krackattacks.com/
AP Jamming : https://people.cs.kuleuven.be/~mathy.vanhoef/papers/acsac2014.pdf et https://www.cs.montana.edu/yang/paper/jamming.pdf
Un POC pour tester, tout frais : https://pastebin.com/aZyyS16w
Une vidéo de vulgarisation : https://www.youtube.com/watch?v=fOgJswt7nAc
L’article de pixis sur cette attaque, je vous le conseille fortement : http://beta.hackndo.com/krack/