USB Gadget Mode on Linux: From Helpful Tool to Stealthy Attack Vector
2026-11-01
Table of Contents
- Introduction
- The USB Protocol: Enumeration and Descriptors
- Linux USB Gadget Mode Fundamentals
- The Dark Side: Attack Vectors
- The Bright Side: Legitimate Use Cases
- USB-Triggered Actions: BusKill, USBKill, and udev Rules
- Hands-On: Building Your Own USB Gadget
- Detection, Defense, and Limitations
- Conclusion
- References
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:
- 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.
- 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.
- 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.
- Device Descriptor: Contains fundamental information including:
- 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)
- 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:
- Create the gadget directory structure
- Set vendor/product IDs and strings
- Create function instances
- Link functions to configurations
- 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:
- Raspberry Pi Zero / Zero W / Zero 2 W: Use the micro USB port closest to HDMI (not the PWR IN port)
- Raspberry Pi 3 Model A+: Supported
- Raspberry Pi 4 Model B: Use the USB-C port
- Raspberry Pi 5 / 500 / 500+: Use the USB-C port
- Compute Module 4: Technically supported but requires manual setup
- Compute Module 5: Use the USB-C port on the IO board
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 standard configurations.
Other supported hardware includes BeagleBone 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:
- Network Emulation: When plugged into a locked computer, PoisonTap presents itself as a USB Ethernet adapter using the g_ether gadget driver.
- 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.
- Traffic Interception: Due to how routing tables prioritize LAN traffic over gateway routes, all internet traffic gets routed through PoisonTap.
- 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.
- Persistent Backdoor: PoisonTap force-caches backdoor pages in the browser cache, creating persistent WebSocket connections to an attacker-controlled server on the internet.
- 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:
- pi_startup.sh: Configures the Ethernet gadget and DHCP server
- pi_poisontap.js: Node.js server handling HTTP requests and cookie capture
- backdoor.html: Cached backdoor with WebSocket to attacker server
- target_injected_xhtmljs.html: HTML/JavaScript injected into victim's requests
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 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:
- Survive operating system reinstalls and disk formatting
- Bypass antivirus software (there's no file to scan)
- Can spread between computers without network connectivity
- Are extremely difficult to detect without specialized hardware
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.
- How it works: Emulates a USB HID keyboard, executing payloads written in DuckyScript
- Attack mode: ATTACKMODE HID
- Strengths: Simple, reliable, bypasses most antivirus (it's just typing!)
- Documentation: documentation.hak5.org/hak5-usb-rubber-ducky
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.
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:
- Inject keystrokes via DuckyScript
- Log keystrokes from connected keyboards (Elite model)
- Be controlled remotely over WiFi
- Exfiltrate data wirelessly
- Spoof any VID/PID/MAC address
- Self-destruct on command
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:
- Keystroke injection at up to 890 keys/second
- 50-300 payload slots (Elite model)
- HIDX StealthLink for bidirectional tunneling
- Encrypted C2 (command and control) communications
- Geofencing triggers
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:
- Multi-function emulation: ATTACKMODE HID AUTO_ETHERNET makes it both a keyboard and network adapter
- Bash scripting: Full Linux environment means you can run nmap, responder, impacket, and other pentest tools
- Payload switch: 3-position hardware switch to select different payloads
- Exfiltration: Store gigabytes of data on internal SSD or MicroSD card
- Geofencing and remote triggers: Bluetooth LE for wireless payload triggering
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:
- Bypass USB device allowlists
- Exploit device-specific driver vulnerabilities
- Evade detection by security tools looking for known malicious device signatures
- Test how systems respond to specific device types
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:
- Activates its USB Device Controller in gadget mode
- Creates a virtual Ethernet adapter (typically using CDC-ECM, CDC-NCM, or RNDIS)
- Presents itself to the host computer as a network interface
- Runs a DHCP server to assign an IP address to the host
- 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:
- Lower latency: Direct USB connection avoids WiFi overhead
- Better security: No wireless signal to intercept; physical connection required
- Power efficiency: Phone charges while tethering; no WiFi radio drain
- Higher throughput: USB 2.0/3.0 can exceed WiFi speeds in practice
- No discovery needed: Automatically recognized; no password entry
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, DoH, 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:
- Keyboard & Mouse (/dev/hidg0, /dev/hidg1): Emulate HID input devices for automation or testing
- FIDO CTAP (/dev/hidg0): Act as a WebAuthn/FIDO2 security key for passwordless authentication
- CCID Smart Card (/dev/ccid_ctrl, /dev/ccid_bulk): Emulate a smart card reader for certificate-based authentication
- UVC Camera (/dev/video?): Present your phone's camera as a USB webcam
- Serial: Provide virtual serial ports for debugging or IoT communication
Requirements:
- Rooted Android device
- Kernel with ConfigFS support (most modern Android kernels have this)
- USB OTG-capable hardware (nearly all Android phones since ~2015)
- Companion apps for actual gadget functionality (e.g., Authorizer for FIDO CTAP)
Use cases for security professionals:
- Portable FIDO2 key: Use your phone as a hardware security token with apps like Authorizer
- Red team operations: Test physical security controls without carrying dedicated hardware
- Incident response: Quickly deploy trusted devices for forensic data collection
- Development testing: Validate USB device drivers and security controls
- Privacy protection: Disable standard USB modes (MTP, ADB) that might expose data
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:
- RNDIS mode for Windows
- CDC-ECM mode for macOS/Linux
- Internet Connection Sharing (ICS) detection for internet access
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:
- ecm: CDC Ethernet Control Model (Linux/macOS)
- rndis: Remote NDIS (Windows)
- ncm: Network Control Model (newer standard)
- eem: Ethernet Emulation Model
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:
- Locking the screen when the cable is removed
- Encrypting or deleting sensitive data
- Sending alerts to security teams
- Triggering system shutdown
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 Removal 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:
- Immediate system shutdown
- Disk encryption key deletion
- Secure file wiping
- Logging and alerting
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:
- Monitor USB device connection/removal
- Switch monitor inputs via DDC/CI or HDMI-CEC
- Configurable per-device behavior
- Cross-platform support (Linux, macOS, Windows)
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:
- Multiple device functions appearing simultaneously
- Device enumeration taking longer than expected
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:
- A "keyboard" that also creates a network interface
- Storage devices with unusual vendor/product IDs
- Devices that change behavior after initial enumeration
- USB devices with serial numbers that look like MAC addresses
Mitigation Strategies
Defending against USB gadget-based attacks requires defense in depth—combining physical security, technical controls, and user awareness.
Physical security:
- Use USB port locks or epoxy for sensitive systems
- Implement strict device control policies
- Never plug in unknown USB devices or cables
- Use USB data blockers ("USB condoms") for charging-only scenarios
- Consider portless designs for high-security environments
- Track and inventory all authorized USB devices
See NIST SP 1334 for formal guidance on portable storage media in particular.
Technical controls:
# 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
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.
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:
- KEYSTROKE_WINDOW: Number of keystrokes analyzed (default: 5)
- ABNORMAL_TYPING: Inter-keystroke timing threshold in microseconds (default: 50000µs = 50ms)
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:
- Open-source hardware design with available schematics
- Configurable filtering policies
- LED indicators for connection status
- Works with keyboards, mice, mass storage devices by default
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:
- Pre-configured filtering rules
- Logging and alerting capabilities
- Physical tamper detection
- Enterprise support options
Monitoring and Detection
- Log all USB device connections with timestamps and user context
- Alert on new vendor/product ID combinations
- Monitor for network interfaces appearing on USB (potential PoisonTap)
- Use EDR solutions that detect keystroke injection patterns (unusually fast typing, scripted sequences)
- Implement USB device fingerprinting beyond VID/PID (timing analysis, power consumption)
- Deploy honeypot USB ports that alert on any connection
Network-Level Defenses (for PoisonTap)
- Use HTTPS exclusively with Secure flag on cookies
- Implement HSTS (HTTP Strict Transport Security) with preload
- Use Subresource Integrity (SRI) for external scripts
- Deploy Content Security Policy (CSP) headers
- Close browsers when stepping away from locked machines
- Consider encrypted sleep modes that clear network state
- Use DoH or DoT to prevent DNS hijacking
Organizational Policies
- Train employees on USB security risks
- Implement "no found USB devices" policies
- Provide approved, tracked USB devices for legitimate needs
- Include USB attacks in red team exercises
- Regularly audit USB device connection logs
Limitations and Practical Considerations
While USB gadget mode is powerful, it has important limitations that affect both attackers and defenders.
Hardware Limitations:
- Not all Linux devices support gadget mode: You need specific hardware with a USB Device Controller (UDC) that supports peripheral mode. Most desktop PCs and laptops cannot act as USB gadgets without specialized add-on cards.
- Power constraints: USB gadgets draw power from the host. Complex gadgets running full Linux distributions may exceed power budgets, causing instability or disconnection.
- Speed limitations: USB 2.0 gadget mode is limited to 480 Mbps theoretical maximum (often less in practice). This affects data exfiltration speeds and network throughput.
- Single-role operation: Most devices can act as either host OR gadget, not both simultaneously on the same port. OTG switching requires hardware support and isn't instantaneous.
Technical Limitations:
- Driver requirements on host: The target system must have drivers for the emulated device class. While keyboards, storage, and Ethernet are nearly universal, exotic device classes may not work.
- Enumeration timing: Complex composite gadgets take longer to enumerate, which can be a detection signal. Some systems timeout or alert on slow enumeration.
- Persistent storage challenges: Gadget configurations typically don't persist across reboots without custom systemd services or init scripts.
- HID complexity: Creating convincing HID devices requires understanding USB HID report descriptors. Mistakes can trigger suspicion or cause the device to malfunction.
Detection Evasion Challenges:
- Device fingerprinting: Security tools can fingerprint USB devices beyond VID/PID, including timing characteristics, power consumption patterns, and endpoint configurations.
- Behavioral analysis: Keystroke injection tools can be detected by typing speed analysis (humans don't type 200 WPM with perfect accuracy), unnatural key sequences, or commands executed immediately after device insertion.
- Network anomalies: PoisonTap-style attacks create unusual network configurations that can be detected by monitoring DHCP requests, routing table changes, or unexpected network interfaces.
- Physical inspection: Modified cables and devices often have subtle physical differences (slightly thicker connectors, unusual weight, heat generation) that trained personnel can spot.
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.
- Authorization required: Always obtain written permission before testing USB attacks on any system
- Scope limitations: Define clear boundaries for what systems and data can be accessed
- Data handling: Have protocols for handling any data accidentally accessed during testing
- Disclosure: Follow responsible disclosure practices if you discover vulnerabilities
The Arms Race Continues
USB security is an ongoing arms race. As detection methods improve, so do evasion techniques. Recent developments include:
- USB Type-C authentication: The USB-C specification includes optional cryptographic authentication to verify cable and device authenticity, though adoption remains limited.
- Hardware-based USB firewalls: Devices like USB Sentry and various USB firewall products sit between the USB device and host, blocking unauthorized commands while allowing legitimate traffic.
- Machine learning detection: Research into using ML to detect anomalous USB behavior based on timing, power, and traffic patterns.
- Open-source hardware verification: Projects like the DEF CON 34 badge demonstrate that fully inspectable, open-source USB devices are possible, raising the bar for supply chain security.
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:
- An embedded developer building the next IoT device
- A security professional defending against physical access attacks
- A hobbyist exploring Linux's capabilities
- A red teamer testing organizational resilience
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:
- BadUSB research: srlabs.de/blog/usb-peripherals-turn
- Black Hat 2014: blackhat.com/us-14/briefings.html
- Hak5 Bash Bunny: shop.hak5.org/products/bash-bunny
- Hak5 Keystroke Reflection: documentation.hak5.org
- Hak5 O.MG Cable Overview: YouTube
- Hak5 O.MG Cable: shop.hak5.org/products/omg-cable
- Hak5 USB Rubber Ducky: documentation.hak5.org/hak5-usb-rubber-ducky
- PoisonTap: github.com/samyk/poisontap and samy.pl/poisontap
Legitimate Use Cases:
- Authorizer (FIDO2 for Android): github.com/tejado/Authorizer
- BeagleBone boards: www.beagleboard.org
- DEF CON 34 badge background: www.wired.com/story/defcon-34-badge-baochip-andrew-bunnie-huang
- DEF CON 34 badge: defcon.org/34b
- F-Secure USB armory: inversepath.com/usbarmory
- GitHub user tejado: github.com/tejado
- Make your own USB storage: popovicu.com/posts/make-your-own-usb-storage-embedded-linux
- Raspberry Pi USB gadget mode: raspberrypi.com/news/usb-gadget-mode-in-raspberry-pi-os-ssh-over-usb
- USB Gadget Tool (Android): github.com/tejado/android-usb-gadget
- USB tethering from iPhone to Linux: https://rtech.support/guides/usb-tethering/#iphones-with-linux
- Xous core FIDO2 implementation: https://github.com/betrusted-io/xous-core
- rpi-usb-gadget GitHub: github.com/raspberrypi/rpi-usb-gadget
USB-Triggered Actions:
- BusKill: Wikipedia
- USBKill: Wikipedia
- display-switch: github.com/haimgel/display-switch
- rfkill documentation: wireless.docs.kernel.org
- udev: wiki.archlinux.org/title/Udev
Detection and Defense:
- Google UKIP: opensource.googleblog.com/2020/03/usb-keystroke-injection-protection.html
- NIST SP 1334: csrc.nist.gov/pubs/sp/1334/final
- UKIP GitHub: github.com/google/ukip
- USB Qubes: doc.qubes-os.org/en/development/user/advanced-topics/usb-qubes.html
- USB Sentry: www.atcorp.com/r-and-d/usbsentry
- USBGuard: usbguard.github.io
- USG (USB Security Gateway): github.com/robertfisk/USG/wiki
- USG background: boingboing.net/2017/03/02/countermeasures.html
- usbauth man page: manpages.ubuntu.com/manpages/resolute/man8/usbauth.8.html
- usbauth: github.com/kochstefan/usbauth-all
Linux Kernel Documentation:
- Gateworks Linux OTG: https://trac.gateworks.com/wiki/linux/OTG
- Toradex USB device mode guide: developer.toradex.com
- USB gadget API: docs.kernel.org/driver-api/usb/gadget.html
- USB gadget ConfigFS: docs.kernel.org/usb/gadget_configfs.html
Wikipedia References:
- Air gap (networking): en.wikipedia.org/wiki/Air_gap_(networking)
- Andrew "bunnie" Huang: en.wikipedia.org/wiki/Andrew_Huang_(hacker)
- BadUSB: en.wikipedia.org/wiki/BadUSB
- CCID smart card: en.wikipedia.org/wiki/CCID_(protocol)
- CDC ACM: en.wikipedia.org/wiki/USB_communications_device_class
- Computer Fraud and Abuse Act (CFAA): en.wikipedia.org/wiki/Computer_Fraud_and_Abuse_Act
- ConfigFS: en.wikipedia.org/wiki/Configfs
- DHCP: en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol
- DNS over HTTPS (DoH): en.wikipedia.org/wiki/DNS_over_HTTPS
- DNS over TLS (DoT): en.wikipedia.org/wiki/DNS_over_TLS
- DNS rebinding: en.wikipedia.org/wiki/DNS_rebinding
- EDR: en.wikipedia.org/wiki/Endpoint_detection_and_response
- Ethernet over USB: en.wikipedia.org/wiki/Ethernet_over_USB
- FIDO CTAP: en.wikipedia.org/wiki/Client_to_Authenticator_Protocol
- FIDO2: en.wikipedia.org/wiki/FIDO2_Project
- Firmware: en.wikipedia.org/wiki/Firmware
- HTTP Cookies: en.wikipedia.org/wiki/HTTP_cookie
- IPv4: en.wikipedia.org/wiki/IPv4
- Internet Connection Sharing (ICS): en.wikipedia.org/wiki/Internet_Connection_Sharing
- Keystroke Logging: en.wikipedia.org/wiki/Keystroke_logging
- PS/2 port: en.wikipedia.org/wiki/PS/2_port
- Raspberry Pi: en.wikipedia.org/wiki/Raspberry_Pi
- Side-channel attack: en.wikipedia.org/wiki/Side-channel_attack
- TOTP authenticator: en.wikipedia.org/wiki/Time-based_one-time_password
- USB HID: en.wikipedia.org/wiki/USB_human_interface_device_class
- USB On-The-Go (OTG): en.wikipedia.org/wiki/USB_On-The-Go
- USB mass storage: en.wikipedia.org/wiki/USB_mass_storage_device_class
- USB-C: en.wikipedia.org/wiki/USB-C
- USB: en.wikipedia.org/wiki/USB
- WebAuthn: en.wikipedia.org/wiki/WebAuthn