Exploiting the USB Ninja BLE Connection

From Embedded Lab Vienna for IoT & Security
Jump to: navigation, search


This documentation is a summary how I exploited the USB Ninja BLE Connection, so that it is able to Control the Bad USB cable with a raspberry pi an a simple python script that is linked in the sources.

Used Hardware and Software

  1. The USB Ninja Pro-kit with Remote control
    1. Containing 3 Bad USB cables (only one is needed).
    2. Remote Control
  1. Hacking Hardware
    1. Raspberry Pi 3, Model B+, WLAN, BT
    2. Ubertooth One, 2.4 GHz wireless development platform
  1. Hacking Software
    1. Hcitool (Linux preinstalled)
    2. Gatttool (Linux preinstalled)
    3. Ubertooth Tools (Too install them read: Bluetooth Sniffing with Ubertooth: A Step-by-step guide)

USB Ninja Pro-kit

USB Ninja

The USB Ninja is a Rubberducky in a USB cable that comes in the flavours USB to USB micro, USB to USB-C and USB to Lightning. The bad USB cable can be programmed with two payloads. The payloads are developed under the usage of the Arduino IDE with the USBNinja libraries. During the attack phase its possible to start triggered payloads can be either by plugging the bad USB cable in or with the magnet or via the BLE 4.0 Remote. The trigger modes get defined by the way the c code is programmed.

The Remote itself has a leaver to turn it on and off and the button A and button B, which activate their corresponding payload. There is also a USB micro input to charge the Remote or to edit the shared secret.

The website states that the remote automatically connects to the bad USB cable if the defined passwords are the same. Where the Remote need a driver and a program to set the password, it can be directly done in the source code of the payload of the bad USB cable.

Sadly the developers require that the user uses Windows based Operating systems because its only possible to update the password of the Remote with a windows program that can be downloaded on the manufacturers website in the help tab. Furthermore, this software gets treated as malicious software form Windows because it doesn't have a manufacturer certificate. So the users have to click threw the warning from windows defender to change the password. I personally would much more like to see a simple shell script for Linux and a batch script for Windows to do the job.

Anyway, the standard password is and as long as the user uses only one Remote at the same time it doesn't really matter. Enough background knowledge let's get to the pen testing.

Reverse Engeneering The Remote

Step one: Standard BLE Actions

As I started to test the USBNinja in a normal fashion, I got curios, how much information I can gather by using the standard the programmes that come with Linux. I shut down the Remote, so the bad USB Cable BLE Module can be found by devices. Then I run the hcitool lescan command that is used by the usual Linux BLE discovery function.

 sudo hcitool lescan
 LE Scan ...
 E1:F1:22:F6:28:B5 (unknown)
 E1:F1:22:F6:28:B5 Ninja
 XX:XX:XX:XX:XX:XX (unknown)

The Raspberry instantly found the BLE signal of the bad USB cable and i might be lucky to gather informaten with the gatttool. As I connected via the gatttool tho the USB cable it closed the connection after two seconds due to invalid file descriptor in the glib. This error makes the Interactive mode useless.

 gatttool -I
 [                 ][LE]> connect E1:F1:22:F6:28:B5
 Attempting to connect to E1:F1:22:F6:28:B5
 Connection successful
 (gatttool:32016): GLib-WARNING **: 13:54:39.135: Invalid file descriptor.

But the not interactive mode did succeed fast enough to work before the Error occurs. So I used the characteristics command form gatttool to list all discoverable characteristics of the device.

 gatttool -b E1:F1:22:F6:28:B5 --characteristics
 handle = 0x0002, char properties = 0x0a, char value handle = 0x0003, uuid = 00002a00-0000-1000-8000-00805f9b34fb
 handle = 0x0004, char properties = 0x02, char value handle = 0x0005, uuid = 00002a01-0000-1000-8000-00805f9b34fb
 handle = 0x0006, char properties = 0x02, char value handle = 0x0007, uuid = 00002a04-0000-1000-8000-00805f9b34fb
 handle = 0x0008, char properties = 0x02, char value handle = 0x0009, uuid = 00002aa6-0000-1000-8000-00805f9b34fb
 handle = 0x000b, char properties = 0x20, char value handle = 0x000c, uuid = 00002a05-0000-1000-8000-00805f9b34fb
 handle = 0x000f, char properties = 0x02, char value handle = 0x0010, uuid = 00002a29-0000-1000-8000-00805f9b34fb
 handle = 0x0011, char properties = 0x02, char value handle = 0x0012, uuid = 00002a24-0000-1000-8000-00805f9b34fb
 handle = 0x0013, char properties = 0x02, char value handle = 0x0014, uuid = 00002a25-0000-1000-8000-00805f9b34fb
 handle = 0x0015, char properties = 0x02, char value handle = 0x0016, uuid = 00002a27-0000-1000-8000-00805f9b34fb
 handle = 0x0017, char properties = 0x02, char value handle = 0x0018, uuid = 00002a26-0000-1000-8000-00805f9b34fb
 handle = 0x0019, char properties = 0x02, char value handle = 0x001a, uuid = 00002a28-0000-1000-8000-00805f9b34fb
 handle = 0x001b, char properties = 0x02, char value handle = 0x001c, uuid = 00002a23-0000-1000-8000-00805f9b34fb
 handle = 0x001d, char properties = 0x02, char value handle = 0x001e, uuid = 00002a50-0000-1000-8000-00805f9b34fb
 handle = 0x0020, char properties = 0x10, char value handle = 0x0021, uuid = 0000fff1-0000-1000-8000-00805f9b34fb
 handle = 0x0024, char properties = 0x0e, char value handle = 0x0025, uuid = 0000fff2-0000-1000-8000-00805f9b34fb
 handle = 0x0027, char properties = 0x1c, char value handle = 0x0028, uuid = 0000fff3-0000-1000-8000-00805f9b34fb
 handle = 0x002c, char properties = 0x28, char value handle = 0x002d, uuid = 8ec90003-f315-4f60-9fb8-838830daea50

So the characteristics are not encrypted and can be read without the key. Furthermore the first 13 of are well-known GATT Services defined by the Bluetooth Special Interest group. These handles and their values are listed in the table below:

Handle Privileges Characteristic Value
0x0003 Read and Write Device Name USBNinja+
0x0005 Read Appearance Appearance Unknown
0x0007 Read Pheripheral preffered connection Parameters 08 00 08 00 00 00 f4 01
0x0009 Read Central Address Resolution 01
0x0010 Read Manufacturer Name String Proxgrind
0x0012 Read Model Number String Ninja
0x0014 Read Serial Number String 20190912
0x0016 Read Hardware Revision String V2.0
0x0018 Read Firmware Revision String V1.0
0x001a Read Software Revision String v5.0
0x001c Read System ID 64 00 00 00 00 9e 00 00
0x001e Read PnP ID 01 d2 00 10 08 01 00

The wellknown Services were easy to read and to decipher but the four custom services couldn't be reverse engineered by using only the gatttool. The rest of this paragraph is a listing of the commands used to create the table above and how to decode the values. So feel free to jump to the Ubertooth BLE connection sniffing part by klicking this link: Step Two: Ubertooth BLE Connection Sniffing.

[1] [Device Name] [RW] handle: 0x0002, char properties: 0x0a, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb

 char-read-hnd 3 
 Characteristic value/descriptor: 55 53 42 4e 69 6e 6a 61 2b
 55 53 42 4e 69 6e 6a 61 2b hex = USBNinja+ ASCII
 char-write-req 3 4861636b6564
 Characteristic value was written successfully
 char-read-hnd 3
 Characteristic value/descriptor: 48 61 63 6b 65 64

[2] [Appearance] [R] handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb

 char-read-hnd 5 
 Characteristic value/descriptor: 00 00
 0 -> Appearance Unknown

[3] [Pheripheral preffered connection Parameters] [R] handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb

 char-read-hnd 7 
 Characteristic value/descriptor: 08 00 08 00 00 00 f4 01 

[4] [Central Address Resolution] [R] handle: 0x0008, char properties: 0x02, char value handle: 0x0009, uuid: 00002aa6-0000-1000-8000-00805f9b34fb

 char-read-hnd 9 
 Characteristic value/descriptor: 01

[5] [Service Change] [Indication] handle: 0x000b, char properties: 0x20, char value handle: 0x000c, uuid: 00002a05-0000-1000-8000-00805f9b34fb

 Indication services are for notifications and can not be read that easily.

[6] [Manufacturer Name String] [R] handle: 0x000f, char properties: 0x02, char value handle: 0x0010, uuid: 00002a29-0000-1000-8000-00805f9b34fb

 char-read-hnd 10
 Characteristic value/descriptor: 50 72 6f 78 67 72 69 6e 64
 50 72 6f 78 67 72 69 6e 64 hex = Proxgrind ASCII

[7] [Model Number String] [R] handle: 0x0011, char properties: 0x02, char value handle: 0x0012, uuid: 00002a24-0000-1000-8000-00805f9b34fb

 char-read-hnd 12
 Characteristic value/descriptor: 4e 69 6e 6a 61
 4e 69 6e 6a 61 hex = Ninja ASCII

[8] [Serial Number String] [R] handle: 0x0013, char properties: 0x02, char value handle: 0x0014, uuid: 00002a25-0000-1000-8000-00805f9b34fb

 char-read-hnd 14
 Characteristic value/descriptor: 32 30 31 39 30 39 31 32
 32 30 31 39 30 39 31 32 hex = 20190912 ASCII

[9] [Hardware Revision String] [R] handle: 0x0015, char properties: 0x02, char value handle: 0x0016, uuid: 00002a27-0000-1000-8000-00805f9b34fb

 char-read-hnd 16
 Characteristic value/descriptor: 56 32 2e 30 
 56 32 2e 30 hex = V2.0 ASCII

[10] [Firmware Revision String] [R] handle: 0x0017, char properties: 0x02, char value handle: 0x0018, uuid: 00002a26-0000-1000-8000-00805f9b34fb

 char-read-hnd 18
 Characteristic value/descriptor: 56 31 2e 30
 56 31 2e 30 hex = V1.0 ASCII

[11] [Software Revision String] [R] handle: 0x0019, char properties: 0x02, char value handle: 0x001a, uuid: 00002a28-0000-1000-8000-00805f9b34fb

 char-read-hnd 1a
 Characteristic value/descriptor: 76 35 2e 30
 76 35 2e 30 hex = v5.0 ASCII

[12] [System ID] [R] handle: 0x001b, char properties: 0x02, char value handle: 0x001c, uuid: 00002a23-0000-1000-8000-00805f9b34fb

 char-read-hnd 1c
 Characteristic value/descriptor: 64 00 00 00 00 9e 00 00

[13] [PnP ID] [R] handle: 0x001d, char properties: 0x02, char value handle: 0x001e, uuid: 00002a50-0000-1000-8000-00805f9b34fb

 char-read-hnd 1e
 Characteristic value/descriptor: 01 d2 00 10 08 01 00

Step Two: Ubertooth BLE Connection Sniffing

After installing the Ubertooth functions and get the device running, I started to sniff the transferred data and piped it directly into wireshark

 Terminal A:
 mkfifo /tmp/pipe  
 sudo wireshark -i /tmp/pipe
 Terminal B: 
 ubertooth-btle -f E1:F1:22:F6:28:B5 -c /tmp/pipe


The Wireshark output shows that the transmitter only interacts with the handle 0x22 and 0x25. I the following figure shows the connection in a simplified way.


During the Connection establishment the exchange MTX gets discussed followed by a write request to the handle 0x22 with the value 0x0100. Then the USB Cable responds with an acknowledgement. I think that this operation causes the Error in interactive mode of the gatttool but I did use it in script of Step Three.

When a button is Pressed it first send a write request to the handle 0x25 with the value 0x38383838. This value is the Password in plaintext but coded as hex (0x38383838 = 8888). Because of that it is possible to overtake the connection if the password got sniffed. After the acknowldgment its send either the value 0x413d4c0d0a (Button A) or 0x423d4c0d0a (Button A) to tirgger the corresponding Payload. Attentive observer will instandly recognize that the first hexpair 0x41 and 0x42 of the sent values are A and B in ASCII and indicate the used buttons.

Step Three: Writing a Contolling Python Script

After the BLE connection sniffing process, I started to write a Python script that mimics and the USB Ninja Remote and it instantly worked to print well-known characteristics of the device and to trigger the payload A. After a bit of bug fixing I figured out how to payload B and converted the simple script to an advanced application which will be publicly available on gitlab under this link soon.

 	./USBNinja.py -m <mode> [options]
 	r							 			Remote: 		Mimics the USB ninja Remote				
 	c										Converter:		Converts ducky.txt payloads into USBNinja.c 
 	u										TBA:			TBA
 	./USBNinja.py -m r -d <BDADDR>
 	Info										Prints device info
 	Button A									Triggers payload A
 	Button B									Triggers payload B
 	Quit										Leaves interactive mode
 	./USBNinja.py -m c -i <input file> -j <input file 2> -o <output file> -l <keyboard language> -t <triggermode>

Example usage of the Remote mode:

 ./USBNinja.py -m r -d E1:F1:22:F6:28:B5
 Device name:                    Ninja
 Model number string:            Ninja
 Serial number string:           20190912
 Hardware revision string:       V2.0
 Firmware revision string:       V1.0
 Software revision string:       v5.0
 System id:                      00 00 00 00 9e 00 00
 PnP id:                         01 d2 00 10 08 01 00
 [E1:F1:22:F6:28:B5][LE]>Button A
 Pressed Button A
 [E1:F1:22:F6:28:B5][LE]>Button B
 Pressed Button B [E1:F1:22:F6:28:B5][LE]>Quit