Loading 3D model… large boards can take a moment.
Bare-bones firmware scaffold for the NorthSec 2026 CTF badge, targeting ESP32-S3.
Design goals (repo requirements):
.ino (pure C++ entrypoint).bin outputs)conference and ctflib/core/ → hardware/system moduleslib/challenges/ → CTF challenge modulesmain, and publishes artifacts on version tagssrc/
main.cpp C++ Arduino entrypoint (no .ino)
lib/
core/
cli/ Serial command line
system/ OTA boot selection / dual-firmware helpers
hardware/ Hardware abstraction (pins, drivers)
challenges/
registry.* Challenge init/tick hooks
example_challenge.* Placeholder challenge module
partitions/
badge_factory_ota.csv Partition table (conference + ctf)
.github/workflows/
build.yml CI build + tag-based release
platformio.ini PlatformIO project config
This project uses PlatformIO with the Arduino framework.
The entrypoint is src/main.cpp (standard Arduino setup() / loop()), not a .ino.
conference + ctfThe partition table partitions/badge_factory_ota.csv defines:
conference (app) — a "golden" imagectf (app) — an alternate/updated imageotadata (data) — controls which app partition boots nextUnder Arduino-ESP32, you can call ESP-IDF’s OTA APIs. This repo wraps them in:
lib/core/system/ota_manager.*That module provides:
core::ota::printBootInfo(Stream&)core::ota::setNextBoot(BootTarget, Stream&)The CLI is implemented in lib/core/cli/ and runs over Serial at 115200.
Commands:
helpinfo — print running partition and configured boot partitionboot conference — set next boot to conference and rebootboot ctf — set next boot to ctf and rebootrebootThis project uses ESP-IDF framework to avoid Windows path-length issues with Arduino-ESP32 SDK extraction.
Before building, set a short PlatformIO core directory to prevent path issues:
# Set environment variable permanently (restart VS Code after)
setx PLATFORMIO_CORE_DIR C:\pio
Then restart VS Code or your terminal.
Clone this repository:
git clone https://github.com/yourusername/badge-2026.git
cd badge-2026
Set the short core directory (Windows only, see above)
Open the project in VS Code with PlatformIO extension, or use CLI
In VS Code: Click the PlatformIO "Build" button (checkmark icon) in the bottom toolbar
Or via CLI:
# Build for conference partition (default)
C:\pio\penv\Scripts\platformio.exe run -e esp32-s3-devkitc-1-conference
# Or if platformio is in PATH
pio run
First build will download Arduino-ESP32 framework and toolchains. Subsequent builds are much faster.
The badge uses a conference + CTF partition layout for dual-firmware boot:
0x10000) - Conference/stable image0x150000) - CTF challenges imageTo flash both partitions:
# 1. Upload to conference partition
C:\pio\penv\Scripts\platformio.exe run -e esp32-s3-devkitc-1-conference -t upload
# 2. Upload the CTF firmware to ctf partition
C:\pio\penv\Scripts\platformio.exe run -e esp32-s3-devkitc-1-ctf -t upload
In VS Code: Use the environment switcher in the bottom toolbar to select esp32-s3-devkitc-1-conference or esp32-s3-devkitc-1-ctf, then click Upload.
After flashing both, you can use the badge CLI commands to switch between them:
boot conference - Set next boot to conference partitionboot ctf - Set next boot to ctf partitioninfo - Show current boot partitionBuild outputs (including flashable binaries) appear under:
.pio/build/<env>/firmware.bin.pio/build/<env>/bootloader.bin.pio/build/<env>/partitions.binIf you have a board connected and the correct upload port set:
pio run -t upload
pio device monitor
A desktop simulator allows running the badge firmware on your development machine without hardware. Useful for testing CLI commands, debugging, and development.
Initialize the FreeRTOS submodule:
git submodule update --init --recursive
pio run -e native
./.pio/build/native/program
The simulator presents the same CLI as the real badge. Press Ctrl+C to exit.
The workflow in .github/workflows/build.yml automatically builds firmware on:
main - Build verificationmain - Build and upload artifactsv*) - Build, create GitHub Release with binariesBoth firmware variants are built in parallel:
badge-conference.bin) - Conference mode with schedule and social featuresbadge-ctf.bin) - CTF challenges modebootloader.bin, partitions.binStep 1: Open a Pull Request
git checkout -b feature-my-changes
# Make your changes
git add .
git commit -m "Add new feature"
git push origin feature-my-changes
Open PR on GitHub targeting main branch. GitHub Actions will build and verify.
Step 2: Merge to Main After review, merge the PR. This triggers a build and uploads artifacts.
Step 3: Create a Release Tag
# Pull latest main
git checkout main
git pull origin main
# Create and push version tag
git tag v1.0.0
git push origin v1.0.0
Or use GitHub's web interface:
v1.0.0) → "Create new tag"Each release includes:
badge-conference.bin - Conference firmware for conference partitionbadge-ctf.bin - CTF challenges firmware for CTF partitionbootloader.bin - ESP32-S3 bootloaderpartitions.bin - Partition tableFLASH_INSTRUCTIONS.txt - Complete flashing guideInstall esptool:
pip install esptool
Find your serial port:
ls /dev/ttyACM* /dev/ttyUSB* (usually /dev/ttyACM0)ls /dev/cu.* (look for cu.usbmodem*)Go to Releases and download the latest .zip or individual files.
Flash bootloader, partition table, and both firmware images:
Windows:
python -m esptool --chip esp32s3 --port COM4 --baud 460800 ^
--before default_reset --after hard_reset write_flash -z ^
--flash_mode dio --flash_freq 80m --flash_size 8MB ^
0x0 bootloader.bin ^
0x8000 partitions.bin ^
0x10000 badge-conference.bin ^
0x150000 badge-ctf.bin
Linux/Mac:
python3 -m esptool --chip esp32s3 --port /dev/ttyACM0 --baud 460800 \
--before default_reset --after hard_reset write_flash -z \
--flash_mode dio --flash_freq 80m --flash_size 8MB \
0x0 bootloader.bin \
0x8000 partitions.bin \
0x10000 badge-conference.bin \
0x150000 badge-ctf.bin
If badges are already initialized, flash only updated firmware:
Conference firmware only:
python -m esptool --chip esp32s3 --port <PORT> --baud 460800 \
write_flash -z 0x10000 badge-conference.bin
CTF firmware only:
python -m esptool --chip esp32s3 --port <PORT> --baud 460800 \
write_flash -z 0x150000 badge-ctf.bin
Both firmwares:
python -m esptool --chip esp32s3 --port <PORT> --baud 460800 \
write_flash -z 0x10000 badge-conference.bin 0x150000 badge-ctf.bin
Connect to serial console at 115200 baud:
# Windows
python -m serial.tools.miniterm COM4 115200
# Linux/Mac
python3 -m serial.tools.miniterm /dev/ttyACM0 115200
You should see the boot banner and CLI prompt. Type help to see available commands.
At the CLI prompt:
boot conference - Reboot to conference firmwareboot ctf - Reboot to CTF challenges firmwareinfo - Show current running partitionThis badge uses a unique dual-firmware architecture:
Conference Partition (0x10000) - Conference mode
core + conferenceCTF Partition (0x150000) - CTF Challenges mode
boot ctf commandcore + challengesBoth firmwares share the core library (CLI, OTA management, hardware abstraction) but have completely different feature sets.
See CONTRIBUTING.md for detailed instructions on adding:
Apache-2.0 (see LICENSE).
NorthSec CTF badge 2026 is brought to you by the teamwork of:
Special thanks to:
No comments yet. Be the first to ask about this board.