PolterHID

A deliberately limited MicroPython awareness-training firmware for an ESP32 USB stick. On boot, it presents as a USB keyboard/mouse and, at independently random intervals, sends only:

  • one Return key press and release; and
  • a one-pixel relative mouse movement.

The authenticated web page also provides manual Volume up and Volume down controls for a clearly observable, non-destructive HID demonstration.

A password-protected local web page changes the enabled event types and their timing. The device connects to one preconfigured Wi-Fi network; it does not create an access point.

Hardware and firmware requirement

This needs an ESP32-S2 or ESP32-S3 board/stick whose USB connector is wired to the chip's native USB peripheral. A classic ESP32 with a CP210x/CH340 USB-to-serial adapter cannot act as a USB HID device.

Flash a current MicroPython build for that exact board which provides machine.USBDevice. Check at the REPL:

from machine import USBDevice

If that import fails, use an up-to-date native-USB MicroPython build for the board. This project uses the custom USB-device API and does not work with CircuitPython's usb_hid API.

Install

  1. Copy settings.example.json to the device filesystem as settings.json and replace all three credentials. Do this before first boot: the firmware cannot join Wi-Fi with the placeholder defaults.
  2. Copy main.py, hid.py, settings.py, and web.py to the device root filesystem.
  3. Reset the board and plug its native USB connector into the demonstration host.
  4. Once it joins Wi-Fi, visit http://polterhid.local/. If the client/network does not support mDNS, find the device IP address in the training Wi-Fi DHCP leases and visit http://DEVICE_IP/ instead.
  5. Sign in with username admin and the web_password from settings.json.

main.py runs automatically after boot in MicroPython. It advertises the HTTP page through mDNS as polterhid.local; this requires a MicroPython ESP32 build containing the mdns module. Configuration saved in the web page is retained in settings.json and takes effect immediately.

Operational safeguards

  • Change the example credentials before deployment. HTTP Basic authentication and all form data, including the password, are unencrypted because this intentionally has no TLS. Use an isolated/trusted training Wi-Fi network.
  • The page provides an immediate Enable all injection switch. Turn it off before handing the device to anyone or ending a session.
  • This firmware intentionally has no shell commands, keystroke payloads, text injection, storage emulation, Wi-Fi scanning, AP mode, or remote firmware-update endpoint.
  • Test first on a dedicated demonstration machine. The configured defaults are intentionally infrequent but still cause a Return and minimal mouse movement.

USB implementation note

hid.py exposes one composite HID interface with keyboard report ID 1, mouse report ID 2, and Consumer Control/media report ID 3 (Volume up/down). It queues reports while the endpoint is busy and discards a transfer if the host disconnects, avoiding stale events being replayed after a reconnect.

S
Description
PolterHID is a harmless ESP32-S3 HID awareness trainer that demonstrates the risks of untrusted USB devices using randomized Return/mouse events, Wi‑Fi controls, mDNS, display animations, and RGB feedback.
Readme
66 KiB
Languages
Python 100%