Ready for a Hacking Reality Check?
What I’m about to talk about is not the end-all be-all rooting device. The devices to be discussed are just keyboards. They can do anything a human at a keyboard can do… if that human could type really, really fast. Here are a couple instances that could happen in real life (or maybe they already have).
The "Half-Calf Double Chi Quad Shot Octuple Macchiato" SituationIf you’re at the coffee shop finishing up those TPS reports and you leave your computer unlocked for 10 seconds to grab your half-calf double chi quad shot octuple macchiato (because fibonacci), a guy sitting next to you with a "Ducky" (I'll explain more in a moment) can ruin your day.
The "Don't Ever Leave Your Computer Unlocked at Work" ScenarioIf you leave your computer unlocked at work, during your hour long lunch break, Joe (a cubical down from you) does not need some fancy USB device... he will be able to finger peck at 10 WPM and still have time to compile the virus he developed on your computer.
USB Ports and Coffee Scare Me...
Why do you USB ports scare me? Well, because they're everywhere and tools like the Ducky and BadUSB exist. What are those? They are the keyboards to which I previously referred - simple USB keyboards (in general) that will type whatever you program them to.
For example, you could type out the entire byte code for a virus into a file and run it in a minute or so. Or, you could type out the commands to open a terminal and background a command to make a web request for a virus then execute it… all in about 3 seconds. Do you ever turn away from your ports for 3 seconds?
It’s the coffee situation that’s scary because it can easily happen in real life. The previous Hurricane Labs standard issue laptop contained an out-of-sight USB port in the back. (This has caused neck problems for those of us who are paranoid, from all the contorting to make sure no one messed with that port). Some of the smarter people would plug something in there, like a mouse for instance. That way, if the mouse didn’t work upon their return, it was a good indicator that something else must be in there. Additionally, there is a hardware key logger floating around here that will read all the keystrokes your keyboard makes if it is put inline with the keyboard.
What Happened to "Bob" and the Ominous Ducky?
We once had an employee, let’s call him "Bob". For some reason, I really felt like I should do Bob a favor and test out his security... He was one of the ones who kept his mouse plugged into his hidden USB port, no matter.
One day, when Bob went out for lunch, leaving his locked computer, I replaced the mouse with a USB HUB, plugged his mouse and a USB extension cord into the HUB, then ran the extension cord under the cubicle wall straight to the next cube. Upon his return, Patrick (one of the best social engineers I have ever met) went over to have a chat with Bob about his latest video game purchase. Bob always turned 180 degrees away from his computer, leaving it unlocked, to talk to someone. During the conversation, I snuck into the next door cubicle, plugged my Ducky in, counted to 5, unplugged my Ducky, and went back to my computer, to find I had a reverse shell on Bob's computer. A few tricks later, I had complete complete control over Bob's workstation. I then proceeded to schedule a very important task on his computer: eject the disk drive at random intervals. Something that, on average, would occur 5 times per day.
The above story terrifies me because I have that exact same USB port exposed on my laptop. Sometimes, and I know I'm lazy for this, I look away from my computer without locking it to talk to people. I just don’t have it in me to check every single little thing plugged into my computer when I come back from the bathroom, lunch, meetings, or whatever else I’m called to do. So, what to do?
My first idea was to stop the Ducky from being registered as a device. This meant blacklisting the Ducky’s product ID. As it turns out, the Ducky actually tells the computer what vendor ID it has. So, the Ducky can spoof any vendor ID it wants. (It could even claim the same ID as my fancy TEX Yoda TrackPoint Keyboard!) That means both blacklisting and whitelisting are out.
Since I can't let my computer blindly trust any USB device I plug in, I must tell it whether it should be trusted or not when it gets plugged in. That means, unless I say so, the moment before a new USB device is plugged in, my computer should not recognize that device as safe. That also means Joe can come over when I am away and unplug my fancy Tex Yoda keyboard. When I get back it won't work until I log into my computer with the laptop keyboard, get a terminal and edit my udev rules (which requires sudo and a password), then unplug and replug my keyboard. That stinks for me and brings Joe a great deal of joy. I don't want Joe to be happy, so here enlies my solution.
Note: This will only work on systems that use UDEV. If your system does not use udev, you could probably implement some similar solution, but I cannot help with it. Sorry.
Things To Do With the Udev Rule
I "solved" (as far as my use case) all this with udev rules and a program I wrote in C. Yes - C. It is scary, but in order to change udev rules you need to be root. To be root easily you can use setuid, but only on a compiled program (and I expect - actually, I know - there are reasons why an interpreted language should not get setuid or sudo without a password).
So, this is how I use the program.
As soon as I log into my computer, the program is run automatically and creates a udev rule that blocks all new USB devices. This will stop the Ducky, Bad USB, and even alert me to the hardware key logger, since you would have to unplug my keyboard in order to install it. It won't block or disturb current devices or devices that are being unplugged.
Now, when I get a USB thumb drive with cat pictures that I want to look at, I simply run the same program again, with no arguments, and it will replace the "block all new USB" rule with one that only blocks new USB keyboards. This means if the USB drive is also a hidden keyboard, then that function will not work; however, the USB block device will.
Next, when Joe comes over and unplugs my keyboard, I run the program again with a single argument (anything really, any number of arguments, I am lazy and don't want to complicate this). Then the program will replace the "block all new USB" rule with one that allows any USB device. Whenever the rule changes, it only changes for 10 seconds, after which the program exits and restores the original "block all USB devices". When my computer shuts down it automatically deletes the udev rule file if it exists so that when I next boot my computer I can have my keyboard automatically (plus, I don't get errors).
Get it on GitHub!
This code is available on my GitHub and you are welcome to use it.
Other Note: This program is intended to run as setuid. If someone could exploit this program they could escalate privileges. However, since there’s barely any user interaction and only writes one of 3 static strings to 1 static file location, I don't think a race condition exists. I don't see how there could be a buffer overflow either since there are no buffers. I don't think there is much room for any vulnerabilities in the code, as long as permissions are set on it properly. However, I would be foolish to say it is 100% secure. So, if anyones finds any problems with it, please let me know and I will correct them. After all I use it too, so I’d like to stay safe myself.