Appareils à interface humaine : le braquage du descripteur

Aujourd’hui, nous allons construire nos propres périphériques d’entrée. Et ils seront faciles à créer et à écrire un firmware, ils fonctionneront parfaitement et ils seront multiplateformes. Nous pouvons le faire à l’aide de la norme Human Interface Device (HID), et en guise d’introduction, afin que vous ne soyez jamais confus par ce que signifie un « descripteur », et nous construirons notre propre périphérique HID – un périphérique d’interface humaine. appareil. La façon dont nous les construisons ne nécessitera pas de lecture de spécifications. Au lieu de cela, je vais vous apprendre à voler les descripteurs HID des appareils existants, à les modifier pour nos besoins et à les utiliser dans nos appareils pour exploiter la puissance du HID.

Depuis des décennies, il est possible de créer une souris ou un clavier HID en utilisant une ou deux bibliothèques, et cela constitue une aubaine pour les pirates informatiques du monde entier. Cependant, ces bibliothèques sont généralement confinées à un certain modèle et peu flexibles, et nous, les pirates, allons souvent au-delà de ce qui est attendu. HID permet bien plus qu’un simple clavier ou une souris. C’est pourquoi nous construisons aujourd’hui un écran tactile – quelque chose qui n’est pas encore abordé en ligne ou dans les bibliothèques.

HID vous permet de créer des appareils conviviaux. Ils n’ont pas besoin de pilotes, ils sont plug and play et ils font ce que vous attendez d’eux. À la base, la norme HID est aussi simple qu’omniprésente. Vous pouvez tunneler HID via USB, Bluetooth, I2C et les systèmes d’exploitation modernes prennent en charge ces trois éléments. Aujourd’hui, passons en revue les bases de HID, puis construisons un écran tactile USB à partir d’un écran tactile résistif connecté par SPI, à l’aide du combo habituel RP2040 + MicroPython. Je vais également vous donner une boîte à outils sur la façon de déboguer un périphérique d’interface humaine de manière aussi approfondie que possible, en particulier sous Linux, montrant toutes les capacités de débogage et d’introspection HID que Linux vous offre. Mais cela fonctionnera également sous Windows grâce à la beauté de la standardisation.

Vérifier la carte

Il existe déjà de nombreux guides sur ce sujet, mais bien sûr, je vais entrer plus en détail, être plus succinct et vous donner des outils que les autres guides n’ont pas. Cela dit, vous pouvez toujours bénéficier de plusieurs guides différents pour vous référencer tout au long de votre voyage, voici donc un guide Adafruit, et en voici quelques autres. En particulier, ils approfondissent la structure des descripteurs HID et l’expliquent avec tous les détails que vous pourriez utiliser pour déterminer les descripteurs. Au lieu de cela, je vais vous donner un aperçu général de HID et vous démontrer que vous n’avez pas besoin de bien comprendre les descripteurs HID pour créer des appareils HID – vous pouvez tout de même les pirater.

Un descripteur de rapport est un guide lisible par machine expliquant comment analyser un paquet HID (« rapport ») provenant de votre appareil. Le descripteur indique à votre système d’exploitation quels bits et octets à l’intérieur d’un paquet HID correspondent à quels types de données. Lorsqu’un périphérique HID est connecté à votre système d’exploitation, le système d’exploitation obtient le descripteur, le lit, apprend ce qu’il peut attendre de votre appareil et chaque fois qu’un paquet de données entrant arrive, le système d’exploitation analyse le paquet de votre appareil en fonction des informations contenues dans le descripteur.

Comme vous pouvez le constater, les descripteurs sont assez verbeux, ce qui permet aux appareils d’envoyer des paquets courts et simples. Cette partie du descripteur a été tirée d’ici, vous pouvez y voir le descripteur complet si vous êtes intéressé.

Bien entendu, votre appareil peut envoyer différents types de paquets, pour différents types de données. Par exemple, un récepteur sans fil souris et clavier enverrait au moins deux types différents de paquets HID, et un écran tactile enverrait différents paquets selon que vous utilisez un doigt ou un stylet spécial. C’est pourquoi un descripteur de rapport peut avoir différentes sections pour différents types de paquets, et les paquets sont ensuite distingués par l’ID du rapport. Cet identifiant doit être le premier octet du rapport – si vous n’obtenez pas l’identifiant en premier lieu, vous ne savez pas quelle section du descripteur utiliser pour analyser l’intégralité du paquet qui vient d’arriver.

Il est facile de construire une souris HID. Il est facile de créer un clavier HID. Il existe des bibliothèques pour ces deux éléments, et si vous souhaitez créer un clavier, le didacticiel Adafruit vous montrera comment procéder. Aujourd’hui, je dois construire un appareil différent pour mon arsenal : un petit écran tactile portable, quelque chose qui n’est pas exactement disponible dans le commerce. Naturellement, je souhaite également qu’il soit plug and play, et à l’avenir, je souhaite qu’il soit également accessible via I2C pour tous mes besoins intégrés.

En guise de polygone de test, voici un écran HDMI tactile avec un circuit intégré de contrôleur d’écran tactile résistif XPT2046 connecté par SPI, un clone de l’ADS7846, avec des broches SPI exposées sur un en-tête compatible Raspberry Pi. La partie HDMI est correcte, à l’exception du fait qu’elle prétend être un écran 1080p alors que sa résolution réelle est de 480 × 320. La partie écran tactile, cependant, est une technologie assez obtuse – elle ne fonctionne que si vous disposez d’une interface SPI, vous devez charger le pilote avant que quoi que ce soit ne fonctionne, et si vous le débranchez, vous devrez peut-être redémarrer votre Pi pour l’écran tactile. travailler à nouveau. De plus, c’est compliqué à calibrer. La prise en charge HID le rendrait universel, plug&play, et le fait d’avoir notre propre micrologiciel nous permettrait même de placer les paramètres d’étalonnage dans un stockage non volatile, ce que font tous les écrans tactiles qui se respectent.

Tout ce que notre micrologiciel a à faire est de stocker un descripteur, puis d’envoyer des paquets HID correspondant au descripteur au système d’exploitation chaque fois que nous souhaitons envoyer des coordonnées tactiles. Tant que le système d’exploitation est d’accord avec notre descripteur et que les valeurs de nos paquets ont du sens, le système d’exploitation va créer des événements d’écran tactile à partir de nos paquets. C’est vraiment aussi simple que ça.

Un coffre-fort rempli de descripteurs

Une façon de créer un descripteur d’écran tactile consiste à lire la spécification HID, à déterminer tout ce que vous devez dire dans votre descripteur pour être un écran tactile valide, à assembler soigneusement ces éléments, puis à le déboguer jusqu’à ce qu’il fonctionne. Si cela ne vous semble pas vraiment amusant, ne vous inquiétez pas, cela ne me semble pas non plus amusant.

Voici plutôt un plan adapté aux pirates. Nous volons un descripteur HID sur un écran tactile, voyons comment les événements de l’écran tactile sont analysés par un système d’exploitation, puis créons notre propre descripteur d’écran tactile à partir de celui d’une souris, envoyons des paquets qui correspondent à ce descripteur et voyons comment notre système d’exploitation réagit. J’ai un écran tactile capacitif que j’ai récupéré sur un ordinateur portable – il se connecte via USB, il fonctionne sous Linux sans problème, et c’est largement suffisant pour en extraire un descripteur.

En attendant, j’ai modifié cet écran pour qu’il soit alimenté via HDMI au lieu d’utiliser une entrée d’alimentation microUSB séparée.

Nous n’utiliserons pas non plus de bibliothèques super abstraites aujourd’hui – construisons des paquets bruts et voyons comment ils fonctionnent. MicroPython n’a toujours pas de support HID, alors voici une version de MicroPython, où [elpekenin] a ajouté la prise en charge des appareils HID avec seulement quelques engagements supplémentaires (plus, sans aucun doute, des heures de sang, de sueur et de larmes). Il n’y a pas d’API « envoyer ‘A’ en appuyant sur une touche » à proprement parler, vous devez créer vos paquets même pour une utilisation au clavier – mais c’est très simple, et c’est parfait pour notre objectif ! Cette construction a été réalisée par [Pablo Martínez (elpekenin)], et je leur suis éternellement reconnaissant de l’avoir partagé – allez les suivre sur GitHub, ils font des trucs sympas ! Pour le pilote XPT2046, j’ai utilisé une bibliothèque MicroPython XPT2046 du toujours prolifique [robert-hh]qui est également le hacker vers qui se tourner si vous voulez votre dose de bibliothèques et d’outils MicroPython de haute qualité !

Je suggère de cloner ce référentiel comme git clone --branch peke-devel --recursive URL, puisque la branche principale du référentiel a été rebasée sur CircuitPython et que le clone récursif requis pour la branche principale, extraira également une tonne absolue d’Adafruit et d’autres codes ajoutés à CircuitPython. Cloner uniquement la branche spécifique dont nous avons besoin, qui repose toujours uniquement sur les bibliothèques MicroPython, vous fera économiser une tonne de bande passante, de temps et d’espace disque. Une fois que vous avez fait cela, cependant, compiler ce firmware et le charger sur un RP2040 convivial vous donnera quelques nouveaux appareils HID et une bibliothèque à importer :

import time
import usb_hid

report = bytearray(8)

report[2] = 0x04 # register 'a' keycode
usb_hid.report(usb_hid.KEYBOARD, report) # send event

time.sleep(2)

report[2] = 0x00 # unregister 'a' keycode
usb_hid.report(usb_hid.KEYBOARD, report) # send event

Comme vous pouvez le constater, un rapport fait 8 octets (64 bits) et différents bits du rapport répondent aux différents caractères que vous pouvez envoyer. Si vous vous demandez comment ça se fait 0x04 Correspond à a, il s’agit d’un mappage bit à caractère par défaut qui peut être trouvé ici et ici et plus d’informations ici, voici plus de conseils sur la façon dont vous pouvez modifier ce mappage. La plupart des descripteurs HID de ce firmware proviennent de la bibliothèque TUSB, éprouvée et vraie, et il y a aussi le MOUSE_ABS descripteur ajouté dans le code lui-même, que vous pouvez modifier si vous recompilez simplement le firmware !

Avec le descripteur MOUSE_ABS utilement inclus et facilement modifiable en particulier, vous disposez de tout ce dont vous pourriez avoir besoin pour créer rapidement votre propre descripteur, qu’il s’agisse d’un clavier personnalisé, d’un écran tactile ou d’une plage braille. Dans CircuitPython, vous n’avez même pas besoin de recompiler le firmware pour changer un descripteur, mais il serait plus difficile d’utiliser CircuitPython pour bricoler ici, pour des raisons que nous pourrions simplement identifier et atténuer dans un prochain article ! En attendant, il s’agit d’une bibliothèque MicroPython qui vous permet de jouer directement avec HID, au niveau le plus bas confortable. Dans le prochain article, je souhaite vous proposer une boîte à outils compatible Linux pour jouer à la fois avec les descripteurs de périphériques et les paquets HID, vous montrant comment déboguer rapidement et facilement tous les côtés de l’équation, puis je vous montrerai comment modifier le descripteur pour créer votre propre écran tactile USB !

François Zipponi
Je suis François Zipponi, éditorialiste pour le site 10-raisons.fr. J'ai commencé ma carrière de journaliste en 2004, et j'ai travaillé pour plusieurs médias français, dont le Monde et Libération. En 2016, j'ai rejoint 10-raisons.fr, un site innovant proposant des articles sous la forme « 10 raisons de... ». En tant qu'éditorialiste, je me suis engagé à fournir un contenu original et pertinent, abordant des sujets variés tels que la politique, l'économie, les sciences, l'histoire, etc. Je m'efforce de toujours traiter les sujets de façon objective et impartiale. Mes articles sont régulièrement partagés sur les réseaux sociaux et j'interviens dans des conférences et des tables rondes autour des thèmes abordés sur 10-raisons.fr.