
Implémentation en Rust de la preuve de concept d'injection de frappes de Marc Newlin (CVE-2023-45866).
⚠️ Avertissement : À des fins de recherche et d'éducation uniquement
Ce projet est une Preuve de Concept (PoC) démontrant l'injection de frappes Bluetooth, réimplémentée en Rust. Il est destiné strictement à des fins éducatives et de recherche en sécurité.
En téléchargeant, clonant ou utilisant ce code, vous acceptez de l'utiliser de manière responsable et en conformité avec toutes les lois et réglementations applicables.
Bienvenue sur Rusty Injector — une implémentation en Rust inspirée de la Preuve de Concept d'injection de frappes Bluetooth de Marc Newlin, liée aux CVE-2023-45866, CVE-2024-21306 et CVE-2024-0230.
Actuellement, ce dépôt n'implémente que CVE-2023-45866, qui exploite les vulnérabilités d'injection de frappes dans BlueZ sur le système d'exploitation Linux.
Ci-dessous une capture d'écran de la description du NIST, incluant le score CVSS :
Capture 1 : Description NIST de CVE-2023-45866.
Les autres CVE, CVE-2024-21306 et CVE-2024-0230, ne sont pas prévues pour être implémentées par moi-même, mais les contributions sont chaleureusement bienvenues.
Avant d'entrer dans les détails, je vous encourage à regarder la présentation de Marc Newlin à la conférence NullCon 2024, car elle offre une explication claire et approfondie de ces vulnérabilités : Hi, My Name Is keyboard par Marc Newlin..
J'ai également mis à disposition une vidéo qui vulgarise cette vulnérabilité. Vous la trouverez ici : Comment un simple hack Bluetooth peut pirater votre appareil - Hi, my name is keyboard.
📌 Si vous remarquez des points manquants, des domaines qui pourraient être mieux simplifiés, ou des erreurs potentielles dans l'explication ci-dessous, n'hésitez pas à la modifier et à soumettre une demande de fusion. Je serais ravi d'examiner vos contributions et de les intégrer dans le dépôt.
Comme nous n'avons couvert que la vulnérabilité CVE-2023-45866 concernant les systèmes d'exploitation Linux, nous expliquerons uniquement le processus pour parvenir à cette exploitation spécifique ciblant la bibliothèque BlueZ.
Tout d'abord, vous devez comprendre que cette vulnérabilité n'est exploitable que sur Bluetooth BR/EDR car elle cible le profil HID reposant sur cette technologie. Vous savez peut-être que l'implémentation architecturale Bluetooth est divisée en plusieurs couches, comme le modèle OSI pour le protocole Ethernet, comme vous pouvez l'observer sur notre schéma ci-dessous.
Diagramme 1 : Pile Bluetooth BR/EDR (Basic Rate - Enhanced Data Rate) simplifiée. La couche la plus basse de la pile représente la couche physique avec une antenne dédiée, et le niveau le plus élevé représente le niveau applicatif ou ce que l'on peut parfois désigner comme le système d'exploitation. Lorsque deux appareils souhaitent communiquer entre eux, ils traversent ces différentes couches : de haut en bas pour les paquets sortants et de bas en haut pour les paquets Bluetooth entrants.
Après le processus d'inquiry, une fois que les appareils déterminent qu'ils souhaitent établir une connexion, ils procèdent au processus d'appairage. Ce processus permet l'authentification mutuelle entre les appareils et l'établissement d'une clé de chiffrement, utilisée ensuite pour sécuriser la communication.
La spécification Bluetooth offre différents niveaux d'authentification et de sécurité. Selon le mécanisme utilisé pour l'authentification, le niveau de sécurité de la communication peut varier. Les appareils peuvent s'authentifier en fonction des périphériques d'entrée et de sortie qu'ils possèdent, un concept appelé modèles d'association. Vous avez probablement déjà rencontré cela lors de l'appairage de deux appareils—par exemple, lorsqu'on vous demande de saisir un code PIN affiché sur l'autre appareil.
Il existe quatre modèles d'association d'appairage, déterminés par les capacités d'E/S (Entrée/Sortie) des appareils :
Voici un tableau montrant quel modèle d'association est utilisé en fonction des capacités de nos appareils IoT.
Diagramme 2 : Tableau illustrant les modèles d'association Bluetooth BR/EDR inspiré de la spécification Bluetooth Core v5.3 - 2.3.5.1 Selecting key generation method Table 2.8 : Mapping of IO capabilities to key generation method (page 1573). Pour plus d'informations sur les modes de sécurité et les modèles d'association, consultez cet intéressant article de blog publié par Thyrasec : Bluetooth Security : Classic & BLE !
Je suis sûr que vous êtes intrigué par la méthode 'Just Works', qui est précisément là où se trouve notre vulnérabilité. Voici le problème : cette méthode établit l'appairage sans nécessiter de confirmation ou d'interaction de l'utilisateur, ne laissant aucun moyen de vérifier l'authenticité de l'appareil d'appairage. Sur les systèmes Linux, la pile BlueZ, par défaut, acceptait les demandes d'appairage entrantes d'appareils classés comme NoInputNoOutput (pour assurer la rétrocompatibilité). Un choix de conception vraiment "merveilleux", n'est-ce pas ?
Capture 2 : Mise à jour de la configuration par défaut de BlueZ pour activer la sécurité Bluetooth et corriger CVE-2023-45866.
Après l'appairage avec l'appareil cible, notre système établit une connexion au Service Discovery Protocol (SDP) via le port 1 de la couche L2CAP. Comme le montre le Diagramme 1, la couche L2CAP sert d'intermédiaire entre les couches de service inférieures et supérieures, assurant la segmentation, le multiplexage et le réassemblage des paquets de données. Grâce à la connexion SDP, nous identifions tous les services disponibles sur l'appareil cible et nous connectons au service du profil d'interface humaine (HID). Le profil HID, utilisé par les systèmes d'exploitation pour traiter les entrées des claviers et souris Bluetooth, fonctionne via les ports 17 (HID Control) et 19 (HID Interrupt) de la couche L2CAP. Pour accéder au profil HID, aucune authentification n'est requise et tout appareil connecté aux ports 17 et 19 de L2CAP est reconnu comme un périphérique HID.
Un attaquant peut usurper les services et la classe d'appareil d'un clavier Bluetooth sans fil, exploiter le modèle d'association 'Just Works' en spécifiant une capacité 'NoInputNoOutput', et injecter des frappes non autorisées dans l'appareil cible.
Pour être tout à fait honnête, le seul objectif était de réimplémenter la preuve de concept en Rust pour mieux comprendre les subtilités de cet exploit. C'est pourquoi, dans cette première itération, l'architecture globale a été inspirée par la preuve de concept Python de Marc Newlin : Github "hi_my_name_is_keyboard". Dans une future refonte, il pourrait être implémenté de manière plus rustique.
Crates (= bibliothèques Rust) utilisées lors de cette implémentation :
[dependencies]
bluer = { version = "0.17.3", features = ["l2cap", "bluetoothd", "id", "rfcomm"] }
tokio = "1.42.0"
regex = "1.11.1"
clap = { version = "4.5.23", features = ["derive"] }
La dépendance clé de mon projet était 'BlueR', une API Rust construite sur la bibliothèque C originale BlueZ. Vous pouvez consulter leur travail ici : GitHub BlueR. J'ai également intégré Tokio pour permettre l'utilisation des fonctions async fournies par la bibliothèque BlueR. De plus, j'ai utilisé Clap, un analyseur d'arguments en ligne de commande, et Regex, une crate qui implémente les expressions régulières en Rust, pour valider les entrées utilisateur pour le 'bt_addr' (adresse Bluetooth).
Après observation de l'implémentation de Marc Newlin, j'ai décomposé l'architecture en plusieurs étapes pour reproduire la même fonctionnalité :
--iface ou -i qui représente l'interface/adaptateur Bluetooth à utiliser. Cet argument est facultatif ; si rien n'est spécifié, il tentera d'atteindre un adaptateur par défaut.--target ou -t qui est obligatoire et spécifie l'adresse Bluetooth de la cible.NoInputNoOutput pour pouvoir accéder à la méthode d'appairage "Just Works" lors de la connexion avec l'appareil cible.0x002540 pour usurper un clavier.J'ai essayé de commenter mon code autant que possible. Si vous le parcourez, vous reconnaîtrez facilement toutes ces étapes. Pour le rendre plus élégant, la prochaine étape serait de le rendre plus rustique, d'avoir une terminaison gracieuse et d'ajouter plusieurs autres fonctionnalités comme la capacité d'analyser des scripts de clavier (charges utiles préparées) ou d'avoir une interface utilisateur graphique. Encore une fois, cela n'était qu'à des fins éducatives ; je ne suis pas sûr de travailler sur d'autres itérations de ce programme. Mais encore une fois, les contributions sont chaleureusement bienvenues. Si vous avez des questions, n'hésitez pas à les poser.
Première chose à noter : Cet outil a été développé et testé sur Ubuntu 24.04.
Pour utiliser cet outil, vous devez désactiver le service HID par défaut enregistré par BlueZ, afin qu'il puisse être réenregistré lors du lancement de l'exploit. Suivez ces étapes :
/etc/systemd/system/bluetooth.target.wants/bluetooth.serviceExecStart=/usr/libexec/bluetooth/bluetoothd
Par la suivante :
ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=inputsudo systemctl daemon-reload
sudo systemctl restart bluetoothMaintenant, il vous suffit de récupérer le projet et de l'exécuter en le compilant avec cargo build ou en l'exécutant directement en spécifiant les arguments avec :
cargo run -- -i [INTERFACE_BT] -t [CIBLE_BT].
Capture 3 : Interface en ligne de commande de Rusty Injector.
Voici un exemple :
cargo run -- -i hci0 -t AA:BB:CC:DD:EE:FF
Autre chose à noter : si vous souhaitez modifier le code et utiliser la fonction "set_address" via le trait Configuration, vous devez installer l'outil bdaddr pour pouvoir l'utiliser :
# construire bdaddr à partir des sources de bluez
cd ~/
git clone --depth=1 https://github.com/bluez/bluez.git
gcc -o bdaddr ~/bluez/tools/bdaddr.c ~/bluez/src/oui.c -I ~/bluez -lbluetooth
sudo cp bdaddr /usr/local/bin/
Veuillez noter que si vous ne spécifiez aucune interface Bluetooth, il tentera d'atteindre une interface par défaut. Et ÉVIDEMMENT, n'oubliez pas de brancher une interface Bluetooth à votre système d'exploitation Ubuntu.🙃
Je pense avoir couvert tous les points—vous êtes maintenant prêt à tirer le meilleur parti de Rusty Injector ! Si vous rencontrez des problèmes ou avez des commentaires ou des retours, n'hésitez pas à ouvrir une issue. Vivez une expérience incroyable et bon hacking ! 🚀