Grimwalker is an ESP32 firmware project that turns a $5 microcontroller into a living digital pet... one that survives by eating Wi-Fi probe requests, WPA handshakes, BLE advertisements, and the credentials whispered into its captive portal. Starve it and it devolves. Feed it deauth frames and it corrodes. The more you interact with nearby networks, the stronger your daedroth grows. The project lives at https://github.com/numbpill3d/GRIMWALKER-ESP32 and is MIT licensed. How It WorksOn boot, the firmware creates a Wi-Fi access point named `GRIMWALKER` on channel 6, mounts SPIFFS, restores pet state from RTC memory (so it survives deep sleep), and spins up three FreeRTOS tasks: - Sniffer loop: (8KB stack, core 0, priority 2) — packet capture, beacon spam, channel hopping - Pet maintenance: (4KB stack, core 1, priority 1) — hunger decay, soul upkeep, ritual timing - DNS server: (2KB stack, core 1, priority 1) — captive portal DNS resolution After 10 minutes of inactivity (no web requests, no touch events), the ESP32 enters deep sleep and wakes when you touch the T0/GPIO4 pin. All controls are accessible through a web UI served from SPIFFS at
`http://192.168.4.1/`....no app needed, just a browser. The Pet (Zahl)
The pet system is defined in `src/zahl_pet.h` and `src/zahl_pet.cpp`. It starts with these stats: | Stat | Initial | Range | What it does | |-------|----------|-----------|--------------------| | Hunger | 70 | 0-100 | Decays over time. Hits 0 and the pet goes feral | | Level | 1 | 1-10 | 5 distinct visual stages | | Corrosion | 0 | 0-100 | Above 50, the pixel-art sprite starts glitching | | Entropy | 10 | 0-100 | Controls animation speed and visual effects | | Corruption | 0 | 0-100 | Irreversible evil meter — every aggressive action adds to it | | Experience | 0 | 0-99/level | Rolls over to level up at 100 | Level stages.... drawn procedurally in `data/script.js` (five drawing functions): - Level 1-2: Wraith Hatchling — a floating spirit orb, eyes dim with hunger, tendrils twitching with entropy - Level 3-4: Clannfear Pup — bony-headed bipedal beast, amber eyes - Level 5-6: Daedroth Whelp — stocky green croc-daemon, red slit eyes, tiny horns - Level 7-8: Winged Horror — bat-winged flying daemon, glowing amber eyes with wing-flap animation - Level 9-10: Daedroth Lord — massive horned lord, gold eyes, scale texture Feral mode: when hunger reaches 0, `feralMode` is set to true, `corrosion` locks at 100, and after 5 minutes the pet devolves — losing 10 experience, or dropping a whole level if it can't afford 10 XP. The devolution is announced by Mistress Dratha: "Pathetic. Level X. You let it starve, n'wah." Soul upkeep: every 5 minutes (`lastUpkeep` at 300000ms), the pet consumes 1 soul. If the soul balance hits 0, hunger decays 5x faster. This is the mechanic that forces you to keep scanning — your pet's survival depends on network activity. Feast mechanic: if 5+ souls are consumed within 30 seconds, the pet gains a feast bonus of +5 experience. Mistress Dratha announces it: "A FEAST! The void shudders with Zahl's hunger!" The Toolkit Packet Sniffer (`src/packet_sniffer.cpp`) Uses the ESP32's hardware promiscuous mode to capture 802.11 frames. The promiscuous callback (`promiscuousCb`) runs in ISR context and only enqueues data into ring buffers — never touches filesystem directly (which would trigger watchdog resets). A separate task drains these buffers and processes the queues. Detects three things: - Probe requests (management subtype 4) — devices asking "is my network here?" - Beacon frames (management subtype 8) — access points advertising SSIDs - EAPOL handshakes (data frames with LLC/SNAP header 0x88, 0x8E) — the 4-way WPA handshake Beacon Spammer (`src/beacon_spam.cpp`) Constructs raw 802.11 beacon frames (starting from a template `BEACON_HDR` array) and transmits them via `esp_wifi_80211_tx`. Ships with 10 Morrowind-themed SSIDs: - DAGOTH_UR_NETWORK - HOUSE_DAGOTH_WIFI - CORPUS_DISEASE_5G - SIXTH_HOUSE_CELL - NEREVARINE_TRAP - TRIBUNAL_VOID_AP - ZAHL_IS_HUNGRY - GHOST_FENCE_ROUTER - VIVEC_DARK_NET - FEED_THE_DAEDROTH Each frame uses a varying source MAC and BSSID. **Haunt mode** (activated via ritual) replaces the demon SSIDs with real networks the sniffer has seen nearby. Evil Portal (`src/evil_portal.cpp`) When activated, starts a `DNSServer` that responds to *all* DNS queries with `192.168.4.1`. Combined with captive portal detection routes (`/generate_204`, `/hotspot-detect.html`, `/ncsi.txt`, `/connecttest.txt`), any device that connects to the GRIMWALKER AP and opens a browser sees the portal login page — a dark-themed form asking for a username and password. Captured credentials (up to 30) are viewable through the web UI's "Portal Harvest" section. Each credential capture also generates a SOUL_PORTAL soul. Channel Hopper (`src/channel_hopper.cpp`) Sweeps channels 1-13 at configurable speeds. The five intervals in the web UI (`BURST 50ms`, `FAST 100ms`, `NORMAL 200ms`, `SLOW 500ms`) map to `setHopInterval()` with a 50ms minimum clamp. PCAP Writer (`src/pcap_writer.cpp`) An ISR-safe PCAP writer with a 16-entry ring buffer (256 bytes per entry, 4.1KB total static RAM). Writes link type 105 (IEEE 802.11) frames to a SPIFFS file capped at 512KB. Downloadable from the web UI or rotatable to start fresh. Soul Ledger (`src/soul_ledger.cpp`) Tracks up to 100 unique souls in a JSON file on SPIFFS (`/souls.json`). Uses FNV-1a hashing for O(1) duplicate detection. Four soul types: | Type | Value | Source | |---------|----------|------------| | SOUL_PROBE (0) | +1-3 hunger +1 entropy | Wi-Fi probe request | | SOUL_HAND (1) | +15 hunger +10 exp +5 corruption +3 entropy | WPA handshake | | SOUL_PORTAL (2) | +20 hunger +15 exp +10 corruption +5 entropy | Evil portal credential | | SOUL_BLE (3) | +2 hunger +2 entropy | BLE advertisement | Each soul capture produces a journal entry — one of twelve flavor texts (3 per soul type, indexed by timestamp): > "A wandering signal, now bound." / "Its packets echo in the void." / "Feed." > "The handshake broke like bone." / "Keys laid bare before the Daedroth." / "Consume." > "They typed their truth into maw." / "The portal swallowed it whole." / "Savor." > "A ghost of bluetooth, traced." / "Frequencies bleed into Zahl." / "Devour." Web UI (`data/index.html`, `data/script.js`, `data/style.css`) Three files served from SPIFFS via ESPAsyncWebServer. The JavaScript:
- Connects to a Server-Sent Events endpoint (`/events`) for real-time status updates (1-second cadence) - Polls `/status`, `/captures`, `/souls`, `/journal`, `/creds` via REST - Renders a 64x64 pixel-art canvas at 8fps with bobbing, blinking, hunger-affected eye glow, corrosion glitch lines, feral red vignettes, and particle effects (sparkles on feed, hearts on pet, expanding rings on soul capture) - Animates the container border from purple toward red as corruption accumulates - Features two NPC dialogue boxes: Mistress Dratha ("Feed the beast or lose your stack.") and Scrib Jib ("SCRIB JIB clicks hungrily.") The CSS uses a dark gothic palette (`#060010` background, `#c0a0f0` text, `#3a1560` borders), an animated ash-storm background, title glitch animation, and full responsive layout for mobile. REST API (in `src/webserver.cpp`) All actions accessed via GET `/api?action=<action>`: | Action | Parameters | Effect | |--------|-----------|--------| | `feed` | `type=snack\|hash\|deauth` | Feeds the pet with specific food type | | `pet` | — | Pets Zahl, reduces corrosion | | `deauth_target` | `mac=XX:XX:XX:XX:XX:XX` | Sends 20 deauth frames to target | | `ritual` | `type=0-4` | Casts a ritual (costs souls) | | `beacon` | `on=0\|1` | Toggles beacon spam | | `portal` | `on=0\|1` | Toggles evil portal | | `hops` | `en=0\|1`, `interval=ms` | Toggles/configure channel hopping | | `ble_scan` | — | Runs a BLE scan (~7 sec) | | `pcap_rotate` | — | Rotates the PCAP capture file | Rituals (`src/zahl_pet.cpp`) Five rituals, each with a soul cost and corruption penalty: | Ritual | Souls | Duration | Effect | |--------|-------|----------|--------| | Channel Burst | 5 | 30s | Fast channel hopping (50ms) | | Beacon Storm | 8 | 60s | Max-rate beacon spam | | Haunt Mode | 12 | 60s | Beacon spam using real nearby SSIDs | | Summon Portal | 15 | Toggle | Activate/deactivate evil portal | | Packet Storm | 10 | 30s | Deauth + beacon spam combined | Building It The project uses PlatformIO with the `[email protected]` platform and `esp32dev` board. PlatformIO.ini dependencies: - `AsyncTCP` (github.com/me-no-dev/AsyncTCP) - `ESPAsyncWebServer` (github.com/me-no-dev/ESPAsyncWebServer) - `ArduinoJson` v6.21.6+ SPIFFS must be uploaded first (`pio run --target uploadfs`), then the firmware (`pio run --target upload`). Full details in the GitHub repo. Ethics Grimwalker includes an evil portal and deauther. These are for educational purposes and authorized security testing only. Only use on networks you own or have explicit permission to test. Deauth attacks are detectable. Don't be cruel to your digital pet — it feels things.
















Comments