From Conference Badge to Remote Keystroke Injector
A free conference badge turned out to be a fully-featured ESP32S3 development board. Here's how I turned it into a Wi-Fi-controlled keystroke injection device — and what that means for physical security.
Unlikely Origins
It started with a hardware shortage. I had run out of microcontrollers and was rooting around for a project when I picked up one of those electronic conference badges we'd been given at a recent event. A closer look stopped me cold — the microcontroller on the badge was a dead ringer for a development module I already had on my bench.
Turned out they were identical: an ESP32S3 WROOM-1. The badge already had everything I needed to start a project right out of the box.
Before writing a single line of code, use the continuity/diode mode on a multimeter to trace which physical pins on the badge correspond to the OLED's SDA and SCL lines, and to your buttons. Cross-reference with the datasheet to get the actual GPIO numbers.
Phase 1 — Hardware Password Manager
My original goal was simple: build a hardware password manager. Our work logins at the time required 16-character passwords with uppercase, lowercase, and special characters. Nobody was memorising those. I figured: if I can't remember 16 characters, I certainly can't remember 32 or 64 — but the ESP32 can.
The key insight is that the ESP32-S3 can masquerade as a USB HID keyboard. To the host computer, it looks exactly like a keyboard plugged into a USB port. From there the sketch logic is straightforward:
-
Button A — cycle entries
Increments an index through a pre-configured array of credentials, showing the selected label on the OLED screen.
-
Button B — inject selected entry
Calls
Keyboard.print()with the string at the current index, typing it into whatever field has focus on the host machine. -
OLED feedback
Shows the currently selected credential name so you know which entry you're about to inject — without displaying the actual secret.
Getting set up is straightforward. Download the Arduino IDE, add the ESP32 board package, and pull up the USB keyboard example sketch. AI assistants like Claude or ChatGPT can generate a useful starting framework — just expect several iterations before it compiles cleanly and behaves correctly on real hardware.
You can also use Espressif's esptool.py to read chip metadata before flashing:
# Identify chip variant and available flash esptool.py --port /dev/ttyUSB0 --baud 115200 flash_id
Phase 2 — Going Remote (The "Evil Keyboard")
Once the local password manager worked, the next question was obvious: the badge has Wi-Fi — why does someone need to physically press a button? Why not control it over the network?
The answer is what I ended up calling a remote evil keyboard. The architecture is simple but effective:
-
ESP32 connects to Wi-Fi
On boot the badge joins a specified SSID and acquires an IP address.
-
Async web server starts
An ESPAsyncWebServer instance serves a minimal HTML interface on port 80. The page has a text field and a send button.
-
Attacker types — victim receives
Text submitted through the web UI is received by the ESP32 over Wi-Fi, then injected keystroke-by-keystroke via the USB HID interface into whatever application has focus on the connected computer.
-
OTA updates
ArduinoOTA is enabled, so the firmware can be updated over the air without ever touching the device physically again.
From the target computer's perspective, this is indistinguishable from a legitimate USB keyboard. There is no OS-level prompt, no driver installation, and no indication that the input is being injected remotely. This is precisely why physically uncontrolled USB ports on production machines are a meaningful attack surface.
"We can use computer A to type into computer B, and the target machine sees it as just a hardware keyboard plugged in. Nothing weird going on."
Miniaturisation & Concealment
The obvious limitation of the badge form factor is that it's conspicuous. A conference badge dangling from a USB port raises questions. That's where miniaturisation comes in.
The Seeed Studio XIAO ESP32-S3 is functionally equivalent to the badge's ESP32-S3, but it's roughly the size of a thumbnail. Anything the full badge can do, the XIAO can do — with a footprint small enough to conceal in a wide variety of enclosures or objects.
The same pin-tracing methodology applies: use continuity mode on a multimeter and the chip's datasheet to identify I2C (SDA/SCL) and GPIO lines. Solder on press-fit headers and you can connect peripherals like OLED screens, NFC readers, or sensor modules.
Other Directions
The keystroke injector is just one application. The ESP32's combination of USB HID emulation, Wi-Fi, Bluetooth, and abundant GPIO opens up a wide range of other builds — a few others explored in this session:
-
Battery-powered NFC card skimmer
An ESP32 reads NFC card UIDs and publishes them to a local web interface. Placed near a door reader, it captures card data from unsuspecting employees who assume they need to badge in. Depending on the card technology, captured data can potentially be cloned.
-
Presence / heartbeat sensor
An X-band radar module detects breathing and heartbeat through walls. Demonstrated here as a home automation trigger, but the underlying sensing capability has broader applications.
-
ESPHome integration
For less adversarial use cases, the ESP32 ecosystem integrates natively with Home Assistant via the ESPHome project — a rich source of inspiration for legitimate IoT builds.
ESP32-S3 boards are inexpensive, ubiquitous, and capable. They can emulate USB keyboards, host web servers, communicate over Wi-Fi and Bluetooth, and talk to a huge range of I2C/SPI peripherals — all from a chip that can be hidden almost anywhere. If you're doing physical penetration testing, understanding this attack class is becoming table stakes.