 Le chaos digital distribué vous présente maintenant pas de POC, pas de FX, une bien triste histoire sur la sécurité Bluetooth. POC c'est Proof of Concept et pas autre chose. Et on parle ici bien sûr de technologie. Donc le sous-titre c'est juste un même copie cassé dans la stack Bluetooth. Est-ce qu'il y a vraiment besoin de corriger ça ? C'est une présentation par Yann Rouga qui va nous parler de ce qu'il a trouvé dans CPS Bluetooth. A toi Yann. Bonjour, je suis Yann Rouga et le titre comme on l'a dit c'est pas de POC pas de FX Et je veux parler aujourd'hui de quelque chose que j'ai trouvé en termes de sécurité dans les puces Bluetooth. J'ai aussi parlé de la méthodologie que je suivis ainsi que du processus de disclosure, de communication avec le fabricant. Alors pourquoi est-ce que j'ai fait ça ? Pendant que j'étais à l'université il y a eu un projet de patching de firmware, notamment sur les contrôleurs wifi de chez Broadcom. Et l'idée principale était qu'on pouvait implémenter un mode de monitoring sur le Nexus 5, ce qui n'était pas possible avant. Donc ils ont construit tout ce système de patch pour le firmware autour, ce qui permettait de modifier le firmware. Et ça comme conséquence, ça a eu que d'autres équipes ont pu utiliser cette technologie, notamment le Project Zero de Google pour l'Exploit qui s'est appelé Road Pound, mais aussi par Quartz Club en April 2019. Donc ça c'est quelque chose qu'il faut garder à l'esprit. Quand vous faites du Reverse Engineering et que vous vous liez à ce que vous avez trouvé, d'autres peuvent aussi utiliser ça pour trouver des exploits. Et ça c'est bien sûr uniquement ceux qui sont codés publiquement. Il y en a peut-être d'autres dont on n'a pas entendu parler. A Simo, il y a pas mal de recherches à propos des contrôleurs Bluetooth de chez Broadcom, comme vous avez pu le voir dans la présentation précédente. Donc il y a cet outil qui s'appelle Internal Blue qui ajoute un système de debug au sein même des contrôleurs Bluetooth. Et on se confronte à nouveau au problème qu'on publie beaucoup de choses sur les contrôleurs Bluetooth. Et on aimerait donc trouver les bugs avant les autres, s'il y a des bugs qui sont un peu trop simples à trouver. Donc un peu d'information préliminaires, donc Bluetooth vous le connaissez probablement déjà tous. C'est un protocole radio qui opère à 2,4 GHz, qui est principalement utilisé pour communiquer entre deux périphériques, peut-être plus. Par exemple un téléphone mobile, un smartphone qui communique avec votre casque. Et ce que vous ne savez pas, c'est que ce que certains ne savent pas, c'est qu'il y a des périphériques mobiles avec le Bluetooth déjà activé. Et on peut aussi connecter par défaut. Donc par exemple vous pouvez utiliser L2Ping, L2Ping, qui permet de pinger sur la couche physique un périphérique Bluetooth. Donc ça c'est une surface d'attaque assez large, parce qu'on a accès déjà à toute la stack Bluetooth à travers ces paquets. Il y a aussi des protocoles plus bas niveau qui sont eux terminés dans le firmware et qui ne sont pas accessibles par l'autre. C'est souvent des protocoles qui sont mal documentés et qui sont assez souvent sujets à des bugs. Donc la plateforme qu'on va utiliser, c'est celle que je vous montre ici. C'est une borde de développement de chez Cypress. Si on dit Cypress et Broadcom, j'utilise les deux termes plus ou moins de façon interchangeable, puisque Cypress a acheté Broadcom Wireless il y a quelques années. Donc le copyright sur le firmware c'est Broadcom dans les deux cas. Donc on a aussi utilisé une borde Bluetooth Low Energy sur laquelle on peut exécuter du code C. Donc on a un environnement de développement dans lequel on peut exécuter du code arbitraire sur le contrôleur en C. Et ce qui est intéressant ici, c'est qu'il n'y a pas de séparation entre l'application qui s'exécute sur le contrôleur et le firmware. Donc c'est-à-dire que l'application qu'on écrit peut lire toutes les régions en mémoire du firmware. On peut lire la RAM, on peut lire la mémoire morte, la ROM et on peut même l'attaquer. Alors de plus, il y a des outils qui permettent d'utiliser, qu'on compétise dans notre code en C directement pour interagir avec le firmware. Donc l'environnement de développement a fourni l'environnement de développement publié directement les noms, les fonctions, les variables globales, les registres hardware. Et ça, ça nous a rendu la vie beaucoup plus facile en termes de reverse engineering. Donc parlons maintenant des protocoles Bluetooth importants ici. Donc à droite il y a un diagramme, en haut vous avez l'autre et en dessous vous avez le firmware en gros là. Donc ici en haut vous voyez qu'il y a un protocole L2CAP, ça c'est la couche la plus basse qu'on peut utiliser pour communiquer entre deux périphériques à Bluetooth. Donc ce protocole est enveloppé dans le protocole HCI qui est un protocole de communication pour que l'autre parle au firmware. Le firmware lui-même a des registres UART pour l'interface série en vert et vous avez en dessous en bleu des composants pour le firmware multisredé. Donc ça c'est des composants qui permettent d'implementer plusieurs threads. En haut vous avez BT Transport qui est un thread qui est responsable qui s'occupe du multiplexing des messages HCI. En dessous vous avez le link manager. Donc ça c'est un processus qui génère des messages HCI et qui génère aussi des messages du link manager, du L2CAP, le protocole dont j'ai parlé au début qui est accessible par l'autre. Et le link manager contrôle également quelque chose qui s'appelle le Bluetooth cross scheduler, le scheduler cross bluetooth. C'est un composant indépendant qui est développé par Broadcom, c'est un scheduler spécifique à CEPUS. Et donc à chaque cycle Bluetooth qui est environ 300 microsecondes, ce composant invoque cette fonction qu'on voit en bas à droite, Bluetooth score int C. Donc toutes les 300 microsecondes et ça s'occupe de plusieurs tâches critiques pour le protocole Bluetooth. Alors un peu plus de background, donc j'ai parlé du projet internal blue que vous pouvez utiliser pour débugger des firmware. Ce projet a été développé d'abord pour le Nexus 5 sur lequel ils n'avaient pas de symbole. Donc ils ont fait de l'assembler en UAM et donc même s'ils ont eu accès au link manager protocole et même s'ils ont pu extraire les messages et envoyer des messages arbitraires, dans cette présentation je parlais d'autres choses, je parlais du projet Frankenstein qui est un framework de patching en C qui est aussi ce qui a été utilisé pour révéler le Bluetooth score scheduler. Alors pourquoi est-ce que c'est important ? Parce que si on regarde un paquet Bluetooth au niveau physique, donc au début du message vous avez ce qui est le channel accesscon, ça c'est simplement un identifiant entre deux périphériques. Ensuite vous avez le header de paquet qui décrit globalement quel type de paquet est envoyé, parce que c'est un paquet de management, c'est un paquet de données. Ensuite vous avez le header des données en eux-mêmes, avec notamment la longueur, le flow, etc. Et ensuite vous avez la payload et le Bluetooth score scheduler lui n'a accès que à la payload. Donc si vous avez accès à l'autre, vous pouvez écrire des paquets que vous voulez en L2K et vous pouvez envoyer aussi, vous pouvez pas envoyer de paquets de management arbitraires. Mais si vous avez accès au scheduler, vous pouvez envoyer des paquets de management et pas que des paquets de données, vous avez accès à tous ces headers complètement librement. Donc ça c'est un endroit très intéressant et on a pu trouver quelques bugs intéressants dedans. Alors la principale technique qu'on a pu exploiter là-dedans, ça a été le hooking, c'est-à-dire que comme on pouvait exécuter du code C dans le contrôleur, on pouvait ajouter notre propre mécanisme de hook, ce qui nous permettait de debugger le firmware et par exemple de tracer les appels ou d'extraire les arguments qui sont utilisés pour appeler cette fonction. Et on s'en est aussi servi pour implémenter certaines attaques puisqu'on voulait avoir accès au protocole directement au plus bas niveau. On s'en est aussi servi pour faire du fosing. Une des choses qu'on a fait assez tôt dans notre cher, c'est qu'on a trouvé la fonction qui sert à copier les payloads du buffer d'envoi au buffer d'envoi hardware et donc on a pu rajouter un hook sur cette fonction. Et à ce point là dans l'exécution, on peut modifier le paquet qui est sur le point d'être envoyé et notamment implémenter du fosing par exemple. Donc à ça que ça ressemble en pratique, c'est le code, le vrai code. Donc on ajoute un hook ici avec cette fonction bcs dma tx enable eir. Donc ça c'est une fonction qui est responsable pour envoyer les paquets à partir du send buffer. Donc c'est une fonction qui va être appelée par exemple si vous faites un scan des périphériques de tous disponibles, cette fonction sera appelée pour envoyer la réponse. Donc c'est une fonction qui est appelée souvent et sur laquelle on a accès à beaucoup de données. Et on peut voir en dessous la fonction qui est invoquée avant la copie de ce paquet du buffer d'envoi au buffer d'envoi hardware. Et donc ici tout ce qu'on fait c'est qu'on rend aléatoire l'adresse de tous puis on inverse quelques bits aléatoires dans la payload et c'est tout. Donc moi j'ai écrit ce code, je l'ai flashé sur le contrôleur et ensuite j'ai commencé à scanner avec mon laptop et ça a craché le contrôleur de mon T430, mon laptop. Ok, alors le problème ici c'est que le T430 c'est un vieux laptop. Le firmware date d'environ 2010, on n'est même pas sûrs d'eux quand il date exactement parce qu'on n'a pas vraiment regardé dedans. On a essayé la même technique sur des périphériques plus récents même quelque chose comme avec ce 5 qui est quand même relativement vieux maintenant et ils avaient pas l'air d'être affectés par ce crash. Donc je me suis dit c'est peut-être pas utile de faire ça mais j'en ai parlé avec Jiska et elle a dit peut-être que tu devrais regarder quand même. Alors j'ai essayé de regarder mais j'avais pas de symbole pour le firmware donc c'était assez difficile de deviner ce qui se passait. À un moment donné j'avais une image du crash et j'avais l'impression, ça ressemblait à une corruption du heap parce qu'il aurait semblé qu'il y avait des fonctions qui étaient appelées qui manipulaient le heap et ça c'est assez problématique parce que dans cette implementation du heap si vous avez un buffer overflow vous pouvez réécrire un pointeur quelque part et ensuite vous libérer le buffer est tout à l'air bien et un peu plus tard vous essayez d'accéder à ces données corrompues et ça crash. Donc c'est presque impossible de corruler le crash avec la cause du crash. Donc on n'a pas eu beaucoup de chance avec celui-là mais du coup on est passé à autre chose et on s'est intéressé surtout à l'émulation du firmware dans notre recherche. Donc l'idée de base c'est que le firmware est juste hard-coded et on peut peut-être extraire un état bien défini du firmware dans lequel on a tous les registres et toute la mémoire et à restaurer les registres et essayer de réexécuter le code à cet endroit-là donc on peut voir à droite le code ou on va essayer de faire ça on a cette fonction xmit state qu'on peut aussi invoquer dans un hook tout ce que ça fait c'est que ça sauvegarde les registres sur la stack ça sauvegarde le pointeur de stack à un endroit fixe en mémoire et ensuite on appelle la fonction xmit memory qui elle va d'abord désactiver toutes les interruptions pour qu'il n'y ait pas d'autres codes qui s'exécutent au même moment on va envoyer toutes les régions de mémoire qui les intéressent à l'autre donc ça c'est un endroit où il ne faut pas utiliser de fonctions qui par exemple utilisent de thread puisque au monopolis on utilise le thread BT transport donc on utilise juste les registres hardware pour faire notre dame de mémoire et donc maintenant qu'on a dumpé la mémoire dans l'autre on peut appeler la fonction de compte, de continuation qui va simplement restaurer les registres à partir à cet endroit et avec ça on peut recommencer l'exécution alors voyons ce que ça peut donner comme résultat de faire ça d'abord on a toute la mémoire ici mais on n'a pas forcément le LUART donc il faut qu'on fasse quelques modifications au firmware pour pouvoir l'exécuter donc ça c'est l'approche qu'on a prise on a utilisé l'ébullateur QMU ARM parce que c'est plutôt pratique de pouvoir utiliser QMU donc on a d'abord notre firmware, on a nos dames de mémoire ensuite on a pu convertir ça en fichiers objets on a pu faire une communication, on a pu écrire du code en C qui existe dans le même espace adressage que le firmware donc on peut aussi compiler ça pour en faire un fichier objet, un point haut et comme j'ai dit avant on a déjà la liste complète de toutes les fonctions de toutes les globales etc donc on peut simplement linker notre code C contre le firmware qu'on a extrait de la puce et avec ça on peut écrire du code C qui va s'exécuter dans le même espace adressage mémoire donc on peut passer des structures de données etc et simplement appeler le code du firmware donc à la fin on a notre code qui est linké, on peut en faire un fichier ELF et ce fichier ELF décrit l'espace mémoire d'exécution et le firmware et à la fin on a rajouté une page supplémentaire dans laquelle se trouve notre code C qui lui fait quelques modifications dans la ROM et dans la RAM et on peut donc modifier les registres et faire ce qu'on veut ici donc la prochaine chose qu'on a fait ça a été ajouter beaucoup de messages de debug pour qu'on puisse tracer le code et l'exécution pour qu'on comprenne ce qui se passe dans le firmware et avec ça on a pu implémenter le trending on a pu aussi injecter et extraire des messages du protocole HCI et on a aussi pu injecter ou extraire des paquets directement au niveau physique sur la couche wireless donc avec ça on peut utiliser HCI on peut attacher notre emulateur comme un périphérique Bluetooth dans notre OS et on peut émettre des paquets qui vont être interprétés par le firmware comme si c'était des vrais paquets qui étaient arrivés sur les ondes et on peut voir comment ça se passe au niveau de l'OS et donc ça c'est ce que je vais vous montrer maintenant dans une démo j'espère que ça va marcher donc ici je fais tourner Ubuntu, vous pouvez voir ici je vais agrandir un petit peu donc là vous pouvez voir que j'ai la configuration Bluetooth avec les paramètres, c'est l'écran standard Ubuntu il n'y a pas d'adaptateur Bluetooth connecté à l'heure actuelle ici j'ai Btemon qui tourne donc on peut voir ce qui se passe au niveau HCI et j'ai aussi un watch qui me montre toutes les deux secondes HCI config qui montre qu'à l'heure actuelle je n'ai pas d'adaptateur Bluetooth et donc ici j'ai la magie qui se passe donc HCI attache l'eubinaire c'est mon émulateur que je peux faire tourner qui va automatiquement s'attacher à la stack Bluetooth de l'OS et je lui envoie simplement des données aléatoires donc AMO firmware que j'émule et je vois comment ça se passe et dès que j'exécute vous pouvez voir qu'on a beaucoup de logs qui nous disent qui se passe typiquement on peut voir dans Btemon qu'on a un nouvel adaptateur qui est actif et qui envoie des données et donc ici on peut voir même au niveau de Bluetooth que le firmware s'est identifié comme adaptateur Bluetooth et qu'on a commencé à scanner les périphériques disponibles et donc on peut voir ici que l'adaptateur voit des frame wireless et on peut voir ici qu'on a des événements comme par exemple device found un autre périphérique a été trouvé et donc bien sûr on a aussi beaucoup de logs et avec un petit peu de chance ouais ah bon c'est une des mots donc bien sûr ça ne marche pas mais bon je vais recommencer donc là on peut voir que ça scan pour essayer de trouver d'autres périphériques d'autres pairs bon c'est pas bien grave donc ce que vous pouvez voir c'est qu'on a beaucoup de logs ici et une autre chose intéressante c'est qu'on peut réexécuter un état du firmware qu'on a sauvegardé donc par exemple ici on a un fronten web dans lequel je peux exécuter le firmware et voir encore plus de choses sur ce qui se passe à l'intérieur donc ici j'ai le firmware compilé de telle façon que ça va simplement exécuter le firmware avec les patchs qu'on y a ajoutés alors on peut voir que dans nos patchs on a des logs de debug on a par exemple des informations sur les context switch les allocations mémoires etc on peut aussi voir ici la mémoire pour voir ce qu'il y a quelles régions en mémoire ont été modifiées et quelles symboles sont attachées à ces adresses en mémoire et tout en bas on a aussi une map de l'activité en mémoire où on peut voir quelles régions en mémoire sont exécutées lues ou écrites et on peut même zoomer pour voir plus en détail et on a bien sûr les symboles qui sont anotées ici aussi pour nous dire quelles symboles du firmware correspondent à ces adresses alors bon désolé que la démo n'ait pas marché ce qui aurait dû se passer à un moment donné avec les frames de device inquiry il y a un bug dans le firmware et à un moment donné vous auriez dû avoir une corruption du heap et on aurait dû avoir donc un erreur de heap corruption détecté corruption du heap détecté et ça c'est ce que vous auriez vu dans la console si on avait un peu plus de chance dans la démo donc j'ai ajouté quelques données de debug ici pour qu'on voit l'état du heap ok et donc ici vous pouvez voir qu'on a une allocation à l'adresse de 109 hexadecimal octaves et ensuite on fait une copie de ce buffer à l'adresse qui est retourné avec une quantité de données qui est bien plus grande que 109 hexadecimal parce qu'on en voit 645 hexadecimal octaves donc ça se donne ici dans le crash quelques informations sur où le crash s'est produit et ça se nous permet de débugger un peu les bugs dans le firmware donc ça c'était une CVE une vraie CVE que l'on a signalé avec donc la description de la CVE c'était une corruption du heap pendant le device inquiry c'est exactement le même bug que ce que j'avais eu sur mon T430 et le problème ici c'est qu'on a un bug dans le firmware donc on peut voir sur un firmware de 2010 mais aussi sur un firmware de 2018 donc ça fait au moins 10 ans peut-être plus que ce bug est en production et ce qui est intéressant ce qui est plus intéressant c'est que ce bug est à deux endroits il est à la fois dans le BCS le Blues Cross Killer et dans le Link Manager et si vous regardez la source ce qui se passe ici c'est que d'abord on extrait la taille de la payload en enlevant les 3 bits les plus bas et en appliquant un masque sur la longueur et dans un autre thread on alloue statiquement 264 octaves de mémoire et ensuite on fait un même copie dans ce buffer avec la taille qui a été calculée au-dessus donc ce qu'on peut demander c'est pourquoi est-ce qu'il n'y a pas de check de la taille qu'est-ce qui se passe si on envoie un paquet plus long que les 240 à plus de 17 à plus de 8 octaves la réponse c'est rien puisque la taille maximum d'un paquet est limitée par la représentation physique mais le bug intéressant ici c'est que le masque de bits ici n'est pas correct c'est 13 bits et non pas 10 bits comme ça devrait l'être donc le paquet inclut aussi 3 bits qui normalement sont réservés pour une utilisation future et qui devrait être mis à zéro si vous mettez un seul de ces bits à 1 vous allez largement excéder la taille maximum et ça ça va générer un buffer overflow alors vous pouvez demander ok j'ai un même copie qui cause un overflow mais est-ce que je peux contrôler les données à quoi ça sert et en regardant de façon un peu plus précise le firmware j'ai utilisé un pattern que l'on peut reconnaître facilement dans la payload vous pouvez facilement reconnaître ici que en bleu vous avez le paquet que j'en vois et pour une raison quelconque il y a des morceaux du paquet qui sont dupliqués à la fin donc même si on envoie juste 240 octaves de mémoire on peut quand même avoir un overflow incontrôlé ici et ça c'est plutôt dangereux dans l'implémentation du scheduler parce que si on regarde à quoi ressemble la mémoire le heap dans le système de shredding on a ici une liste, une free liste qui contient tous les buffers qui sont free et si on a un overflow on peut simplement corrompre un de ses pointeurs et rediriger la liste chainée vers un emplacement arbitraire en mémoire avec ça c'est que vous pouvez utiliser n'importe quel adresse en mémoire comme un buffer valide donc si on peut allouer trois buffers de suite on peut réécrire n'importe quel donné en mémoire et aujourd'hui il n'y a aucune mitigation de cet exploit, c'est à dire que toute la mémoire est accessible en écriture et en exécution on peut réécrire n'importe quelle fonction dans la RAM donc on peut exécuter le code arbitraire et si vous pensez à l'ASLR les adresses aléatoires, vous rêvez c'est du code embarqué, faut pas y croire donc nous on a construit une proof of concept qu'on a transmis à Broadcom en avril de l'année dernière on a signalé à Broadcom après deux semaines on a demandé à Broadcom ce qu'ils faisaient ils ont dit qu'ils avaient trouvé ce bug en février 2018 qu'ils ont un correctif complet et qu'ils ont transmis l'information à tous leurs clients et que du coup tout va bien c'est pas mal comme pokerface ici parce que nous, la board qu'on avait datait du 18 janvier 2018 et ils ont dit qu'ils avaient trouvé ce bug deux semaines après la réaliste de la board qu'on utilisait donc on a regardé ça d'un peu plus près parce que j'étais à peu près sûr que j'avais essayé le Samsung Galaxy A3 avec le patch level qui datait de juin 2018 donc bien sûr après février 2018 et qu'on a aussi testé et trouvé ce bug sur le Samsung Galaxy S8 avec des patchs qui datait de mars 2019 qui à l'époque était très récent et on a essayé même d'autres périphériques et on n'en a pas trouvé un seul qui n'était pas vulnérable à ce bug donc on a demandé à Broadcom qu'est-ce qu'il se passe ? C'est le problème, c'est leur problème si ils veulent appliquer le correctif donc c'était bizarre parce qu'on n'a quand même pas trouvé un seul périphérique qui était patché jusqu'à ce que Gisca achète un S10e un Samsung Galaxy S10e et on peut voir ici que dans le code il y a de fait un check de la taille un check si la taille est plus grande que 240 si oui on tronque à 240 octets et donc ça c'est un build qui date de avril 2018 donc de fait ils ont probablement trouvé le bug en février 2018 mais on a quand même dû signaler ça à tous les fournisseurs de téléphone et d'autres périphériques on a contacté Google, on a contacté Apple les deux utilisent des puces Bluetooth que ce soit Android ou iOS donc Android a fourni des firmware avec le correctif en août 2019 et Apple a aussi fourni en septembre 2019 et nous a donné de la reconnaissance publique qui était sympa mais pour nous c'était plutôt stressant de devoir signaler ce bug parce qu'on a vraiment dû demander à tous ces fabricants est-ce que vous pouvez insister pour avoir un correctif pour ce bug d'exécution de code à distance qui est en prod depuis plus de 10 ans c'est pas comme ça que les choses devraient être et donc maintenant je vais parler un petit peu de ACL ou asynchronous connection less qui interme pour un type de collection Bluetooth donc ACL est une cible intéressante parce que c'est une des tâches les plus complexes dans le firmware ça inclut également l'implémentation du protocole de LinkManager dans lequel on s'attendait aussi à trouver des bugs et bien sûr Jiska a aussi trouvé des bugs où il manquait un check de taille de copies aussi dans LinkManager donc on a essayé différents types d'attaques on a essayé du phasing de la stack Bluetooth on a essayé de faire les paquets ACL directement alors ça a pas marché parce que les paquets sont passés directement à la stack au fret de BT Transport et donc ils ne sont pas interprétés par le LinkManager on a aussi essayé d'envoyer des paquets de inquiry qu'on avait aussi modifié avant qu'il soit copié dans les registres hardware et aucune de ces approches n'a fourni de bugs utiles alors pour nous c'était plutôt surprenant Jiska se retrouve un crash dans le Nexus 5 alors c'était pendant ma thèse mais déjà c'était pas dans le scope de ma thèse parce que ma thèse était sur l'analyse dynamique de firmware et donc le OS Android n'est pas vraiment le sujet j'avais pas le temps de débugger ça et puis on n'avait pas de symbole aussi ce qui rend le debugging beaucoup plus difficile on pouvait voir aussi que le crash avait lieu ici dans le thread 19 donc il y avait plusieurs threads qui s'exécutaient ce qui rendait les choses plus difficiles à analyser donc j'ai laissé passer ça et j'ai juste dit que c'était quelque chose qu'il faudrait tester plus tard mais donc plus tard on a de fait retesté avec ce même faiseur sur un Samsung Galaxy S10a et on peut voir ici qu'on a aussi observé ce même crash alors qu'on n'y pensait plus vraiment, on avait plus ou moins oublié ce crash-là mais ce qui est bien ici c'est qu'on a des symboles donc on peut voir que le crash a eu lieu dans le même copie, dans la libsée et on peut voir que le paramètre de Thaï, qui est passé à ma copie, a vraiment l'air d'être un nombre négatif et l'adresse ici a beaucoup de 0 ce qui indique probablement qu'on a ici un même copie avec un nombre négatif et typiquement ça va passer outre la fin d'une page ce qui va cracher les choses et donc on peut regarder dans cette fonction et on peut voir ici qu'il y a de fait une copie avec une différence entre la Thaï et si vous avez passé un offset l'offset maintenant que vous avez ça vous pouvez causer un même copie avec des nombres négatifs dedans alors ce qui est intéressant c'est qu'il y a au-dessus avant d'exécuter ça, une protection contre les buffer overflow mais en essayant du fozik nous on s'est rendu compte qu'il y avait plusieurs crashes dedans et c'est la première fois qu'on ne pouvait pas expliquer comme celui-ci ou l'adresse est vraiment bizarre parce que on l'a réécrit en ASCII et le crash ici a lieu dans du code complètement différent tous ces crashes sont reproducibles on peut les réexécuter donc je suppose qu'il y a d'autres bugs ici mais regardons d'abord le code lié à ce bug-là donc il faut regarder l'implementation de la fragmentation dans le protocole L2CAP vous avez un paquet avec le header qui inclut un paquet qui inclut un header et une payload et si la payload est trop longue on peut fragmenter ce paquet donc si vous envoyez ce paquet vous pouvez juste envoyer un header qui dit un paquet L2CAP qui est fragmenté et vous avez ici les 500 premières octets par exemple et ensuite vous pouvez avoir un autre paquet qui dit maintenant voilà le reste des octets à partir du cinquième octet et donc quand le paquet suivant arrive les données sont copiées à la suite de la payload et le code essaye de réassembler le paquet dans l'ordre alors le problème c'est que même copie fonctionne bizarrement sur android avant la version 10 on n'a pas encore fait de signalement du bug mais il était possible d'exploiter ce bug sur android 10 android avant la version 10 et ça ça nous permettait d'obtenir un shell avec le même utilisateur que le demo bluetooth sur android à distance donc on a écrit ce qu'on avait trouvé on a décidé d'envoyer ça à google on s'est dit qu'on a quand même regardé l'état des choses sur la branche master parce qu'on avait du code qui était un petit peu vieux parce que c'est ce qui tournait sur nos périphériques de test et en regardant ce qu'il y avait sur master il y avait déjà un commit qui corrigait ce bug et ça disait clairement que la mauvaise taille de paquet pouvait causer de la corruption en mémoire et ce commit datait d'avril 2019 donc c'était un bug qui était assez vieux et ce qui est intéressant c'est que le fixe était visible sur master pendant plusieurs mois avant d'être appliqué sur une release donc comme j'ai dit on a écrit un bug pour ce bug-là qui a été résolu en février 2019 donc le bug affectait environ 1,5 milliard de devices on a signalé le bug en novembre 2019 et le patch est arrivé le 3 février 2020 exactement 90 jours après alors ce qui est intéressant c'est Google a eu besoin de 90 jours pour appliquer un fixe qui était déjà dans master alors ce qui est intéressant c'est qu'il y a des périphériques qui reçoivent des mises à jour que tous les 90 jours et il y a d'autres périphériques qui ne reçoivent pas mises à jour du tout par exemple parce que le téléphone a plus de deux ans et on a aussi été contacté par certains vendeurs du monde automobile on sait pas vraiment quand on marche leur cycle de patching chez eux donc ça c'est un problème toujours quand on a une chaîne d'entreprise parce que la première entreprise a besoin de 90 jours pour corriger le bug et la deuxième entreprise a besoin de 90 jours également etc etc donc signaler des bugs comme ça ça peut prendre très longtemps et donc en conclusion les exploit c'est fatigant on aimerait bien voir des vendeurs des fabricants qui corrige les bugs sans demander un poke à chaque fois par exemple en le cas de Broadcom ils avaient déjà trouvé le bug mais ils n'avaient pas corriger le bug mais il n'y avait pas de patch et on a toujours le problème de la distribution des patchs il y a toujours des périphériques qui ne peuvent pas être patchés ou simplement qui mettent très longtemps à être patché parce qu'il faut du temps pour que le patch arrive entre les mains du consommateur final vous pouvez regarder les outils malheureusement la démo n'a pas marché mais le code source est disponible, vous pouvez l'essayer vous-même et c'est avec ces outils là qu'on a pu exploiter la vulnérabilité dans les plus brotes comme et c'est à peu près tout ce que j'avais et si vous avez des questions je serai ravi d'y répondre et si vous avez des questions vous pouvez les poser sur un pad qui est lié à partir du Farplan que vous pouvez trouver sur di.c3vok.c3voc.de slash farplanfahrplan est-ce qu'on est sur le stream ? alors première question quel sanitiser de heap a été utilisé pour détecter ces bugs alors c'était notre propre sanitiser de heap un qu'on a utilisé qui était basé sur celui de tredex on a fait du reversing engineering sur le heap et c'est assez facile pour le tredex et c'est assez facile pour nous décrire des tests assez simples qui permet de savoir si le heap est toujours intact et on a aussi hoocé les fonctions les plus intéressantes ce qui nous a permis d'insérer des tests pour savoir si le heap était toujours intact et d'afficher des messages d'erreur quand il y avait quelque chose qui ne marchait pas correctement et je devrais ajouter la SLR n'est pas possible sur un processeur Cortex-M3 la SLR est quelque chose qui est difficile à utiliser dans le monde de l'embarquer le DOP est peut-être utilisable Dead Exception Prevention mais pour ça il faudrait avoir des barrières qui rendent les mises à jour des fermoirs impossibles donc je ne pense pas que c'est quelque chose qui va être implémenté un jour il faut noter aussi que Broadcom a implémenté des vérifications de heap c'est probablement comme ça que eux ont trouvé le bug de leur côté mais c'est pas vraiment un système de mitigation d'exploit qui marche je n'ai pas entendu la question je crois qu'elle est posée sur Mumble en même temps le héros n'est pas... le héros l'aque beaucoup alors on utilise environ 100 peut-être 200 hooks qu'on a ajouté pour pouvoir faire du debug le nombre de fonctions qu'on a dû remplacer c'est pas tant que ça la plupart de ces fonctions c'est simplement des fonctions qui est écrite vers l'art c'est simplement des fonctions qui prennent un buffer et une taille et qui copie vers l'art et on peut simplement remplacer ça par un write vers la console pareil pour les lectures depuis Dubart il y a aussi des fonctions qui compadrent dans notre implantation river space comme par exemple des activés et des interruptions donc ça c'est des fonctions qu'on ajoute des activés il y a aussi toutes ces fonctions qui ont trait au matériel par exemple lecture ou écriture vers un registre matériel et pour moi tant que je peux écrire quelque part en mémoire ça me suffit donc si on a l'état de la mémoire et qu'on a des bonnes valeurs par défaut le code marche plus ou moins ok facilement alors pour l'exploit Broadcom on a un repository GitHub, un depot GitHub mais le concept pour Android n'a pas été publié pour le moment