Waveshare ESP32-S3-Touch-AMOLED-1.8 · Wi-Fi research tool
BadAP turns an ESP32-S3 into a wrist-worn access point that answers every DNS, HTTP, HTTPS, NTP, and mail request a connected client throws at it — and quietly logs the rest. On the wrist, it just tells the time.
Tap the watch 5 times quickly to unlock the log view — exactly like the real device.
Overview
Boot it, and it starts an open (or WPA2) Wi-Fi network. Anything that joins gets DNS answers that all point back to the device, a web server that says "200 OK" to everything, and fake DNS-over-TLS, NTP, and mail servers that log whatever a client tries before rejecting it. Everything that can't be answered convincingly is still listened to and logged.
DNS, HTTP, HTTPS/TLS, DNS-over-TLS, NTP, POP3, IMAP, and SMTP all get a real-enough reply so the client keeps talking — every hostname, path, and credential attempt is captured on the way past.
mDNS, SSDP, LLMNR, NBNS, WS-Discovery, and STUN are logged without a reply, so device discovery chatter and STUN binding requests show up without the sinkhole ever interacting.
Every event lands on the AMOLED log, Serial, the SD card (if present), and a live view on the web dashboard — simultaneously, no configuration required.
Every sinkhole and listener is a toggle in an on-device settings menu, written back to /sinkhole_config.txt on the SD card.
Protocols
| Service | Port | Behavior |
|---|---|---|
| DNS sinkhole | UDP/53 | Resolves every query to the AP's own IP address. |
| HTTP sinkhole | TCP/80 | Replies "200 OK" to anything, or serves real files from /www on the SD card, falling back to /www/index.html for unmatched paths — captive-portal style. |
| HTTPS / DoT sinkhole | TCP/443, TCP/853 | Reads the ClientHello, logs the SNI hostname, then drops the connection — unless a valid cert.pem + key.pem pair is on the SD card, in which case port 443 performs a real self-signed TLS handshake so a browser's own trust warning can be checked. |
| NTP sinkhole | UDP/123 | Replies with a structurally valid time packet, using the onboard RTC if it's been set. |
| POP3 / IMAP / SMTP sinkhole | TCP/110, 143, 25 | Speaks just enough of each greeting/AUTH exchange to prompt a client for credentials, logs what's sent, then rejects the login. Plaintext auth (USER/PASS, LOGIN, AUTH PLAIN/LOGIN) is flagged distinctly from challenge/response methods like APOP or CRAM-MD5. |
| mDNS / SSDP passive | UDP/5353, UDP/1900 | Logs multicast discovery traffic without answering. |
| LLMNR / NBNS passive | UDP/5355, UDP/137 | Logs legacy Windows name-resolution broadcasts without answering. |
| WS-Discovery passive | UDP/3702 | Logs device-discovery probes without answering. |
| STUN passive | UDP/3478 | Logs NAT-traversal binding requests without answering. |
On-device UI
Word-wrapped, colour-coded by protocol, and touch-scrollable — drag up to review history, drag down to catch up, and it auto-follows new lines when you're at the bottom. A side scrollbar thumb shows roughly where you are.
Both bars sit inset from the edges to clear the panel's own rounded corners. The header carries the title, a live UTC clock, and battery; the footer carries the connected client count and an explicit Settings button.
A scrollable list of on/off pill toggles — one per sinkhole or listener — reached from the header or the footer's Settings button. Back and Save config live as fixed footer buttons, reachable from anywhere in the list.
A tap toggles the screen on or off — debounced, and everything keeps sinkholing while the screen is dark. A 6-second-plus hold is still a full hardware power-off regardless of what the sketch is doing.
Stealth mode
When the stealth clock face is on (the default), every screen wake shows a plain analog watch face — no branding, no log, nothing that reads as a research tool. Five taps anywhere on the screen, in quick succession, switch through to the real log view. A single tap, or five taps spread too far apart, does nothing visible.
Turning the screen off and back on with the PWR button always returns to the clock face, so it's never left showing mid-scroll logs. Anything that happened while locked keeps logging in the background — nothing is lost, it's just not on screen.
It's one row in the settings menu — clockface in the config file — so it can be turned off entirely if you'd rather the screen wake straight into the log, same as before.
Web dashboard
A lightweight dashboard runs on TCP/7777, streaming the same events shown on-device to anyone browsing to the AP's address. It also doubles as the easiest way to set the onboard RTC — punch in a time manually, or sync it to whatever clock the browsing device already has.
Configuration
/sinkhole_config.txt on the SD card holds every flag as a simple key=1 / key=0 line. It's created with sensible defaults on first boot, editable by hand, or entirely from the on-device settings menu.
cert.pem/key.pem on port 443 before falling back to sniff-only./www from the SD card.The access point itself defaults to SSID Research with password 12345678 — both editable in the same config file.
Setup
Install XPowersLib and SensorLib (both by lewisxhe) via the Arduino Library Manager, plus pin_config.h and GFX_Library_for_Arduino from Waveshare's example package for the ESP32-S3-Touch-AMOLED-1.8.
In Arduino IDE: Tools → USB CDC On Boot → Enabled. Everything else can stay at its default.
Drop in /www to serve real files from the HTTP sinkhole, or cert.pem + key.pem to give the HTTPS sinkhole a real handshake. Neither is required — the device works from a blank card, or none at all.
Compile and upload. On first boot it writes a default /sinkhole_config.txt to the SD card (if present) and starts the Research access point.
Connect a test device to the AP. DNS, HTTP, and passive-listener traffic starts appearing on screen, on Serial, and on the port-7777 dashboard immediately.
Use responsibly
This is a traffic-interception tool. Only point it at networks and devices you own, or have explicit written permission to test. Capturing credentials or traffic from anyone else's device without consent is illegal in most jurisdictions.