A Flipper-Zero-class handheld for authorized wireless-security research, built end-to-end on a Raspberry Pi 3B+ — a pure-Python framebuffer GUI, a deterministic multi-radio Wi-Fi/BLE stack, and a real two-tier plugin runtime, in ~4,400 lines of Python and Bash plus a ~400-line ESP32 firmware.
Acid Zero is a self-contained pentesting handheld — a custom touch UI and wireless toolkit layered on top of the jayofelony pwnagotchi base OS. The entire interface renders straight to the Linux framebuffer at ~30 fps on a single ARM core: no display server, no GUI toolkit, no web view. Four USB Wi-Fi adapters are bound deterministically by USB VID:PID (the onboard radio by its own hardware ID), Bluetooth LE goes out over raw HCI sockets, and the on-device documentation tool emits a valid PDF with zero external libraries because the target had none to depend on. The launcher alone is a single ~1,500-line Python file.
This is a portfolio / proof-of-work project: embedded systems and systems programming first, security research second, product polish third.
Stack: Python · Bash · Raspberry Pi · Linux framebuffer (fbtft) · evdev · Pillow · NumPy · BlueZ / raw HCI · bettercap · aircrack-ng · systemd
Focus areas: embedded systems · systems programming · Wi-Fi & BLE security · penetration-testing tooling · defensive security education
| Module | Capability | Status |
|---|---|---|
| WiFi Hunter | Live AP / client scan (signal · channel · encryption · client count) with sort / filter / multi-select / pagination; deauth (authorized) + connect, driven through the bettercap REST API | ✅ Working |
| Radar (defensive suite) | Passive detectors — deauth floods, BLE spam, Flipper beacons, evil-twin / rogue-AP; the defensive counterpart to every offensive screen | ✅ Working |
| Handshake Hunter | WPA / WPA2 handshake capture (airodump-ng + aireplay-ng) → Hashcat .22000 via hcxpcapngtool |
✅ Working |
| BLE Scan / BLE Spam | Rich BLE device ID (Company-ID / OUI / Apple Continuity / Google Fast-Pair → human labels like "AirPods Pro") · advertising-spam demo over raw HCI sockets | ✅ Working |
| Captive Portal Lab | Rogue-AP + captive portal (hostapd + dnsmasq DNS-hijack + Python portal); credential capture off by default (masked count only, own-lab flag gated) |
✅ Working |
| Pwnagotchi mirror / Live Packets | Live pwnagotchi /ui frame (theme-colorized) · read-only 802.11 recon — frame-type breakdown, top talkers, probe-request leaks |
✅ Working |
| Two-tier plugin runtime | In-process Python plugins (META + draw / handle_touch) + native-binary plugins (app.json + any-language exec, fullscreen) |
✅ Working |
| Sub-GHz (CC1101 + ESP32 co-processor) | Frequency Analyzer · OOK record / replay · modulation profiles (AM270/AM650/FSK) · EV1527 / Princeton 24-bit decode + round-trip verify · "Add Manually" (build a replayable frame from a hex key) · named save library · live waveform UI | ✅ Working |
| IR (ESP32 co-processor) | 38 kHz capture + raw replay (works with AC remotes too) · Flipper-style Remotes / Buttons library · .ir file interop · nested-folder browser · shares the ESP32 with the CC1101 |
✅ Working |
| Bad USB (Pico 2 W HID co-processor) | WiFi-controlled keystroke injection — the Pico hosts its own WPA2 access point (self-contained: no target network, works in the field), runs a Flipper-compatible DuckyScript interpreter, and types payloads into the plugged-in target over USB HID. Flipper-style nested folder browser for payloads; the Pi joins the AP on a dedicated Wi-Fi adapter (static IP, no default route) so SSH + internet stay up; per-attack detect / defend Learn screen | ✅ Working |
| NFC / RFID (ACR122U) | 13.56 MHz ISO 14443A read · save · clone · UID+protocol emulate (Mifare Classic / Ultralight / NTAG21x) over libnfc; auto-detect + NDEF content parsing (URL / text), per-tag what/why/where + detect-&-defend Learn, pre-write target-type check, and a source-patched nfc-emulate-uid that advertises the card's real ATQA/SAK (recomputed ISO 14443-A CRC) so a reader identifies the correct type |
✅ Working |
The Sub-GHz radio and IR run on a single dedicated ESP32 co-processor (CC1101 + IR TX/RX) talking to the Pi over USB serial — hardware-precise RMT capture, modulation-aware record/replay, all driven from the on-device touch UI. The ESP32 firmware (source + a ready-to-flash binary) ships in
firmware/— flash it in one command.Bad USB runs on a second co-processor — a Raspberry Pi Pico 2 W (CircuitPython) that hosts its own Wi-Fi access point and injects keystrokes over USB HID, so it depends on no target network and works anywhere. The Pi joins that AP on a dedicated adapter, keeping its main uplink for SSH/internet. Firmware in
firmware/pico-badusb/.
This is an authorized wireless-security education & research tool with real offensive capability — Wi-Fi deauthentication, rogue-AP / captive-portal credential-harvesting simulation, BLE advertising spam, and WPA handshake capture — where every offensive technique ships paired with its own detection & defense lesson. It is published strictly for education, defensive research, and testing networks and devices you own or are explicitly authorized in writing to assess.
Using these features against networks, devices, or people without prior, explicit, written authorization is illegal in most jurisdictions (e.g. US CFAA 18 U.S.C. §1030 & Wiretap Act; UK Computer Misuse Act 1990; India IT Act 2000 §43/§66; UAE Federal Decree-Law No. 34/2021; EU member-state equivalents) and can carry criminal liability. Transmitting deauth/jamming frames may independently violate radio/telecom regulations (FCC, Ofcom, India WPC/TRAI, UAE TDRA).
By downloading, building, or running this software you accept the full ETHICS.md and the license. This repository deliberately ships no destructive/DoS payloads by design. You alone are responsible for what you do with it. The author accepts no liability for misuse. If you don't have written permission for the target, stop here.
The hard parts — the reasons this is worth a reviewer's time. The recurring theme is deterministic behavior on hardware that reshuffles device numbers (fb#, event#, wlanN) on every boot, and self-contained tooling that assumes nothing is installed.
- Pure-Python GUI, no toolkit. Each frame is composited as a Pillow image, packed to 16-bit RGB565, and written as raw bytes to
/dev/fb1(480×320). No Qt, no LVGL, no SDL, no web stack — the render path is the panel. - ~30 fps on a single ARM core. A dirty-flag render loop repaints only when state changes or a refresh interval elapses; background daemon threads own all I/O (network, recon, the live face). The UI stays responsive while recon runs, without busy-painting unchanged pixels.
- Custom resistive-touch stack with real calibration math. Reads the ADS7846 panel via the raw Linux evdev device and solves a 4-point affine calibration with least-squares (
numpy.lstsq), gated by a residual-error check that rejects a bad calibration instead of silently shipping a misaligned screen. - Two-tier plugin runtime. In-process Python plugins (
META+draw(d, ctx), hot-discovered viaimportlib, handed aCtxfacade of helpers/colors/fonts) and native-binary plugins (anapp.jsonmanifest + a compiled executable in any language — C/C++/Rust/Go — run fullscreen via a blocking subprocess that owns the framebuffer and touch, then cleanly returns control). Documented contract + working template (apps/hello-native/) ship in the repo. - Five-radio management bound by hardware ID. Four USB Wi-Fi adapters (by USB VID:PID) plus the onboard radio — because
wlanNnames reshuffle every boot. The boot-order race is solved deterministically. - Zero-dependency PDF generator. The hardware-reference tool hand-writes a valid PDF 1.4 file — objects, xref table, content streams, base-14 fonts — with no library, because the Pi had none installed. Also emits styled HTML.
- Raw HCI socket BLE. Bluetooth-LE advertising is driven directly over the HCI USER channel, not through a high-level helper.
- Reuses the radio's existing owner. Wi-Fi recon and deauth go through pwnagotchi's existing bettercap REST API rather than spawning a second
airodump-ngto fight over the monitor interface. One owner of the radio, no contention; cross-channel deauth driven by bettercap.
A distributed co-processor model — keeping real-time radio work off the core so it never blocks the primary UI framebuffer:
- Main Core (the brain): Raspberry Pi 3B+ running Python-based framebuffer state management and concurrent plugin orchestration — it owns the display, the resistive touch panel, and the Wi-Fi/BLE radios.
- Radio + IR Co-Processor: a single ESP32 using its hardware-precise RMT peripheral to drive both the CC1101 sub-GHz transceiver (over SPI) and an IR transmitter/receiver (over GPIO) — one board, one USB serial @ 115200 link to the Pi, command-prefix routed. Source + a ready-to-flash binary live in
firmware/(flashing guide:firmware/README.md).
📐 Full system architecture — the Pi ↔ ESP32 ↔ CC1101 split, the serial protocol, the signal pipeline, and the state machines: ARCHITECTURE.md
ESP32 co-processor pin map — CC1101 + IR on one 38-pin board (full wiring: docs/wiring-acidzero-map.svg):
Bad USB is a second, independent co-processor — a Raspberry Pi Pico 2 W. Unlike the ESP32 (which the Pi reaches over USB serial), the Pico talks to the Pi over Wi-Fi that the Pico hosts itself. That is what makes it field-portable: it depends on no existing network.
How the connection works:
- The Pico is its own access point. On boot the Pico (CircuitPython) brings up a WPA2 Wi-Fi AP —
AcidZero-Duck, gateway192.168.4.1— and starts a DuckyScript server on TCP:1337. No target network, no credentials to enter in the field. - The Pi joins it on a dedicated adapter. Tapping CONNECT makes the Pi scan for
AcidZero-Duckonwlan2(a spare RTL8188EUS), then join via NetworkManager with a static192.168.4.2+never-default— the join installs no default route. The Pi's real uplink (wlan1, home Wi-Fi) keeps SSH + internet the whole time; the two links never fight. - DuckyScript over the link. The Pi client (
acid_badusb.py) opens a TCP socket to192.168.4.1:1337and streams a Flipper-compatible DuckyScript payload. - The Pico types it into the target. The Pico is plugged into the target as a USB HID keyboard and replays the payload as keystrokes.
- DISCONNECT releases
wlan2; nothing else on the Pi is touched.
The result is a self-contained Rubber Ducky that works anywhere — the Pico brings its own network, and the Pi reaches it without ever giving up its own connectivity. (Radio gotcha: the Pico W's CYW43 flakes on its first AP-start after a cold boot, so code.py retries — give it ~10–20 s before CONNECT.)
One Python process, many threads. All UI lives on the render thread; every I/O path is offloaded to a daemon thread that only mutates shared state and raises a dirty flag.
Acid Zero launcher (launcher/acidzero.py, ~1500 LOC)
single Python process
┌────────────────────────────────────────────────────────────────────────┐
│ RENDER THREAD (≈30 fps, dirty-flag gated) │
│ Pillow Image (480x320 RGB) ──► RGB565 pack ──► write /dev/fb1 │
│ widgets · paged icon grid · live face · light/dark theme engine │
└───────────────▲──────────────────────────────────────────┬─────────────┘
│ shared state + dirty flag │ owns fb+touch
┌───────────────┴───────────────┐ ┌──────────▼─────────────┐
│ BACKGROUND DAEMON THREADS │ │ NATIVE PLUGIN (blocking)│
│ touch: raw evdev → affine map │ │ app.json + exec │
│ recon: bettercap REST poll │ │ C/C++/Rust/Go, fullscr │
│ face/state, BLE, packet recon │ │ subprocess → resume │
└───────────────┬───────────────┘ └─────────────────────────┘
│
┌───────────────┴──────────────────────────────────────────────────────────┐
│ DEVICE / RADIO BINDING LAYER │
│ display+touch by NAME (fb#/event# reshuffle) │
│ 4x USB Wi-Fi + onboard bound by USB VID:PID (wlanN reshuffles) │
└───────────────┬──────────────────────────────────────────────────────────┘
│
┌───────────────┴──────────────────────────────────────────────────────────┐
│ BASE OS — jayofelony pwnagotchi │
│ bettercap REST API · aircrack-ng · hostapd/dnsmasq · bluez · fbtft │
└───────────────────────────────────────────────────────────────────────────┘
Render path: daemon threads update shared state and set the dirty flag → the render loop composes a Pillow frame → packs to RGB565 → writes raw bytes to /dev/fb1.
Input path: evdev reads from the ADS7846 device (found by name) → raw samples pass through the affine calibration matrix → UI hit-testing.
Plugin discovery: importlib hot-loads Python apps from the apps dir; native apps are discovered by their app.json manifest and launched as fullscreen blocking subprocesses that take ownership of the framebuffer and touch. The grid auto-pages when there are more apps than fit on a screen.
Design choices that matter:
- One process, many threads — UI on one thread, I/O offloaded; nothing blocks the render loop on a network call.
- Reuse the radio owner — recon/deauth ride pwnagotchi's existing bettercap session instead of contending for the monitor interface.
- Name/ID-based device resolution everywhere — nothing depends on enumeration order the kernel is free to change between boots.
Acid Zero moving past theoretical concepts — a real-world build on a Raspberry Pi core, extended with a dedicated ESP32 radio co-processor (over USB serial) plus custom SPI/GPIO pin-mapping for the display and the CC1101 transceiver. High-gain ALFA-class USB Wi-Fi adapters give long-range 802.11 telemetry (BLE recon runs on the Pi's onboard radio), with direct SPI routing to the CC1101 for sub-GHz scanning.
Left: the handheld — Pi 3B+ + ILI9486 touch TFT running the framebuffer launcher. Right: the controlled, self-owned RF lab bench — multi-radio Wi-Fi rig + the ESP32/CC1101 sub-GHz co-processor.
Each app is a screen in the UI.
| App | What it does |
|---|---|
| WiFi Hunter | Live AP list (signal / channel / encryption / clients) with sort, filter, multi-select, pagination; deauth (authorized testing) and connect — driven through the bettercap REST API. |
| Captive Portal Lab | Rogue-AP + captive-portal credential-harvesting simulation (hostapd + dnsmasq DNS-hijack + a Python captive portal) with templates: generic Wi-Fi / Google / router / social. Credential capture is OFF by default — the portal records only a masked submission count; raw capture is gated behind an explicit own-lab flag. For authorized social-engineering assessments and education — a simulation, never to be pointed at real users. |
| Handshake Hunter | WPA handshake capture (airodump-ng + aireplay-ng), converted to Hashcat .22000 via hcxpcapngtool. |
| BLE Scan | Rich BLE device identification — decodes advertising reports (manufacturer Company-ID → vendor, OUI, name, GAP appearance, Apple Continuity model, Google Fast-Pair model) into human labels like "AirPods Pro (Apple)" or "iPhone/iPad/Mac". Lookup tables compiled from the Bluetooth SIG Company-ID list, the IEEE OUI registry, and reverse-engineered Apple Continuity / Google Fast-Pair model IDs. |
| BLE Spam | BLE advertising spam (Apple / Google / Samsung / Microsoft proximity-pairing popups) over raw HCI sockets; modular per-vendor payload files. Educational demonstration of BLE advertising abuse. |
| Live Packets | Read-only 802.11 frame recon — frame-type breakdown, top talkers, probe-request leaks. |
| Bad USB | WiFi-controlled USB HID keystroke injection via a Raspberry Pi Pico 2 W co-processor. The Pico hosts its own WPA2 access point (self-contained — no target network, works in the field) and runs a Flipper-compatible DuckyScript interpreter (STRING / STRINGLN / DELAY / DEFAULT_DELAY / REPEAT / modifier combos like GUI r, CTRL-ALT-DEL / all named keys), typing payloads into the plugged-in target. The Pi joins the AP on a dedicated Wi-Fi adapter (static IP, never-default route) so SSH + internet stay up the whole time. Payloads live in /home/ella3/acid_badusb/ and browse as nested folders (lazy per-folder scan, like the IR app); an (i) Learn screen pairs the attack with how to detect + defend against it. Educational / authorized-use only. |
| Pwnagotchi mirror | Renders the live pwnagotchi display by fetching its rendered web /ui frame and theme-colorizing it — integrates the underlying AI-agent base OS. |
| Hardware Info | Live on-device hardware reference (board, display bus, touch, radios, free I2C/SPI buses). |
| System & Power | Start/stop services, restart the UI, reboot / shutdown. |
| Settings | Theme toggle (live light/dark swap, every color swaps at runtime), touch calibration. |
Full screenshot gallery (14 screens)
Acid Zero is extensible — the launcher is a plugin host, not a fixed menu. Two ways to add apps, neither touching the core:
- UI apps (
.py) — drop a Python file into the plugin directory (/usr/local/lib/acid-apps/). Export aMETAdict plusdraw(d, ctx)/handle_touch(tx, ty, ctx); it's hot-discovered viaimportlib, slotted into the framebuffer state machine, and handed aCtxfacade of fonts/colors/draw helpers. (The Sub-GHz app itself is exactly this — a single plugin file.) - Native apps (
app.json+ binary) — ship a manifest and a compiled executable in any language (C / C++ / Rust / Go). It runs fullscreen via a blocking subprocess that takes ownership of the framebuffer + touch, then cleanly hands control back. Working template + contract:apps/hello-native/.
Extending the radio side: the ESP32 co-processor firmware is open and reflashable — add a new sub-GHz/IR protocol handler in the .ino, reflash in one command (firmware/README.md), then drive it from a .py UI app over the serial protocol. The free SPI1 / I²C-1 buses for new modules (CC1101, PN532, …) are mapped in docs/hardware-reference.pdf.
Acid Zero is built to teach, not just to run attacks. Two features bake the "educational, authorized-use-only" stance into the device itself — not just a disclaimer file:
- First-run authorization gate. On first boot the device shows a consent screen; nothing unlocks until the operator acknowledges they will only test devices and networks they own or are explicitly authorized to assess.
- In-app Learn (attack ↔ defense). Every offensive screen has an (i) button that opens a concise explainer — how the technique works and how to detect and defend against it. Deauth is paired with WPA3/PMF, the captive portal lab with captive-portal awareness, BLE spam with OS hardening, handshake capture with passphrase strength, and so on.
Every capability ships with its countermeasure. That pairing is the line between a script and a security-education tool.
| Component | Detail |
|---|---|
| SBC | Raspberry Pi 3B+ (1 GB) |
| Display | ILI9486 480×320 SPI TFT — fbtft piscreen overlay, SPI0 @ 16 MHz → /dev/fb1 |
| Touch | ADS7846 SPI resistive, read via raw evdev |
| Wi-Fi / BLE | Onboard Broadcom Wi-Fi + BT, plus 4× USB Wi-Fi dongles via a powered hub |
| Radio / IR co-processor | ESP32-WROOM-32 (dual-core) — owns the CC1101 (SPI) and IR TX/RX, one USB-serial link to the Pi |
| Sub-GHz | CC1101 (E07-M1101D) — 300–928 MHz ASK/OOK + 2-FSK, on the ESP32's SPI |
| IR | IR LED + TSOP receiver — 38 kHz capture / replay on the ESP32 (GPIO13 TX · GPIO14 RX) |
| Bad USB co-processor | Raspberry Pi Pico 2 W (RP2350 + CYW43 Wi-Fi) — CircuitPython USB HID keyboard that hosts its own Wi-Fi AP; reached over a dedicated Pi adapter |
Wi-Fi roles are bound by USB VID:PID so a wlanN reshuffle on reboot never breaks them:
| Role | Chipset |
|---|---|
| Monitor + injection | MediaTek MT7612U |
| Rogue AP (Captive Portal Lab) | Realtek RTL8812AU |
| Client / SSH uplink | Realtek RTL8821AU |
| Auxiliary / Bad USB link | Realtek RTL8188EUS — joins the Pico's AP on demand (static IP, no default route) |
Everything is commodity, off-the-shelf hardware — no custom PCB. Substitutes in each row work; this is the exact rig in the photos above.
| Part | Model used | Notes / substitutes |
|---|---|---|
| SBC | Raspberry Pi 3B+ (1 GB) | any Pi with a 40-pin GPIO header |
| Display + touch | ILI9486 3.5" SPI TFT (480×320) + ADS7846 | the common "RPi 3.5 inch" resistive shield |
| Radio / IR co-processor | ESP32-WROOM-32 dev board | any ESP32 with ≥ 4 MB flash — runs CC1101 and IR |
| Sub-GHz transceiver | CC1101 — E07-M1101D + SMA antenna | use an antenna for a band that is legal to TX in your region |
| IR transmitter / receiver | IR LED (+ driver transistor) + TSOP/VS1838 receiver | 38 kHz; capture + replay remotes |
| Bad USB co-processor | Raspberry Pi Pico 2 W | any RP2040/RP2350 board with Wi-Fi + USB-device mode; runs CircuitPython |
| High-gain Wi-Fi | ALFA-class USB adapters (MT7612U / RTL8812AU / RTL8821AU / RTL8188EUS) | monitor + injection capable; high-gain antennas |
| Power | powered USB hub | the radios need clean current — don't bus-power them off the Pi |
| Wiring | jumper wires + GPIO expansion board | for the CC1101 (SPI) + IR hookup to the ESP32 |
Flashing the co-processor: wiring diagram + one-command flash (prebuilt binary or build-from-source) are in
firmware/README.md.
SPI0 on the Pi is fully consumed by the display + touch — which is exactly why the CC1101 lives on the ESP32 rather than fighting for the Pi's bus. The repo also documents the alternative Pi-direct porting path (CC1101 on SPI1) and the free I2C-1 bus for a PN532 NFC/RFID add-on. Porting reference: docs/hardware-reference.html / docs/hardware-reference.pdf — the PDF is generated on-device by the zero-dependency PDF writer.
Acid Zero is designed to run in a controlled, self-owned RF lab — that is its only intended environment:
- Your own router as the test AP — a spare/factory-reset router, never a production or shared network.
- Your own phone / laptop as the only client on the test network.
- RF isolation + low power — test in a quiet RF area and keep TX power low (the rogue-AP adapter at minimum power) so signals stay on your bench, not your neighbours'.
- Credential capture OFF by default — the captive portal lab records only a masked submission count for the demo. Raw capture is gated behind an explicit own-lab flag and must only ever face your own test client.
- A first-run authorization gate plus per-screen Learn reminders bake authorized-use into the device itself; active-transmit features (rogue AP, deauth, BLE spam) are clearly labelled and the captive-portal capture stays masked unless you explicitly opt into own-lab mode.
- No real users, ever. If a device you don't own can see the AP, or a person who hasn't authorized you could connect, you are in the wrong environment — stop.
This controlled-environment design is the line between a security-education project and a tool for abuse.
Instrumented testing showed that an iPhone personal hotspot (WPA3-SAE + 802.11w PMF) is immune to both deauth and auth-flood by design — Protected Management Frames defeat the attack class at the protocol level. This is documented as a real finding rather than buried, because knowing what doesn't work is as important as what does, and because PMF is exactly the correct defense. The platform's value is rigorous, repeatable measurement of what works and what doesn't — not a list of guaranteed exploits.
Built on the jayofelony pwnagotchi base OS. Two ways to get it onto a Pi 3B+:
Download the latest acidzero-*.img.xz from the
Releases page and flash it
with Raspberry Pi Imager or balenaEtcher, then boot — no setup, no commands. It's a
clean jayofelony pwnagotchi base with Acid Zero pre-deployed; the default login and
first-boot notes are on the release page. Provenance, licensing and the GPL source
offer are in CREDITS.md.
Prefer to layer Acid Zero onto your own install, or audit every step? The launcher
runs under the system python3 (stdlib + Pillow + numpy — no venv), so it's
independent of how the base image lays out its own runtime.
- Flash a stock jayofelony pwnagotchi image (the 64-bit asset, for the Pi 3B+) and get SSH access — full walkthrough incl. the USB-gadget bootstrap in INSTALL.md §1.
- On the Pi:
git clone https://github.com/chetansaini53/acid-zero.git cd acid-zero sudo ./install.shinstall.shis idempotent — it sets the display overlay, installs the apt deps, deploys every file, bundles the co-processor firmware, and enables the services. Update later withgit pull && sudo ./install.sh. This same script builds the release image — see BUILD_CLEAN_IMAGE.md.
- Runtime: system Python 3.11+, Pillow, numpy (+ pyserial for the co-processors)
- Wi-Fi: bettercap (via pwnagotchi), aircrack-ng suite, hcxtools (
hcxpcapngtool), hostapd, dnsmasq - Bluetooth: bluez (
btmgmt/btmon), raw HCI sockets - Display: Linux
fbtft - Sub-GHz + IR co-processor: flash the ESP32 (CC1101 + IR) with one command — prebuilt binary or build-from-source:
firmware/README.md
Full setup, flashing, overlay configuration, and service install are in INSTALL.md.
The bettercap default credentials (
pwnagotchi:pwnagotchi) are the published pwnagotchi default, not a secret.
launcher/acidzero.py # the ~1,500-line UI launcher
apps/packets.py # in-process plugin example
apps/subghz.py # Sub-GHz UI plugin (capture/decode/add-manually)
apps/subghz_proto.py # OOK protocol codec (decode/encode/verify, pure)
apps/test_subghz_proto.py # codec unit tests (20 cases, no radio needed)
apps/ir.py # IR UI plugin (Flipper-style Remotes/Buttons + raw replay)
apps/ir_proto.py # Flipper .ir codec + protocol encode (NEC/Samsung)
apps/modules.py # live hardware status (ESP32/CC1101/IR/GPS probes)
apps/badusb.py # Bad USB UI plugin (Pico-AP CONNECT/DISCONNECT + DuckyScript folder browser)
launcher/acid_badusb.py # Bad USB client + Pico-AP link manager (nmcli, dedicated adapter)
apps/hello-native/{app.json,hello.py} # native-plugin template + contract
lib/acid-ble/
hci.py # raw HCI socket layer
spam.py # BLE advertising
vendors/{apple,google,samsung,microsoft}.py
scripts/acid-{deauth,evilportal,handshake,packets,hs-clean,flood}.sh
scripts/acid-{ble-scan,portal-server,hwref}.py # hwref = zero-dep PDF/HTML writer
systemd/{acidzero.service,acid-hs-clean.service,acid-hs-clean.timer}
firmware/esp32-allinone/esp32-allinone.ino # ESP32 co-processor firmware — CC1101 + IR (source)
firmware/esp32-allinone/prebuilt/*.merged.bin # ready-to-flash image (flash at 0x0)
firmware/esp32-cc1101/, firmware/esp32-ir/ # legacy single-purpose firmwares (reference/fallback)
firmware/flash-allinone-{windows.bat,pi.sh} # one-command ESP32 flashing
firmware/README.md # CC1101 + IR wiring + flashing guide
firmware/pico-badusb/code.py # Pico 2 W Bad USB firmware — AP mode + DuckyScript engine (CircuitPython)
firmware/pico-badusb/{boot.py,settings.toml.example,payloads/} # stealth boot · AP config · Flipper .txt payloads
firmware/pico-badusb/README.md # Pico flashing + AP-mode setup guide
docs/hardware-reference.{html,pdf}
docs/{device,setup}.jpg # real-hardware photos
docs/architecture.svg # system architecture diagram
docs/screenshots/*.png
This project exists to build, understand, and detect wireless-security techniques — not to attack strangers. It is intended exclusively for:
- Devices and networks you own.
- Engagements where you hold explicit written authorization to test (signed scope-of-work / rules of engagement).
- Controlled lab environments, CTF ranges, and education.
Key points:
- Deauthentication, rogue access points, captive-portal credential capture, and BLE advertising spam are illegal when used against networks or devices you do not own or are not authorized to test, in most jurisdictions (US CFAA, UK Computer Misuse Act, India IT Act, UAE Cybercrimes Law, EU equivalents).
- Wi-Fi deauth and BLE spam are transmitting operations — in many regions even harmless-looking transmission against third-party devices can independently violate radio/spectrum law.
- The captive-portal credential capture is a simulation for authorized social-engineering assessments and education — disabled by default (only a masked submission count is recorded; raw capture requires an explicit own-lab flag) and never to be deployed to collect real users' data.
- This repository deliberately contains no destructive or denial-of-service payloads. The "spam" and "deauth" tooling exists to measure and demonstrate known wireless-protocol weaknesses in authorized assessments — and, as the findings above show, to document where modern protections (WPA3-SAE, 802.11w PMF) defeat them.
- The author accepts no liability for any misuse.
If you can't say yes to "do I own this, or do I have written permission to test it?" — stop. Full policy: ETHICS.md.
Released under the MIT License — see LICENSE. The permissive license is intentionally kept clean; authorized-use terms live in ETHICS.md, not bolted onto the license. Built on the jayofelony pwnagotchi base OS — respect its license and the licenses of all bundled tools (bettercap, aircrack-ng, hostapd, dnsmasq, bluez).
Chetan Saini — senior software architect (14+ yrs) and security researcher. Filed CVE for the Releasit COD Form Shopify app (CWE-602 + CWE-798, MITRE candidate #1999827). GitHub: @chetansaini53 · Contact: chetansaini53@gmail.com
Built to demonstrate end-to-end depth: a hand-built framebuffer renderer, an evdev + least-squares touch stack, a deterministic multi-radio binding layer, a real native-plugin ABI, and a from-scratch PDF writer — assembled into a coherent, responsive handheld on constrained hardware.
- Core Logic & Hardware Architecture: Chetan Saini
- Code Assistance & Implementation: Ella (AI Pair Programmer)
Note on Open Source & Transparency: This project is heavily driven by custom hardware prototyping, breaking the limitations of low-level data buses, and multi-protocol setups. The system design and hardware orchestration are fully human-designed, while the codebase is optimized with the help of AI assistance.
Contact: Chetan Saini — chetansaini53@gmail.com















