pico-bit Svelte Themes

Pico Bit

Open source DuckyScript runtime and operator portal for Raspberry Pi Pico 2 W — USB HID payload injection, Wi-Fi browser portal, and Rust agents for authorized security lab workflows.

Pico Bit

Pico Bit home

pico-bit is an open source MicroPython project for the Raspberry Pi Pico 2 W. It combines a USB HID DuckyScript runtime, a Wi-Fi-hosted operator portal, and an optional Rust agent delivery flow for authorized security research, lab automation, and defensive validation.

The Pico types payloads over USB, serves a browser UI at http://192.168.4.1, and can stage one uploaded executable on the Pico filesystem for USB-based delivery.

Highlights

  • Boot-time and on-demand execution of payload.dd
  • Browser editor with save, validate, and run actions
  • Line-level dry-run diagnostics in the portal
  • Host typing target selection by OS and keyboard layout
  • Shared Host USB status for the runtime MSC/HID device
  • Single-binary USB staging as payload.exe or payload.bin
  • Live execution timeline plus loot import and loot.json download
  • Precompiled Svelte 5 + Tailwind v4 frontend embedded in firmware flash
  • Frozen UF2 builds plus release metadata with SHA-256 checksums

Hardware Support

  • Supported board: Raspberry Pi Pico 2 W (RPI_PICO2_W) only
  • Use the Pico's own USB data port for HID and MSC delivery

Default Access

What Value
Wi-Fi SSID PicoBit
Wi-Fi password PicoBit24Net
Portal URL http://192.168.4.1
Portal username admin
Portal password PicoBit24Admin

Flash a Release UF2

  1. Hold BOOTSEL while connecting the Pico.
  2. Download the latest pico-bit-RPI_PICO2_W-<version>.uf2 from the releases page.
  3. Copy it to the RPI-RP2 drive.
  4. Wait for the board to reboot.
  5. Join the PicoBit Wi-Fi network and open http://192.168.4.1.

On first boot, Pico Bit creates payload.dd if it is missing.

Build From Source

Prerequisites

  • Python 3.11 to 3.14
  • uv
  • Node.js 24 for frontend builds
  • mpremote if you want to copy local builds directly to a Pico
  • Rust if you want to build the agent binaries locally

Install dependencies:

uv sync
npm ci --prefix web

Build Local Runtime Artifacts

This creates:

  • dist/boot.py
  • dist/boot.mpy
  • dist/mpy/**/*.mpy
uv run python scripts/build.py

If frontend assets are already up to date, you can skip the Vite step:

uv run python scripts/build.py --skip-frontend

Copy a Local Build to a Pico With mpremote

Install mpremote once:

python3 -m pip install mpremote

Copy the bundled boot file:

mpremote connect auto fs cp dist/boot.py :boot.py
mpremote connect auto reset

If you also want to seed a local payload file manually:

mpremote connect auto fs cp payload.dd :payload.dd

Build a Frozen UF2 on Linux

Install firmware build prerequisites:

sudo apt-get update
sudo apt-get install -y build-essential cmake gcc-arm-none-eabi libnewlib-arm-none-eabi ninja-build

Then build the release UF2:

uv run python scripts/release.py build-uf2 \
  --micropython-ref v1.28.0 \
  --board RPI_PICO2_W \
  --release-version v0.0.2

Useful release options:

  • --usb-profile default|generic-composite|generic-keyboard|hobbyist
  • --ap-ssid ...
  • --ap-password ...
  • --portal-username ...
  • --portal-password ...

Artifacts land in dist/, including .uf2 files and release.json.

Build the Rust Agent Binaries

The Rust agents live under agent/. Available binaries are:

  • recon
  • exfil
  • persist
  • wipe

Local Development Checks

cargo check --manifest-path agent/Cargo.toml --bins

Native Local Builds

cargo build --manifest-path agent/Cargo.toml --release --bin exfil
cargo build --manifest-path agent/Cargo.toml --release --bin persist
cargo build --manifest-path agent/Cargo.toml --release --bin wipe
cargo build --manifest-path agent/Cargo.toml --release --bin recon --features with-sysinfo

Linux Release-Style Builds

rustup target add x86_64-unknown-linux-musl aarch64-unknown-linux-musl
python3 -m pip install ziglang
cargo install cargo-zigbuild
cargo zigbuild --manifest-path agent/Cargo.toml --release --target x86_64-unknown-linux-musl --bin exfil
cargo zigbuild --manifest-path agent/Cargo.toml --release --target x86_64-unknown-linux-musl --bin persist
cargo zigbuild --manifest-path agent/Cargo.toml --release --target x86_64-unknown-linux-musl --bin wipe
cargo zigbuild --manifest-path agent/Cargo.toml --release --target x86_64-unknown-linux-musl --bin recon --features with-sysinfo

Swap the target to aarch64-unknown-linux-musl for arm64.

Frontend Development

Run the portal locally with mock Pico APIs:

npm --prefix web run dev

To test the Vite frontend against real hardware:

PICOBIT_PROXY=http://192.168.4.1 npm --prefix web run dev

Local Verification

npm --prefix web run build
npm --prefix web run check
npm --prefix web run lint
npm --prefix web run test
uv run python -c "from scripts.helpers.assets import sync_web_assets; sync_web_assets(check=True, skip_build=True)"
uv run ruff format --check .
uv run ruff check scripts src tests
uv run pyright
uv run pytest
uv run python scripts/build.py --skip-frontend

Repository Notes

  • src/web_assets.py is generated from dist/web/ and should not be edited by hand
  • firmware serves a generated static route table from flash-resident bytes, including /, /assets/index.css, and /assets/index.js
  • payload.dd is writable on the Pico filesystem and is not frozen into firmware
  • the portal stages one executable at a time as payload.exe for Windows agents or payload.bin for Linux/macOS agents
  • armory uploads are executable-only and capped at 1 MB
  • src/usb.py is the source of truth for the shared machine.USBDevice singleton, MSC capability detection, runtime active() state, and staged binary filenames
  • src/keyboard.py owns the HID keyboard runtime and keyboard layout metadata; src/boot.py initializes USB first, then keyboard
  • release UF2 builds expose the Pico filesystem over built-in USB MSC and append the HID keyboard interface for offline delivery
  • host volume names may vary and can appear as No Name, so USB stagers search for payload.exe or payload.bin by filename
  • successful uploads refresh the shared USB runtime so the staged file becomes visible on the mounted Pico drive
  • USB-delivered agents can write loot-usb.json to the Pico drive; the portal imports it into canonical loot.json

Releases

GitHub releases publish:

  • UF2 firmware for RPI_PICO2_W
  • prebuilt Windows, Linux, and macOS agent bundles
  • release.json with release metadata, file sizes, and SHA-256 checksums

Manual release runs can build firmware and agent bundles independently, and partial reruns preserve checksum metadata for unchanged assets.

Contributing

See CONTRIBUTING.md.

Responsible Use

Use Pico Bit only on systems you own or are explicitly authorized to test. Unauthorized access to computer systems is illegal and out of scope for this project.

License

GPL-3.0-only. See LICENSE.

Top categories

Loading Svelte Themes