USB Gadget Mode on Linux: From Helpful Tool to Stealthy Attack Vector

2026-11-01

Table of Contents

Introduction

Picture this: you're traveling and your phone battery is dwindling. You spot a USB charging port at the airport lounge and plug in. What if that port isn't just charging your device, but silently exfiltrating browser cookies and session tokens over unencrypted HTTP connections? Or imagine you need internet access and plug in what appears to be a legitimate USB mobile hotspot to tether your laptop. It provides connectivity, but it also creates a backdoor routing all your network traffic through an attacker's server, capturing everything that isn't properly encrypted.

These aren't hypothetical scenarios. They're real attacks built on USB gadget mode—the same technology that lets you conveniently tether your phone or SSH into a Raspberry Pi with a single cable. Here's an uncomfortable truth: that innocent-looking USB cable you found at a conference? It might already be typing commands on your computer. And the Raspberry Pi Zero you're using for a headless server project? It can do the exact same thing.

USB gadget mode (also called device mode or peripheral mode) inverts the typical USB relationship. Instead of your computer acting as the host deciding what devices to trust, gadget mode lets your Linux device become the device. Your single-board computer can impersonate a keyboard, network adapter, flash drive, or all three simultaneously. This capability powers everything from convenient development workflows to some of the most elegant physical access attacks ever demonstrated.

This article explores both sides of USB gadget mode: the legitimate uses that make embedded Linux development delightful, and the attack techniques that should make you think twice before plugging in unknown devices. We'll examine the Linux filesystem interfaces that make this possible, review real tools used by both defenders and attackers, and walk through practical examples. Whether you're building the next IoT device or securing your organization against physical access attacks, understanding USB gadget mode is essential.

The Core Problem: USB gadget mode exploits a fundamental asymmetry in the USB trust model. The host computer automatically trusts devices during enumeration—loading drivers, granting network access, accepting keystrokes—while the device can lie about its identity. A "charging cable" can be a keystroke injector. A "mobile hotspot" can be a traffic interceptor. A "webcam" can be a network backdoor. The USB specification prioritized convenience over security, and gadget mode reveals the consequences of that design choice.

The USB Protocol: Enumeration and Descriptors

When you plug a USB device into your computer, you're witnessing a carefully choreographed negotiation governed by the USB specification. Your computer acts as the USB host—providing power on the VBUS line (typically 5V), initiating all communication, and maintaining control over the bus. The device you plug in is the peripheral, responding to the host's requests and identifying itself through a hierarchical structure of descriptors.

The Enumeration Process

Enumeration happens in the first milliseconds after connection:

  1. Physical Detection: The host detects the device's presence through a pull-up resistor on either the D+ line (for high-speed and full-speed devices) or D- line (for low-speed devices). This resistor signals "a device is present" to the host controller.
  2. Reset and Speed Detection: The host issues a reset signal and determines the device's speed (low, full, high, or super-speed) based on which data line is pulled high.
  3. Descriptor Reading: The host reads a series of descriptors that describe the device's capabilities:
    • Device Descriptor: Contains fundamental information including:
      • bcdUSB: USB specification version the device supports
      • idVendor (VID): 16-bit vendor identifier (e.g., 0x1d6b for Linux Foundation, 0x046d for Logitech)
      • idProduct (PID): 16-bit product identifier specific to the vendor
      • bcdDevice: Device release number
      • iManufacturer, iProduct, iSerialNumber: Indices pointing to string descriptors
      • bNumConfigurations: Number of configuration descriptors
    • Configuration Descriptor: Describes power requirements and number of interfaces. A device can have multiple configurations (e.g., one for bus-powered operation, another for self-powered).
    • Interface Descriptor: Defines a group of endpoints that work together to provide a function. A single configuration can have multiple interfaces (e.g., audio interface + HID interface).
    • Endpoint Descriptor: Describes data transfer endpoints (direction, type, max packet size). Endpoints are the actual data pipes.
    • String Descriptors: Human-readable Unicode strings for manufacturer, product, and serial number.
  4. Driver Loading: Based on the device class (specified in interface descriptors), the host loads appropriate kernel drivers. Common classes include:
    • 0x03: Human Interface Device (HID)—keyboards, mice
    • 0x08: Mass Storage
    • 0x02 (CDC): Communications Device Class—serial, Ethernet
    • 0xEF: Miscellaneous (often composite devices)
  5. Configuration Selection: The host selects a configuration and sets it active. The device is now operational.

This entire process happens automatically, built on a foundation of implicit trust. Your operating system assumes the device is what its descriptors claim. USB gadget mode exploits this trust by letting your Linux device craft arbitrary descriptors, presenting itself as anything from a harmless flash drive to a trusted keyboard.

Peripheral vs. Host Mode: "Peripheral mode" means your device responds to a host (like a phone in peripheral mode presenting itself as a USB storage device to your host PC). "Host mode" means your device controls the bus (like your phone in host mode reading files from a connected USB storage device). USB On-The-Go (OTG) hardware can switch between these roles, which is essential for gadget mode support. DRP (Dual-Role-Power) ports allow devices to switch between being a power source and sink.

Linux USB Gadget Mode Fundamentals

What is a USB Gadget?

In Linux kernel terminology, a gadget is a USB device implementation. When your Linux-powered hardware acts as a USB peripheral instead of a host, it's running a gadget driver. The gadget framework lets you compose multiple functions (mass storage, Ethernet, serial, HID) into a single configuration presented to the USB host.

ConfigFS: The Filesystem-as-API

Modern Linux USB gadget configuration uses ConfigFS, a RAM-based filesystem typically mounted at /sys/kernel/config. This approach embodies the Unix philosophy: configure your USB device by creating directories and writing to files. No special tools, no kernel recompilation—just filesystem operations.

The current kernel documentation for USB gadget ConfigFS is available at docs.kernel.org/usb/gadget_configfs.html. The hierarchy looks like this:

/sys/kernel/config/usb_gadget/g1/ # g1 is your gadget instance
├── idVendor                 # Write your VID here
├── idProduct                # Write your PID here
├── bcdDevice                # Device release number
├── bDeviceClass             # Device class
├── bMaxPacketSize0          # Max packet size for endpoint 0
├── strings/
│   └── 0x409/               # Language ID (0x409 = US English)
│       ├── manufacturer
│       ├── product
│       └── serialnumber
├── configs/
│   └── c.1/                 # Configuration 1
│       ├── MaxPower         # Maximum power consumption
│       └── strings/
│       └── 0x409/
│           └── configuration
├── functions/
│   ├── mass_storage.0/      # Mass storage function
│   ├── ecm.usb0/            # Ethernet function (CDC-ECM)
│   ├── rndis.usb0/          # Ethernet function (RNDIS for Windows)
│   └── hid.0/               # HID function
└── UDC                      # Bind to USB Device Controller

To activate a gadget, you:

  1. Create the gadget directory structure
  2. Set vendor/product IDs and strings
  3. Create function instances
  4. Link functions to configurations
  5. Write the UDC (USB Device Controller) name to the UDC file

Hardware Requirements

Not every Linux device can act as a USB gadget. You need hardware with a USB Device Controller (UDC) that supports peripheral mode. Here's the rundown for popular platforms:

Raspberry Pi models supporting USB gadget mode:

Important: Earlier Raspberry Pi B-series models (1B, 2B, 3B) have a USB hub between the SoC and the USB ports, preventing direct gadget mode access. The Pi 400 seems to support gadget mode under certain configurations.

Other supported hardware includes BeagleBoard boards, many embedded ARM systems, and specialized security devices like the F-Secure USB armory.

The Dark Side: Attack Vectors

PoisonTap: Hijacking Networks from Locked Machines

Perhaps the most elegant demonstration of USB gadget mode's offensive potential is PoisonTap, created by security researcher Samy Kamkar. Built on a $5 Raspberry Pi Zero, PoisonTap exploits the automatic trust granted to USB Ethernet adapters.

How PoisonTap Works:

  1. Network Emulation: When plugged into a locked computer, PoisonTap presents itself as a USB Ethernet adapter using the g_ether gadget driver.
  2. DHCP Hijacking: It responds to the automatic DHCP request with a crafted response claiming the entire IPv4 space (0.0.0.0/0) is on its local network.
  3. Traffic Interception: Due to how routing tables prioritize LAN traffic over gateway routes, all internet traffic gets routed through PoisonTap.
  4. Cookie Siphoning: Background browser requests (ads, analytics, etc.) hit PoisonTap's web server, which serves malicious HTML/JavaScript that creates hidden iframes across the Alexa top 1 million sites, capturing cookies.
  5. Persistent Backdoor: PoisonTap force-caches backdoor pages in the browser cache, creating persistent WebSocket connections to an attacker-controlled server on the internet.
  6. Router Access: Through DNS rebinding techniques, it even creates backdoors to the victim's internal router.

The brilliance? This all works on locked, password-protected machines because the network stack operates independently of the login screen.

Key files in PoisonTap:

GitHub: github.com/samyk/poisontap
Project page: samy.pl/poisontap

BadUSB and Keystroke Injection

The BadUSB attack, presented at Black Hat 2014 by Karsten Nohl and Jakob Lell, demonstrated that USB device firmware could be reprogrammed to perform malicious actions. Unlike traditional malware that lives in the filesystem, BadUSB resides in the device's firmware, surviving OS reinstalls and disk formatting. For a comprehensive overview, see the BadUSB Wikipedia article.

The core insight of BadUSB is that many USB devices contain microcontrollers with reprogrammable firmware. When you plug in a USB device, the host reads descriptors that tell it what the device is—but nothing prevents a device from lying about its identity. A flash drive can reprogram itself to act as a keyboard. A charging cable can log keystrokes. This isn't malware in the traditional sense; it's the device itself becoming the attack vector.

Unlike traditional malware, BadUSB attacks:

The Linux gadget framework makes BadUSB-style attacks accessible to anyone with a supported single-board computer, democratizing both offensive security research and defensive testing capabilities.

Hak5 Arsenal: Professional-Grade USB Attack Tools

Modern implementations have refined the BadUSB concept into practical, scriptable platforms. Hak5 has developed a suite of professional tools widely used in penetration testing.

USB Rubber Ducky
The original keystroke injection tool. The Rubber Ducky presents itself as a keyboard and executes pre-programmed keystroke sequences at superhuman speeds. It uses DuckyScript, which has evolved from basic macros to a structured programming language with variables, loops, and conditional logic.

The Rubber Ducky can also execute a keystroke reflection attack to exfiltrate data through a side channel. In this attack, the device captures data from the target machine and encodes it into a sequence of keyboard LED states—specifically utilizing the Caps Lock, Num Lock, or Scroll Lock indicators. Next, the Rubber Ducky runs a script on the computer that triggeres these LED changes, sending the signals back to the device via USB HID OUT. The device then captures and stores these signals, allowing an attacker to retrieve the original data directly from the hardware. This makes the technique an effective method for exfiltrating data from air-gapped systems. See the documentation on exfiltration techniques.

Product page: shop.hak5.org/products/usb-rubber-ducky

O.MG Cable
This is where things get particularly concerning. The O.MG Cable looks identical to a legitimate USB charging cable but contains a hidden implant with WiFi capabilities. Demonstrated in various security presentations including this overview, it can:

The cable remains dormant during normal charging and data transfer, activating only when commanded. An attacker can sit hundreds of feet away, connect to the cable's WiFi access point, and deploy payloads through a web interface.

Technical capabilities:

Product page: shop.hak5.org/products/omg-cable

Bash Bunny
The Bash Bunny is the Swiss Army knife of USB attacks. Running a full Linux distribution on a quad-core ARM processor with 8GB of storage, it can simultaneously emulate multiple device types: keyboard, network adapter, serial device, and mass storage. This enables multi-vector attacks that combine techniques.

Key features:

Example payload snippet:

ATTACKMODE HID AUTO_ETHERNET
GET TARGET_HOSTNAME
RUN WIN cmd /K color a & tree c:\
LED R

The Bash Bunny can perform "bring-your-own-network" attacks, creating a network interface that the target trusts, then using that connection for further exploitation.

Product page: shop.hak5.org/products/bash-bunny

VID/PID Spoofing and Device Impersonation

One of the most powerful aspects of USB gadget mode is the ability to spoof device identifiers. By writing arbitrary values to the ConfigFS files, you can make your device appear as any USB product.

# Set vendor and product ID to impersonate a specific device
echo 0x046d > /sys/kernel/config/usb_gadget/g1/idVendor   # Logitech
echo 0xc31c > /sys/kernel/config/usb_gadget/g1/idProduct  # Specific keyboard model

# Set strings to match
echo "Logitech" > /sys/kernel/config/usb_gadget/g1/strings/0x409/manufacturer
echo "Logitech USB Keyboard" > /sys/kernel/config/usb_gadget/g1/strings/0x409/product
echo "0123456789" > /sys/kernel/config/usb_gadget/g1/strings/0x409/serialnumber

This technique allows attackers to:

The DEF CON 34 badge takes this to another level. Designed by Andrew "bunnie" Huang, the badge features the Baochip-1x, a transparent, open-source SoC. After the conference, the badge's core module can be detached and used as a FIDO2 security key, TOTP authenticator, or password manager. It demonstrates legitimate secure element functionality while being fully inspectable down to the RTL source code.

DEF CON 34 Badge: defcon.org/34b

The Bright Side: Legitimate Use Cases

While the attack potential is significant, USB gadget mode enables numerous legitimate and valuable applications.

USB Tethering: A Common Gadget Use Case

You've probably already used USB gadget mode without realizing it. USB tethering—the feature that lets you share your phone's mobile data connection with your laptop over USB—is one of the most widespread implementations of USB gadget mode in the world.

When you enable USB tethering on your Android or iOS device (note that Apple implements a custom protocol), your phone:

  1. Activates its USB Device Controller in gadget mode
  2. Creates a virtual Ethernet adapter (typically using CDC-ECM, CDC-NCM, or RNDIS)
  3. Presents itself to the host computer as a network interface
  4. Runs a DHCP server to assign an IP address to the host
  5. Routes traffic between the USB network interface and your cellular modem

On Linux, you can verify tethering is working by checking for the new network interface:

# Check for USB network interfaces
ip link show

# You should see something like usb0, enp0s20f0u1, or similar
ip addr show usb0

# View the routing table to see traffic flowing through USB
ip route show

USB tethering offers several advantages over WiFi hotspots:

However, the same technology enabling convenient tethering also enables network-based attacks like PoisonTap. The difference lies in intent and authorization. This duality is the essence of USB gadget mode.

The Peril of USB Tethering: While USB tethering is convenient, it creates a trusted network path that can be exploited. A malicious device posing as a tethering hotspot can intercept unencrypted traffic, perform man-in-the-middle attacks, or establish persistent backdoors. Always verify the device you're tethering to, use encrypted connections (HTTPS, DNS over HTTPS (DoH) or DNS over TLS (DoT), VPN), and avoid tethering from unknown or untrusted devices.

Your Android Phone as a Multi-Tool USB Device

Beyond tethering, Android devices running Linux kernels with ConfigFS support can be transformed into virtually any USB device. The open-source USB Gadget Tool app by tejado brings this capability to your pocket.

USB Gadget Tool: Available on GitHub and F-Droid, this app provides a user-friendly interface for creating and activating USB gadget configurations on rooted Android devices. No command-line knowledge required.

Supported USB gadget types:

Requirements:

Use cases for security professionals:

GitHub Repository: github.com/tejado/android-usb-gadget
Companion App (Authorizer): github.com/tejado/Authorizer
Available on: F-Droid store

Note: USB Gadget Tool requires root access because it modifies kernel-level USB configurations. Only use on devices you own and understand the security implications of rooting your phone. The app itself only enables the USB gadget endpoints; you'll need additional apps to implement actual device functionality (keyboard input, FIDO authentication, etc.).

SSH Over USB for Headless Development

Raspberry Pi's rpi-usb-gadget package (included in Raspberry Pi OS Trixie and later) makes it trivial to set up Ethernet-over-USB for headless development. No WiFi configuration, no network scanning—just plug in and SSH.

Setup commands:

# Install the package
sudo apt update
sudo apt install rpi-usb-gadget

# Enable gadget mode
sudo rpi-usb-gadget on
sudo reboot

After reboot, connect the Pi to your computer via USB-C (Pi 4/5) or the USB-A (Zero). Your computer will see it as a network adapter. SSH using the hostname you configured:

ssh pi@raspberrypi.local

The package automatically handles:

GitHub: github.com/raspberrypi/rpi-usb-gadget
Announcement: raspberrypi.com/news/usb-gadget-mode-in-raspberry-pi-os-ssh-over-usb

Virtual Mass Storage for Embedded Systems

You can turn your embedded Linux device into a USB flash drive, exposing a file or block device as mass storage. This is useful for firmware updates, data exchange with devices lacking network connectivity, creating bootable installation media, or secure data transfer by copying to an encrypted file system on the embedded device.

Complete example script (adapted from popovicu.com):

#!/usr/bin/env bash
# Create a USB mass storage gadget

CONFIGFS="/sys/kernel/config"
GADGET="$CONFIGFS/usb_gadget/g1"
STORAGE_FILE="/storage/lun0.img"

# Create example storage file with zeroes on FAT
dd if=/dev/zero of=$STORAGE_FILE bs=1M count=16
mkfs.vfat $STORAGE_FILE

# Mount configfs
mount -t configfs none "$CONFIGFS"

# Create gadget directory
mkdir -p "$GADGET"
cd "$GADGET"

# Set vendor and product IDs
echo 0xabcd > idVendor
echo 0x1234 > idProduct

# Create strings
mkdir -p strings/0x409
echo "0123456789" > strings/0x409/serialnumber
echo "Your Name" > strings/0x409/manufacturer
echo "USB Flash Drive" > strings/0x409/product

# Create configuration
mkdir -p configs/c.1
mkdir -p configs/c.1/strings/0x409
echo "Mass Storage Config" > configs/c.1/strings/0x409/configuration
echo 120 > configs/c.1/MaxPower

# Create mass storage function
mkdir -p functions/mass_storage.0
mkdir -p functions/mass_storage.0/lun.0
echo "$STORAGE_FILE" > functions/mass_storage.0/lun.0/file

# Link function to configuration
ln -s functions/mass_storage.0 configs/c.1

# Find and bind to UDC
ls /sys/class/udc/ > UDC

echo "USB mass storage gadget activated!"

Network Adapters and Serial Consoles

Ethernet gadgets provide network connectivity over USB, useful for devices without Ethernet ports, secure out-of-band management, or testing network configurations.

Available functions:

Serial gadgets (CDC ACM) provide virtual serial ports for console access during debugging, communication with legacy equipment, or IoT device management.

# Create a serial gadget
mkdir -p functions/acm.GS0
ln -s functions/acm.GS0 configs/c.1

Development and Debugging

USB gadget mode enables powerful development workflows including FunctionFS for implementing custom USB functions in userspace (MTP, custom protocols), composite gadgets for complex device emulation, rapid prototyping of USB device drivers without dedicated hardware, and automated USB device testing in CI/CD pipelines.

USB-Triggered Actions: BusKill, USBKill, and udev Rules

Beyond gadget mode, USB events can trigger automated actions on the host system. This capability serves both defensive purposes (protecting data when devices are removed) and offensive ones (executing payloads when devices are inserted).

BusKill: Cable Yank Detection

BusKill is a security mechanism that triggers actions when a USB cable is unplugged. Originally designed for laptop users in hostile environments, it detects when the USB connection is severed and can execute predefined responses.

Use cases include:

The BusKill project provides both hardware (a magnetic breakaway cable with embedded electronics) and software components. See the Wikipedia article on BusKill for background.

USBKill: Device Change Protection

USBKill monitors USB ports and triggers protective actions when unauthorized devices are connected or removed. It's commonly used to protect against data exfiltration attempts.

Typical responses include:

The tool is open-source and configurable via JSON policies. More information is available on the USBKill Wikipedia page.

udev Rules: Custom USB Event Handling

Linux provides udev, the device manager for the Linux kernel, which can execute arbitrary commands when USB devices are connected or disconnected. This is more flexible than dedicated tools like BusKill or USBKill.

Example: Disable WiFi when USB device is removed

# Create udev rule: /etc/udev/rules.d/99-usb-kill.rules

# Trigger when USB device is removed
ACTION=="remove", SUBSYSTEM=="usb", RUN+="/usr/sbin/rfkill block all"

# Trigger when USB device is added
ACTION=="add", SUBSYSTEM=="usb", RUN+="/usr/sbin/rfkill unblock all"

Example: Log USB connections

# Log all USB device additions
ACTION=="add", SUBSYSTEM=="usb", RUN+="/usr/bin/logger USB device added: %k"

Example: Block unauthorized vendors

# Block specific vendor IDs
ACTION=="add", ATTRS{idVendor}=="1234", RUN+="/bin/sh -c 'echo 0 > /sys$DEVPATH/authorized'"

After creating rules, reload udev:

sudo udevadm control --reload-rules
sudo udevadm trigger

For rfkill documentation, see the kernel documentation.

display-switch: Monitor Control on USB Events

The display-switch project takes a different approach: it switches monitor inputs when USB devices are connected or disconnected. This is useful for KVM-like setups where you want to automatically switch displays between computers.

Key features:

GitHub: github.com/haimgel/display-switch

Security Note: USB-triggered actions can be exploited by attackers. A malicious device could repeatedly connect/disconnect to trigger unwanted behavior, or mimic authorized devices to bypass protections. Always combine USB event handling with device authorization (USBGuard) and behavioral monitoring.

Hands-On: Building Your Own USB Gadget

Detecting Device Mode Support

Before you start, verify your hardware supports gadget mode:

# Check for USB Device Controller
ls /sys/class/udc/

# Check kernel configuration
zcat /proc/config.gz | grep -i "USB_GADGET"
# Or for current kernel config:
grep -i "USB_GADGET" /boot/config-$(uname -r)

# Look for dwc2 (DesignWare USB2) or other UDC drivers
dmesg | grep -i "udc\|gadget\|dwc2"

# Check if libcomposite is loaded
lsmod | grep libcomposite

If /sys/class/udc/ is empty, your hardware likely doesn't support peripheral mode, or you need to enable it via device tree overlay.

Creating a Composite Gadget

Here's how to create a gadget that acts as both mass storage AND Ethernet:

#!/usr/bin/env bash
# Composite gadget: Mass Storage + Ethernet

CONFIGFS="/sys/kernel/config/usb_gadget"
GADGET="$CONFIGFS/g1"

# Clean up existing gadget if present
if [ -d "$GADGET" ]; then
    echo "" > "$GADGET/UDC" 2>/dev/null
    rm -rf "$GADGET"
fi

# Create gadget structure
mkdir -p "$GADGET"
cd "$GADGET"

# Set IDs (using Linux Foundation IDs for testing)
echo 0x1d6b > idVendor    # Linux Foundation
echo 0x0104 > idProduct   # Multifunction Composite Gadget

# Strings
mkdir -p strings/0x409
echo "0123456789" > strings/0x409/serialnumber
echo "Your Name" > strings/0x409/manufacturer
echo "Composite Gadget" > strings/0x409/product

# Configuration
mkdir -p configs/c.1/strings/0x409
echo "Composite Config" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower

# Mass Storage function
mkdir -p functions/mass_storage.0
dd if=/dev/zero of=/tmp/storage.img bs=1M count=32
mkfs.vfat /tmp/storage.img
echo /tmp/storage.img > functions/mass_storage.0/lun.0/file

# Ethernet function (ECM for Linux/macOS, auto-switches to RNDIS for Windows)
mkdir -p functions/ecm.usb0

# Link functions to configuration
ln -s functions/mass_storage.0 configs/c.1
ln -s functions/ecm.usb0 configs/c.1

# Bind to UDC
ls /sys/class/udc/ > UDC

echo "Composite gadget activated!"
echo "Storage: /dev/sdX should appear"
echo "Network: usb0 interface created"

Detection, Defense, and Limitations

Identifying Reprogrammable Devices

How can you tell if a connected USB peripheral might be utilizing gadget mode?

Physical indicators:

Linux reconnaissance commands:

# Detailed USB device information
lsusb -v | less

# Look for suspicious indicators:
# - Multiple device classes in one device
# - Generic vendor IDs (0x1d6b Linux Foundation)
# - Missing or suspicious manufacturer strings
# - Device class 0x00 (defined at interface level)

# Monitor USB events in real-time
udevadm monitor --udev --property --subsystem-match=usb

# Check for network interfaces appearing on USB connection
ip link show
dmesg | tail -50

# Look for mass storage devices
lsblk
dmesg | grep -i "sd[a-z]"

# Check USB device tree
lsusb -t

Suspicious patterns:

Mitigation Strategies

Defending against USB gadget-based attacks requires defense in depth—combining physical security, technical controls, and user awareness.

Physical Security
Monitoring and Detection
Network-Level Defenses (for PoisonTap)
Organizational Policies

NIST SP 1334 offers more targeted formal guidance if you are focusing specifically on portable storage media.

USB Device and Interface Authorization

USBGuard: This open-source framework enforces USB device authorization policies. It can automatically generate rules based on currently connected devices, then block any new devices that don't match the allowlist. See usbguard.github.io for documentation.

usbauth This open-source alternative to USBGuard enforces authorization policies for USB interfaces instead of devices. See manpages.ubuntu.com for documentation.

# Install usbguard for USB device allowlisting
sudo apt install usbguard
sudo usbguard generate-policy > /etc/usbguard/rules.conf
sudo systemctl enable --now usbguard

# Block specific device classes
# Edit /etc/usbguard/rules.conf to deny HID devices from unknown vendors

# Disable USB storage entirely (if not needed)
echo "install usb-storage /bin/true" > /etc/modprobe.d/disable-usb-storage.conf

# Enable USB authorization
echo 1 > /sys/bus/usb/devices/usbX/authorized
echo 0 > /sys/bus/usb/devices/usbX/authorized_default

Keystroke Injection Detection

Google open-sourced UKIP (USB Keystroke Injection Protection), a daemon that monitors keystroke timing patterns to detect and block injection attacks. The tool uses heuristics to distinguish between human typing and automated keystroke injection:

When an attack is detected, UKIP can either log the event (MONITOR mode) or immediately unbind the malicious device driver (HARDENING mode). While not a silver bullet, it raises the bar significantly for attackers.

# Install UKIP from source
git clone https://github.com/google/ukip.git
cd ukip
chmod +x setup.sh
./setup.sh

# Configure heuristics (edit /usr/sbin/ukip)
KEYSTROKE_WINDOW=5
ABNORMAL_TYPING=50000

# Enable and start the systemd service
sudo systemctl enable ukip.service
sudo systemctl start ukip.service

# Check logs for detected attacks
journalctl -u ukip.service

Google's UKIP Tool: Read the original announcement on the Google Open Source Blog. The tool is particularly effective against Rubber Ducky-style attacks that type at superhuman speeds (hundreds of words per minute). However, sophisticated attackers can slow down their payloads to evade detection, which is why UKIP should be part of a layered defense strategy.

Sandboxing the USB Stack

As another layer of defense, the software stack that interacts with USB devices can be sandboxed. Qubes OS achieves this through a USB virtual machine, which isolates the processes communicating with USB devices. Because a misconfiguration in this setup could disable a USB keyboard, PS/2 keyboards are recommended instead.

Hardware USB Firewalls

Software controls like USBGuard run on the host system and can be bypassed if the host is compromised. Hardware USB firewalls provide an additional layer of protection by filtering USB traffic at the physical level.

USG: USB Security Gateway

The USG (USB Security Gateway) is an open-source hardware firewall that sits between a USB device and your computer. It inspects all USB traffic, blocks unauthorized control commands, and permits only allowlisted device classes.

Key features:

Unlike software solutions, USG provides hardware-level protection that cannot be bypassed by malware on the host system. The project was developed as a countermeasure against BadUSB and similar attacks.

Project wiki: github.com/robertfisk/USG/wiki
Background: boingboing.net/2017/03/02/countermeasures.html

Limitation: USG protects against malicious USB commands but cannot prevent all attack types. Network-based attacks (like PoisonTap) may still succeed if Ethernet-over-USB is allowlisted. Combine USG with software controls and user awareness for comprehensive protection.

Commercial Alternatives

Commercial USB firewall products include USB Sentry and various USB data firewall devices that similarly monitor and filter USB traffic between devices and hosts. These products typically offer:

USB Data Blockers

A USB data blocker—sometimes called a "USB condom"—is an adapter or cable that provides power but lacks data pins. By allowing charging while preventing data transfer, it protects devices from juice jacking, a security threat where charging equipment is used to steal data from connected devices.

USB Overvoltage Protection

USB killers damage connected hardware by delivering high-voltage surges. Protective devices, such as the USBKill Shield, safeguard hardware by blocking these surges and preventing such attacks.

Limitations and Practical Considerations

While USB gadget mode is powerful, it has important limitations that affect both attackers and defenders.

Hardware Limitations:

Technical Limitations:

Detection Evasion Challenges:

Legal and Ethical Considerations: Using USB gadget mode for attacks against systems you don't own or have explicit permission to test is illegal in most jurisdictions. Computer fraud and abuse laws (such as the CFAA in the United States) apply to USB-based attacks just as they do to network-based attacks. Only use these techniques on systems you own or have written authorization to test.

The Arms Race Continues

USB security is an ongoing arms race. As detection methods improve, so do evasion techniques. Recent developments include:

Understanding these limitations helps defenders set realistic security expectations. The most effective security posture acknowledges that USB gadget mode is neither unstoppable nor undetectable—it's simply another attack surface that requires appropriate controls.

Conclusion

USB gadget mode on Linux exemplifies technology's dual-use nature. The same capability that lets you SSH into your Raspberry Pi with a single cable also enables attackers to hijack networks from locked machines. The filesystem-based ConfigFS interface makes it beautifully simple to configure USB devices, but that simplicity also means sophisticated attacks are just a few echo commands away.

Understanding USB gadget mode is essential whether you're:

The tools and techniques discussed here—from PoisonTap's elegant network hijacking to the Bash Bunny's multi-vector attacks, from Raspberry Pi's convenient SSH-over-USB to the DEF CON badge's open-source FIDO2 implementation, from Android phones as multi-tool USB devices to Google's UKIP keystroke injection detector—all stem from the same fundamental capability: gadget mode's ability to become any USB device you can imagine.

As with all powerful tools, the responsibility lies with the wielder. Use this knowledge to build better defenses, create more secure systems, and understand the invisible negotiations happening every time you plug in a USB device. And maybe think twice before picking up that abandoned USB cable at the coffee shop.

References

Attack Tools and Research

Legitimate Use Cases

USB-Triggered Actions

Detection and Defense

Linux Kernel Documentation

Wikipedia References

Blog Posts

  1. USB Gadget Mode on Linux: From Helpful Tool to Stealthy Attack Vector (2026-11-01)
  2. Finding Weak ECDSA Keys: A Lesson from the eMudhra Incident (2026-10-25)
  3. CVE-2026-113582: Apache Abdera XML External Entity (XXE) Vulnerabilities (2026-10-24)
  4. Bringing TEE-Mediated Private AI to Linux with TPM-Backed Passkeys (2026-02-21)
  5. Sandboxing Applications on Linux: Securing Password Managers with Firejail (2026-02-07)
  6. Running Tailscale in a Container (2026-01-25)
  7. Running dnscrypt-proxy in a Container (2026-01-17)
  8. Proxying Applications Without Native SOCKS Support (2026-01-11)
  9. Running a SOCKS Proxy for the Tor Onion Network in a Container (2026-01-05)
  10. Running OpenSSH Client as a SOCKS Proxy in a Container (2026-01-04)
  11. Adding Poe AI Support to Roo Code (2025-11-23)
  12. Introducing Edi: A CLI Tool for Interacting with the Poe API (2025-09-14)
  13. Deriving the Sum of Powers Formula (2025-08-03)
  14. Scheduling Color Temperature Changes for Your Monitors (2025-06-07)
  15. Stream and Play: Emulating Retro Games on Chromecast with Google TV (2025-05-10)
  16. Simulating the Monty Hall Problem (2025-05-04)
  17. Pi-hole on Raspberry Pi OS with dnscrypt-proxy (2024-01-28)
  18. Prime or Not Prime: That is the Question (2023-07-22)
  19. Switching Monitor Inputs on Computer Wakeup (2021-04-25)
  20. Changing the Playback Speed on Spotify's Web Player (2021-04-24)
  21. Solving Microcorruption Hollywood (2021-03-28)
  22. Font Rendering on macOS (2020-07-02)
  23. Video Disk Recorder (VDR) Tooling (2020-05-30)
  24. Spotify Web Player Failure due to Crash of Connected Device (2020-05-08)
  25. Malicious Forward Proxies (2020-04-27)
  26. Switching to a Dark Theme (2020-04-25)
  27. USB 3.0 to Gigabit Ethernet Adapter with Realtek 8153 Chipset on macOS Catalina (2020-04-23)
  28. Backing up Emails using OfflineIMAP (2020-04-19)
  29. Using a Raspberry Pi as a Wireless Access Point (2020-04-18)
  30. Accessing External Hard Drives in a Virtual Machine (2017-12-11)
  31. Managing Clipboards (2016-11-23)
  32. Multi-Screen Configuration Using Xrandr (2016-07-02)
  33. Email Backup and Migration using Thunderbird (2016-06-29)
  34. Automatic SSH Proxy Selection (2016-02-08)
  35. Set Color Temperature (2015-11-25)
  36. Completion Methods in Vim (2015-10-10)
  37. Fuzzing the mbed TLS Library (2015-09-26)
  38. SSH Weak Diffie-Hellman Group Identification Tool (2015-08-12)
  39. Building a Standing Desk for 50 Bucks (2015-01-25)
  40. High-DPI Displays under Linux (2014-12-23)
  41. Slow Wi-Fi on the Raspberry Pi (2014-06-15)
  42. XBMC on the Raspberry Pi (2014-06-14)
  43. Turning the Raspberry Pi into a Game Console (2014-06-12)
  44. ZFS Backups to External Hard Drives (2014-03-23)
  45. Display the I/O Usage of a Process (2014-02-21)
  46. Determining Wireless Network Channel Usage (2014-02-09)
  47. Managing Web Files through a Repository (2013-08-17)
  48. Simple HTTP File Servers (2013-08-16)
  49. Protect your SSH Private Keys (2013-06-16)
  50. Forward Secrecy for HTTPS and Ephemeral Diffie-Hellman (2013-06-14)
  51. Markdown Preview Chrome Extension (2013-06-13)