rss home github email

Preventing USB Attacks with Grsecurity

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:

grsecurity-3.1-4.8.14-201612110933.patch:121501

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.

[Service]
Type=oneshot
ExecStart=/usr/bin/sysctl kernel.grsecurity.deny_new_usb=1
ExecStop=/usr/bin/sysctl kernel.grsecurity.deny_new_usb=0
RemainAfterExit=yes

[Install]
WantedBy=default.target suspend.target sleep.target

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

#!/bin/bash

set -e

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