Defending Against Malicious USB Firmware with GoodUSB

Finally, 4 months after our paper was accepted by ACSAC’15, I could now write a blog talking about our work – GoodUSB, and release the code, due to some software patent bul*sh*t. (I sincerely think software patent should be abolished from the very start!) Anyway, this post is all about malicious USB firmware, BadUSB attacks, and our defense solution from the Linux kernel – GoodUSB. Go ahead to download GoodUSB and play with it. Any question, shoot me an email.

0. To memorize the old paper title given by Dr. Bates

GoodUSB: How I Learned to Stop Worrying and Love the Rubber Ducky

1. A quote from a chat in Skype[1]

“I read an article about how a dude in the subway fished out a USB flash drive from the outer pocket of some guy’s bag. The USB drive had “128” written on it. He came home, inserted it into his laptop and burnt half of it down. He wrote “129” on the USB drive and now has it in the outer pocket of his bag…”

2. BadUSB attacks

If you read the reference link, you will find that the “USB flash drive” (or USB Killer) has embedded some capacitors supporting high negative voltage (-110V). Once charged, these capacitors are able to cause over current in the USB signal line. While we are not going to talk about this in details (probably in another post), it does leave us a question: “Arriving at work, you find a USB drive on your table. What would you do?”[1]

In reality, data exfiltration or backdoor injection is preferred to burning down the machine. This is what USB rubber ducky[2] designed for. As a penetration testing tool, the USB rubber ducky looks like a USB thumb drive, but quacks like a keyboard, and types like a keyboard. Therefore, it is a keyboard. The only difference between a keyboard and a USB rubber ducky besides the appearance is that unlike normal keyboards, a USB rubber ducky does not need a human being to type the keystrokes – an adversary can write a malicious script, compile and load it into the ducky, and the ducky will execute it once plugged. How cool is that! A more powerful programable USB device is Teensy[3]. Teensy 3.1 development has been integrated into Arduino IDE. Similar with USB Killer, the best possible defense solution would be to open the case, and look at the PCB board carefully (as long as you know what you are looking at…).

Unfortunately, BadUSB[4] attacks in BlackHat 2014 made our best try so far a vain. Rather than requiring a specific USB micro controller, people could write malicious firmware by themselves on common USB micro controllers, thanks to the existing firmware building tools[5]. This means that a USB flash drive could behave like a storage and a keyboard the same time. While the storage provides the normal usage, the keyboard part is essentially a USB rubber ducky. The problem now is that we will not know if the firmware is malicious or not util it is plugged. And most of the time, we do not even know that there is a keyboard enabled, since it happens within the OS. Now let us repeat the question again: “Arriving at work, you find a USB drive on your table. What would you do?”

3. Root Cause Analysis

The root of BadUSB attacks originates from the USB spec. A USB device is able to have multiple functionalities (interfaces). Think about a USB headset, which contains audio functionalities (speaker + microphone), and a input/keyboard functionality (volume control). Therefore, there is no violation from the spec point for a USB storage device to have a keyboard functionality (and for some storage devices, this extra keyboard functionality may be needed as we will talk about this later). In reality, when a USB device is plugged into the host machine, it can report any functionalities (interfaces) that need OS’s support. The OS would try its best to find the corresponding driver to serve each of the functionality. Think about a BadUSB thumb drive. When it is plugged into the host machine, it reports itself with both a storage and an input (keyboard) interfaces during the USB enumeration (a procedure for the host machine to recognize the device). The OS then loads a storage driver and an input driver to make the device function. Once the input driver is loaded, the BadUSB device types a malicious script (like a human being), which is executed by the OS automatically. All of these happen in the OS within a second while the user is going through the files saved in the storage.

4. GoodUSB

The OS knows nothing about the USB device but is able to load different drivers to make the device happy (work); the user knows something about the device, e.g., from the appearance of the device, but is not able to interpose between the OS and the device. To bridge this semantic gap, ideally, we need a way to let the user and the OS talk:

User: I have just plugged in a USB flash drive.
OS: OK. I will not allow it to have a keyboard functionality then.

Essentially, this is GoodUSB.

As a end-to-end & systematic solution defending against malicious USB firmware, GoodUSB does not only include a customized Linux kernel but also a user-space daemon supporting GUI and a Honeypot KVM (HoneyUSB) for redirecting suspicious devices during run-time or start-time. While I am not going to list technical details here, I put the GoodUSB architecture figure here for a flavor and redirect further interests to our paper.

goodusb_arch

When the USB device is plugged into the host machine for the first time, the device class identifier in the kernel would try to fingerprint the firmware to get the signature (SHA1). The kernel then suspends further actions and sending the information about the device to the user-space daemon before enabling the device. The GoodUSB user-space daemon (gud) pops out a GUI asking for the user’s expectation about this device, as shown in the figure below:

goodusb_stupid_user_mode

Note that the choices in the GUI are high-level description for the device without any low-level USB spec terms. One beauty of GoodUSB is that once the user could give a general description of the device, the policy engine within gud is able to find right possible functionalities (interfaces) required to enable the device with the least “permission” (if we treat drivers as permissions). For instance, if the user choses “USB Storage”, no keyboard (input) functionality will be enabled for sure. After this, another GUI would pop out letting the user to bind this device with a security picture (just like a security picture when logging into online banking system). Now gud has all the information it needs. Besides updating the local device database, it relays all the information to the kernel, which could further configure the device as needed and expected by the user. When the device is plugged in for the 2nd time, the kernel is able to recognize it and asks for confirmation from the user via gud:

sec_pic_user_mode

However, if the device is shown as a green dinosaur but the user knows it should be a red one, then the user is aware that the firmware of the device has been changed (to mimic the device bound with a green dinosaur). In the case, after “This is NOT my device!” is clicked, the device will be redirected into HoneyUSB, where we have implemented a USB profiler (usbpro) to inspect the behaviors of the device. Even though GoodUSB was designed against BadUSB attacks, its ability to customize the functionalities to be enabled for a USB device is also invaluable in daily use. E.g., GoodUSB is able to shutdown the microphone in a USB headset but leaving the speaker working as usual.

5. Limitations

As other 0-day stuffs, GoodUSB is not able to defend against 0-day malicious firmware. If the keyboard is able to input scripts automatically, there is nothing GoodUSB can do. As readers may have been realized, GoodUSB relies on the trust of drivers. If the driver is malicious, GoodUSB does not work. Another thing I have to mention here is USB quirks. Although we have tried to cover as many devices as possible, there are always USB quirks, which would not function properly with GoodUSB. One example would be Yubikey, which looks like a thumb driver, has a USB hub functionality, and behaves like a keyboard. The last limitation comes from us – human beings. GoodUSB uses GUI and security pictures with the hope to help users make a better judgement. Again, this is our hope. We have not done and will not do any user study to show the validity of using GUI and security pictures. Usability is beyond the scope of the paper.

6. RtDC
paper: https://github.com/daveti/daveti/raw/master/paper/acsac15/acsac2015djt.pdf
code: https://github.com/daveti/GoodUSB

References:
[1]http://kukuruku.co/hub/diy/usb-killer
[2]http://hakshop.myshopify.com/products/usb-rubber-ducky-deluxe?variant=353378649
[3]https://www.pjrc.com/teensy/teensy31.html
[4]https://srlabs.de/badusb/
[5]https://github.com/daveti/badusb

About daveti

Interested in kernel hacking, compilers, machine learning and guitars.
This entry was posted in OS, Security and tagged , , , , , , , . Bookmark the permalink.

2 Responses to Defending Against Malicious USB Firmware with GoodUSB

  1. Pingback: Badusb - an Arduino based keystroke | Embeddedhacker

  2. Harish Yadav says:

    Sir, I am not able to execute goodUSB, can you please provide the guidelines to execute the program correctly. I’m stuck at “gud: info: waiting for a new connection”.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.