Preventing USB Attacks with Grsecurity

An update to this post using the linux-hardened project is available here.

USB has some surprising security implications: when a device is plugged in, the operating system generally loads the appropriate driver and initializes it. For example, plugging a device into an unlocked computer can execute code, since the device can act as a USB keyboard. This is how the "BadUSB" series of attacks work.

Samy Kamkar's Poisontap project has been getting a lot of press recently. It's a little more interesting since it can work on locked computers.

When PoisonTap (Raspberry Pi Zero & Node.js) is plugged into a locked/password protected computer, it:

grsecurity comes with a mitigation. If your grsecurity kernel is built with GRKERNSEC_DENYUSB, then the kernel.grsecurity.deny_new_usb sysctl lets you prevent new USB devices from being loaded:


a new sysctl option with name "deny_new_usb" will be created. Setting its value to 1 will prevent any new USB devices from being recognized by the OS. Any attempted USB device insertion will be logged. This option is intended to be used against custom USB devices designed to exploit vulnerabilities in various USB device drivers.

For greatest effectiveness, this sysctl should be set after any relevant init scripts. This option is safe to enable in distros as each user can choose whether or not to toggle the sysctl.

I wrote a systemd service so that I can enable it on boot and suspend, and sudo systemctl stop deny_new_usb when I actually want to use a USB device.

ExecStart=/usr/bin/sysctl kernel.grsecurity.deny_new_usb=1
ExecStop=/usr/bin/sysctl kernel.grsecurity.deny_new_usb=0


and added a bit to i3status, so that I can see whether it's on or not in my statusbar:


set -e

i3status | while true; do
    read line
    if systemctl status deny_new_usb >/dev/null
        usb_status="USB 🔒"
        usb_status="USB 🔓"
    echo "$usb_status | $line"