Retour aux articles • MATÉRIEL • • 9 min de lecture

Clés USB HID : BadUSB, RP2040 & ATtiny85

Comprendre les clés USB d'injection et d'automatisation de frappes clavier (USB HID) : fonctionnement du protocole, comparatif des solutions prêtes à l'emploi (Rubber Ducky, Flipper Zero) et guide complet pour fabriquer sa propre clé DuckyScript à 4 € avec un RP2040-Zero ou un ATtiny85.

Clés USB HID : BadUSB, RP2040 & ATtiny85

Vous branchez ce qui ressemble à une banale clé USB sur un poste de travail. Moins d’une seconde plus tard, sans qu’aucune fenêtre d’explorateur de fichiers ne s’ouvre, le menu Exécuter (Win + R) surgit, un terminal PowerShell ou Bash se lance, et une séquence de commandes s’exécute à la vitesse de 1 000 caractères par minute : exactement comme si un opérateur invisible tapait frénétiquement sur le clavier.

Ce concept porte un nom technique précis : l’injection de frappes par émulation USB HID (Human Interface Device), popularisée sous les termes de Keystroke Injection ou BadUSB. Utilisée aussi bien par les administrateurs système (pour automatiser la configuration BIOS/OOBE de dizaines de machines hors réseau) que par les auditeurs Red Team, cette technologie existe aujourd’hui sous deux formes : des outils commerciaux prêts à l’emploi et des microcontrôleurs DIY à moins de 5 € que l’on peut assembler et programmer soi-même en dix minutes.


1. Pourquoi l’ordinateur obéit-il aveuglément ? Le protocole USB HID

Lorsqu’un périphérique est inséré dans un port USB, le contrôleur hôte interroge son descripteur de périphérique (Device Descriptor) avant même de charger un pilote. Une clé USB de stockage classique s’annonce avec la classe 0x08 (Mass Storage) : une classe souvent bloquée par les politiques de sécurité d’entreprise (GPO Windows, EDR, DLP).

À l’inverse, une clé d’automatisation de frappes contient un microcontrôleur qui s’annonce auprès du système d’exploitation avec la classe 0x03 (bInterfaceClass = HID) et le protocole 0x01 (Boot Interface Keyboard) :

Architecture & Flux : Clés USB HID : BadUSB, RP2040 & ATtiny85

Pour Windows, Linux, macOS ou Android, il ne s’agit pas d’une clé USB, mais d’un clavier filaire standard. Le système d’exploitation lui accorde une confiance implicite immédiate et transmet chaque paquet de 8 octets (HID Report contenant les modificateurs CTRL/ALT/GUI et jusqu’à 6 scancodes simultanés) directement à la fenêtre active.


2. Les solutions prêtes à l’emploi (Clé en main)

Si votre objectif est d’obtenir un outil immédiatement opérationnel en mission d’audit ou d’administration, sans écrire de code C/Python ni manipuler de fer à souder, plusieurs références dominent le marché :

Outil Clé en MainFormat PhysiqueLangage de ScriptDéclenchement & Atouts MajeursPrix indicatif
Hak5 USB Rubber Ducky (Gen 3)Clé USB-A + USB-C (boîtier furtif standard)DuckyScript 3.0 (compilé en inject.bin sur microSD)Variables, boucles, détection de l’OS cible via empreinte USB, bouton d’armement interne~80 €
Flipper Zero (Mode BadUSB)Boîtier multifonction avec écran LCD + boutonsDuckyScript (fichiers .txt lisibles directement sur la carte SD)Sélection visuelle du script à l’écran avant exécution, support USB-C et Bluetooth BLE HID~170 €
O.MG Cable / O.MG PlugCâble de charge ou adaptateur USB d’apparence anodineDuckyScript via interface Web Wi-Fi embarquéeDéclenchement à distance depuis un navigateur smartphone, géofencing Wi-Fi, auto-effacement~130 - 180 €
M5Stack Cardputer / AtomS3UMini-clavier ESP32-S3 ou clé USB compacteFirmware communautaire (Bruce / BadUSB SD)Très abordable, Wi-Fi/BLE intégrés, exécution de payloads depuis carte microSD~15 - 35 €

Le standard universel : DuckyScript

Toutes ces solutions ont convergé vers un langage déclaratif ultra-lisible créé par Hak5 : le DuckyScript. Un script se résume à une suite d’instructions séquentielles (DELAY, GUI, ALT, CTRL, STRING, ENTER).

Voici un exemple de script légitime d’inventaire matériel et réseau express qu’un technicien support peut exécuter sur un poste Windows pour exporter la configuration sur le Bureau :

REM ============================================================
REM Automatisation Diagnostic Réseau & Système (Windows FR)
REM ============================================================
DELAY 1000
GUI r
DELAY 400
STRING powershell -NoProfile -ExecutionPolicy Bypass
ENTER
DELAY 800
STRING Get-NetIPConfiguration | Out-File "$env:USERPROFILE\Desktop\diag_reseau.txt"
ENTER
STRING systeminfo >> "$env:USERPROFILE\Desktop\diag_reseau.txt"
ENTER
STRING exit
ENTER

3. Fabriquer sa propre clé d’automatisation (DIY) pour moins de 5 €

Fabriquer soi-même sa clé d’automatisation présente trois avantages décisifs : un coût dérisoire (2 € à 5 €), une compréhension intime du protocole USB HID, et la possibilité de personnaliser entièrement le comportement matériel (ajout d’un interrupteur physique, d’une LED d’état RGB ou d’un sélecteur de profil).

Deux familles de microcontrôleurs se distinguent aujourd’hui pour cet usage :

Architecture & Flux : Clés USB HID : BadUSB, RP2040 & ATtiny85

Option A (La plus performante) : Waveshare RP2040-Zero ou Raspberry Pi Pico (pico-ducky)

Le microcontrôleur RP2040 (conçu par la fondation Raspberry Pi) est de loin la meilleure plateforme DIY actuelle. Dans sa variante miniature Waveshare RP2040-Zero (~4 €) ou RP2040-One (qui possède une prise USB-A mâle directement soudée sur le circuit imprimé), il offre un processeur Dual-Core ARM Cortex-M0+ à 133 MHz et 2 Mo de mémoire Flash.

Grâce à CircuitPython et au projet open-source pico-ducky, votre carte à 4 € se comporte exactement comme une véritable USB Rubber Ducky : vous modifiez simplement un fichier texte payload.dd à la racine de la clé !

Étape 1 : Flasher CircuitPython sur le RP2040

  1. Maintenez le bouton miniature BOOTSEL enfoncé tout en branchant le RP2040 sur votre ordinateur.
  2. Un lecteur USB nommé RPI-RP2 apparaît instantanément.
  3. Téléchargez le fichier .uf2 officiel de CircuitPython (pour Waveshare RP2040-Zero ou Raspberry Pi Pico) et glissez-le dans RPI-RP2.
  4. La carte redémarre automatiquement et monte un nouveau volume nommé CIRCUITPY.

Étape 2 : Installer les bibliothèques HID et la disposition AZERTY FR

Sur le volume CIRCUITPY, copiez dans le dossier lib/ :

  • Le module adafruit_hid (fourni dans le bundle officiel Adafruit CircuitPython).
  • Le module adafruit_hid_fr (keyboard_layout_win_fr.py et keycode_win_fr.py) qui traduit automatiquement chaque caractère accentué ou symbole français (\, |, $, m, a) vers le bon scancode AZERTY.

Étape 3 : Le script Python autonome (code.py) avec cavalier de sécurité

Un point crucial en DIY est d’éviter que la clé ne commence à taper ses commandes sur votre propre machine au moment où vous la branchez pour modifier son script ! Sur le RP2040, il suffit de vérifier l’état d’une broche GPIO (par exemple GP0 reliée à GND par un petit cavalier) pour activer un mode Édition sécurisé.

Voici un exemple complet et minimaliste de fichier code.py fonctionnant directement sous CircuitPython :

import time
import board
import digitalio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from keyboard_layout_win_fr import KeyboardLayout

# Broche GP0 en Pull-Up : si reliée à GND, on n'exécute pas la séquence (Mode Édition)
safe_pin = digitalio.DigitalInOut(board.GP0)
safe_pin.direction = digitalio.Direction.INPUT
safe_pin.pull = digitalio.Pull.UP

if not safe_pin.value:
    print("Mode Édition actif : exécution HID désactivée.")
else:
    # Attente de l'énumération USB par l'OS hôte
    time.sleep(1.2)
    kbd = Keyboard(usb_hid.devices)
    layout = KeyboardLayout(kbd)

    # 1. Ouvrir la boîte de dialogue Exécuter (Win + R)
    kbd.send(Keycode.WINDOWS, Keycode.R)
    time.sleep(0.45)

    # 2. Lancer un terminal et afficher les interfaces réseau
    layout.write("cmd /k ipconfig /all")
    kbd.send(Keycode.ENTER)

Astuce boot.py (Furtivité du stockage) : Par défaut, CircuitPython expose à la fois un clavier HID et le lecteur de stockage CIRCUITPY. En ajoutant storage.disable_usb_drive() dans le fichier boot.py (conditionné à l’état de la broche GP0), le volume de stockage disparaît complètement : l’ordinateur hôte ne voit plus qu’un clavier pur, exactement comme sur un Rubber Ducky matériel.


Option B (L’ultra-minimaliste à 2 €) : Le Digispark ATtiny85

Avant l’arrivée du RP2040, la star des ateliers hardware était le Digispark ATtiny85. C’est une minuscule carte de la taille d’un ongle (~1,50 € à 2 €) dont le circuit imprimé forme directement le connecteur USB-A mâle.

Contrairement au RP2040, l’ATtiny85 ne dispose que de 8 Ko de mémoire Flash (dont ~2 Ko occupés par le bootloader Micronucleus) et ne possède même pas de contrôleur USB matériel dédié : il émule le bus USB 1.1 Low-Speed par voie logicielle (bit-banging via la bibliothèque V-USB / DigiKeyboard.h).

#include "DigiKeyboard.h"

void setup() {
  pinMode(1, OUTPUT); // LED embarquée sur la broche P1
  DigiKeyboard.sendKeyStroke(0);
  DigiKeyboard.delay(1000);

  // Ouverture de Win + R
  DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
  DigiKeyboard.delay(500);

  // Attention : DigiKeyboard envoie des scancodes QWERTY US par défaut !
  DigiKeyboard.println("powershell");
  digitalWrite(1, HIGH); // Allume la LED une fois la frappe terminée
}

void loop() {
  // Ne rien répéter en boucle
}

Les limites de l’ATtiny85 face au RP2040 :

  1. Délai d’amorçage de 5 secondes : Au branchement, le bootloader Micronucleus attend 5 secondes une éventuelle reprogrammation Arduino avant de lancer le payload.
  2. Piège du clavier QWERTY : DigiKeyboard.h traduit les chaînes ASCII selon la disposition QWERTY US. Sur un poste français en AZERTY, taper cmd écrira c,d et taper powershell écrira pozershell si vous n’utilisez pas une table de conversion scancode francisée (DigiKeyboardFr.h).
  3. Recompilation obligatoire : Chaque modification du script nécessite de recompiler et reflasher la puce via l’IDE Arduino, là où le RP2040 accepte une simple édition de fichier texte.

4. Comparatif Synthétique : Clé en Main vs DIY

CritèreHak5 USB Rubber DuckyFlipper Zero (BadUSB)DIY RP2040-Zero (pico-ducky)DIY Digispark ATtiny85
Coût matériel~80 €~170 €~4 €~2 €
Temps de préparationImmédiatImmédiat~10 minutes (flash .uf2)~20 minutes (IDE Arduino)
Édition des scriptsCarte microSD (inject.bin)Carte microSD (.txt direct)Lecteur Flash USB (payload.dd)Recompilation C++ obligatoire
Support Clavier AZERTY FRNatifNatifNatif (adafruit_hid_fr)Complexe (conversion scancodes)
Vitesse de frappe> 1 000 caract./min~800 caract./min> 1 000 caract./min~400 caract./min (USB 1.1 logiciel)
Idéal pourAudit professionnel & discrétionCouteau suisse multi-protocolesApprentissage, labo & automatisation ITDéfis micro-électroniques minimalistes

5. Comment se protéger contre les périphériques USB HID non autorisés ?

Puisqu’un périphérique HID contourne les politiques qui ne bloquent que les supports de stockage (Mass Storage), la défense d’un parc informatique repose sur trois verrous complémentaires :

  1. Filtrage matériel par liste blanche sous Linux (USBGuard) : Le démon usbguard intercepte l’énumération USB au niveau du noyau Linux et bloque par défaut tout nouveau clavier (03:01:01) qui ne figure pas dans /etc/usbguard/rules.conf ou lorsqu’un clavier principal est déjà actif et que l’écran est verrouillé :
    # Générer la politique initiale autorisant uniquement les périphériques présents
    sudo usbguard generate-policy > /etc/usbguard/rules.conf
    sudo systemctl enable --now usbguard
    
Animation exécution CLI dans le terminal
  1. Restriction d’installation de périphériques par GPO sous Windows : Via Stratégie de groupe > Modèles d'administration > Système > Installation de périphériques, restreindre l’installation aux classes et couples VID/PID approuvés par l’entreprise, et surveiller dans l’observateur d’événements (Sysmon / Event ID 6416) l’apparition soudaine d’un second clavier HID suivi immédiatement d’une exécution powershell.exe ou cmd.exe (détection comportementale EDR sur la vélocité de frappe inhumaine < 5 ms entre chaque touche).
  2. Hygiène physique et verrouillage systématique (Win + L) : Une clé d’injection de frappes ne possède pas plus de privilèges que la session dans laquelle elle est branchée. Sur un poste dont la session est verrouillée (Win + L / écran de connexion), les raccourcis Win + R ou l’ouverture d’un terminal sont inopérants.

Sources et Références Officielles


Si vous voulez plus d’information sur l’infrastructure vous pouvez voir mon repo à ce sujet : https://github.com/ravindrajob/InfraAtHome