Badge-UnknownSecurity-Conference-2026

Public

@electroniccats

Download board files

Files for version 1. Pick what you came for.

Share Badge-UnknownSecurity-Conference-2026

Check access before sharing the link.

Who can open this board

Anyone can open this board. No sign-in is required.

This link opens the latest version. Copying it does not grant additional access.

Loading…

README

Badge UnknownSecurity Conference 2026

Repositorio oficial del Badge UnknownSecurity Conference 2026. Aquí encontrarás el hardware (esquemático, PCB y footprints) y la documentación de uso del badge.

El badge es un dispositivo autónomo: se alimenta por USB-C (o batería en el portapilas J3), se maneja con sus 4 botones direccionales y muestra todo en su OLED. No necesita computadora ni aplicación para jugar; la PC sólo se usa para flashear y para la consola serie de diagnóstico.

El firmware que corre en el badge es PwnPet, un framework de mascota virtual (tipo Tamagotchi) sobre BLE con retos de CTF integrados. Este badge corresponde a la variante ch573/unknownSecurityConference-2026, cuya criatura es la Pwn Llama (species_id 0x0003).

Para interactuar con el badge desde una computadora existe PwnPet_CLI, una herramienta de línea de comandos en Python que se conecta por BLE. Ver la sección CLI.


Hardware

BloqueParte
MCUCH573F QFN28 (RISC-V, BLE 4.2, AES-128 por hardware, USB Full-Speed)
AntenaAntena embebida en el PCB (AE1)
PantallaOLED 128×64 en conector J2 (I²C @ 0x3C) — panel 0.96" SSD1306
LED de usuarioWS2812B RGB direccionable (D11)
Sensor de luzLTR-303ALS-01 (I²C @ 0x29, comparte el bus del OLED)
Entrada botones4 push buttons direccionales (activo-bajo, sobre el header J1)
AlimentaciónUSB-C (P1) + portapilas / LiPo (J3), OR-ing por schottky y PMOS
ReguladoresAP2112K-3.3 (3.3 V)
Relojes32 MHz (BLE) + 32.768 kHz (RTC)
DepuraciónHeader SWD (J4) para WCH-LinkE

Asignación de pines (variante unknownSecurityConference-2026)

FunciónPinNota
OLED SDA / SCLPB12 / PB13I²C por software (SoftWire) @ 400 kHz
LTR-303 SDA / SCLPB12 / PB13Comparte el bus I²C del OLED (0x29)
WS2812 DATAPA14SPI0 MOSI (movido desde PB14 para liberar SWDIO)
Botón ARRIBAPB7
Botón ABAJOPA8
Botón IZQUIERDAPA9
Botón DERECHAPA12Antes CS del breakout J1
ADC de usuarioPA4 / PA5AIN0 / AIN1 libres en J1
USB D+ / D−PB11 / PB10Fijo por silicio
SWCLK / SWDIOPB15 / PB14Programación SWD (J4)
BOOT / RESETPB22 / PB23SW3 (ISP por ROM) / SW1

[!NOTE] Nota de panel OLED. Esta variante no define BOARD_OLED_CONTROLLER, por lo que el firmware compila en modo SSD1306 (sin offset de columna), que es el controlador real de los paneles de 0.96" 128×64. Si montas un panel de 1.3" (que casi siempre es un SH1106) verás 2 columnas corridas: en ese caso hay que añadir #define BOARD_OLED_CONTROLLER 1 a pwnpet_variant.h.

El esquemático, PCB y footprints están en hardware/. El proyecto se diseñó con KiCad 9.


Qué sabe hacer el badge

1. Mascota virtual persistente

El badge cría una criatura (Pwn Llama, species_id 0x0003) con estadísticas que evolucionan en el tiempo y sobreviven al apagado (se guardan en la DataFlash del CH573):

EstadísticaRangoQué la afecta
Felicidad0–1000Acariciar, jugar, misiones
Hambre0–1000Alimentar (sube), decae sola con el tiempo
Salud0–1000Descuido prolongado la baja
XP0–…Misiones, caricias, alimentar

Estados de la criatura (se reflejan en el sprite del OLED y en el color del LED):

EstadoCondiciónLED
TemerosoEstado inicialAzul fijo
CuriosoAl acumular algo de XPAmarillo fijo
LealAl acumular bastante más XPVerde fijo
Paranoia3 passkeys incorrectos por BLERojo parpadeante (60 s)
HambrientoSalud críticaMagenta parpadeante
MuertoDescuido total o sobrealimentaciónApagado

Sobrealimentar tiene consecuencias: al pasar de 600 / 750 / 900 de hambre la criatura se pone "gordita" (sprites y LED naranja en tres intensidades), y al saturar en 1000 muere de sobrealimentación. Después de morir hay una penalización de 3 minutos antes de poder revivirla (arise, con animación y LED naranja).

Con el panel de 128×64 los sprites son a pantalla completa y las cadenas de estadísticas se muestran sin abreviar (HAP: / HUN:).

2. Sensor de luz

El LTR-303 es el sensor secundario de la especie: el badge mide luz ambiental en lux y reacciona a ella (hay un sprite de "iluminado" y el LED parpadea en amarillo mientras la condición se sostiene). El sensor primario sigue siendo la temperatura interna del chip, que es la que se publica como sensor_value.

3. Controles físicos

ControlEtiqueta en PCBFunción
Interruptor slideSW2Encendido principal
Botón táctilSW1 (RST)Reset del sistema
Botón táctilSW3 (BOOT)Bootloader ISP por ROM (mantener al conectar el USB)
Botones direccionalesARRIBA/ABAJO/IZQUIERDA/DERECHAJuego, estadísticas, amistad y retos
AcciónEfecto
ARRIBA (pulsación corta)Acariciar la criatura (+5 XP) — muestra Petted! +5xp
ARRIBA (pulsación larga)Muestra/oculta la pantalla completa con el nombre del dueño
ABAJO (pulsación corta)Alimentar (+25 comida/felicidad, +5 XP) — muestra Fed! +25food
ABAJO (pulsación larga)Muestra/oculta la placa con el nombre de la mascota en la esquina superior derecha (sin tapar el sprite)
IZQUIERDAOverlay de estadísticas: HAP:<felicidad> HUN:<hambre>
DERECHAOverlay de estadísticas: HP:<salud> XP:<xp>
IZQUIERDA + DERECHA ≥ 500 msActiva/desactiva el modo amistad (Friend mode ON/OFF)
ARRIBA con solicitud pendienteAcepta la solicitud de amistad en pantalla

Las pulsaciones largas de ARRIBA y ABAJO no generan un evento nuevo para las misiones de patrón de botones: el flanco de subida ya acarició o alimentó, la pulsación larga sólo añade el interruptor de pantalla.

Presionar IZQUIERDA o DERECHA por separado retrasa su overlay ~200 ms, para dar tiempo a que el otro botón se una al combo de modo amistad.

Con la criatura muerta los botones de interacción quedan inhibidos hasta hacer arise desde la CLI.

4. Misiones

El firmware incluye un conjunto de misiones integradas. Cada misión, cuando se completa, otorga XP y pone a disposición una bandera (PWNPET{...}). Esta guía no las resuelve; explica el marco para que sepas cómo abordarlas.

Cómo explorarlas desde la CLI:

  1. missions — descubre qué misiones existen en tu badge y cuáles ya has completado.
  2. missions --hint <id> — solicita la pista oficial del firmware para una misión específica.
  3. Interactúa (a través de la CLI o físicamente) hasta que la misión quede marcada como completada.
  4. flag <id> — recoge la bandera de una misión completada.

Categorías de misión presentes en esta variante (dependen de los indicadores HAS_*):

  • Basada en el tiempo — se completa dejando pasar cierta cantidad de tiempo desde el arranque.
  • Interacción BLE — se completa escribiendo un valor específico en una característica desde la CLI.
  • Sensor por umbral — depende del entorno físico: hay que llevar una magnitud que el badge mide por encima (o por debajo) de cierto valor.
  • Sensor por duración — requiere sostener una condición ambiental durante varios segundos, no sólo alcanzarla un instante (posible gracias al LTR-303).
  • Patrón de botones — requiere una secuencia de pulsaciones direccionales (presente porque HAS_BUTTONS=1).

Como HAS_TOUCH=0, la misión de patrón táctil de otras variantes no existe en este badge. Por eso la numeración de misiones no es contigua: lista siempre con missions para ver cuáles existen realmente.

Algunas misiones se pueden completar completamente desde la CLI; otras requieren interacción física con el hardware. Esto es intencional: el badge es a la vez un dispositivo físico y un objetivo BLE.

Recuerda: las características que contienen banderas no se nombran en la CLI y sólo devuelven datos cuando se cumplen sus condiciones. Descúbrelas usando las pistas del propio firmware, no aquí.

5. Modo amistad (badge ↔ badge)

Con el modo amistad activo (combo IZQ+DER sostenido ≥ 500 ms), el badge escanea anuncios BLE de otros PwnPet cercanos. Cuando detecta uno con RSSI suficiente (umbral −80 dBm, es decir, badges a corta distancia) muestra Amigo? PwnPet_XXYY [^]. Al presionar ARRIBA, ese badge queda guardado en la lista de amigos y aparece +Amigo: PwnPet_XXYY.

  • La amistad es asimétrica por diseño: cada badge da su propio consentimiento local. No hay handshake de red.
  • Capacidad: 6 amigos guardados en DataFlash (persisten al apagado).
  • La solicitud pendiente expira sola a los 30 s; no hay botón de rechazo explícito.
  • Se pueden bloquear direcciones desde la CLI para que no vuelvan a aparecer.
  • El escáner sólo corre mientras el modo amistad está activo, para no interferir con el radio durante el uso normal.

6. Servidor BLE GATT (retos de CTF)

El badge anuncia como PwnPet_XXXX (derivado del UID del chip) o PwnPet_<nombre> si se le puso nombre personalizado, y expone un servicio paraguas 0xFEED al que se conecta cualquier cliente BLE estándar (nRF Connect, bleak, etc.):

GrupoUUIDsContenido
Vida0xFE01–0xFE09species_id, nombre, felicidad, energía, estado, XP, salud, lista de misiones, nombre del dueño (todos de lectura)
Interacción0xC001–0xC009feed, pet, play, renombrar, bandera y pista de misión, factory reset, comando de amistad, set_owner
Estado0xDE02, 0xFA01all_missions_done, valor del sensor (lectura)

Además, el anuncio BLE lleva un payload de fabricante con species_id, el estado actual de la criatura y 3 bytes derivados de la flag, así que pwnpet scan puede mostrar especie y estado sin conectarse.

El servicio expone más características de las que se documentan aquí. Las que no aparecen en esta tabla devuelven datos vacíos hasta que se cumplen sus condiciones de acceso. Enumerar el GATT y averiguar esas condiciones es parte del reto: usa las pistas del propio firmware (missions --hint).

  • Las flags tienen formato PWNPET{12hex} y se derivan por CMAC del UID del chip, así que cada badge tiene flags distintas.
  • Hay contenido protegido por un passkey que el badge muestra brevemente en el OLED cuando la criatura alcanza suficiente confianza contigo.
  • Tres passkeys incorrectos consecutivos disparan el estado Paranoia: el badge se aísla 60 s (LED rojo parpadeante) y suma un ataque al contador permanente.

7. Consola serie (USB CDC)

Al conectar el USB-C aparece un puerto serie a 115200 baudios. Al arrancar imprime un banner de diagnóstico:

pwnpet F7 boot
chip_uid: XX-XX-XX-XX-XX-XX-XX-XX
AES-128 KAT: PASS
flag_derive KAT: PASS
BLE name: PwnPet_XXXX
type 'help' for commands

Escribe help para la lista de comandos. Sirve para diagnóstico; el juego real se hace con los botones y por BLE.


CLI — PwnPet_CLI

El badge se juega solo, pero para inspeccionarlo, resolver misiones por BLE y recoger banderas existe PwnPet_CLI: una herramienta de línea de comandos en Python que habla BLE con el badge desde Linux, macOS o Windows.

La guía completa está en el README de PwnPet_CLI. Aquí sólo va lo esencial para usarla con este badge.

Instalación

Requisitos: Python ≥ 3.10 y un adaptador Bluetooth BLE 4.0+.

git clone https://github.com/ElectronicCats/PWNPet_CLI.git
cd PWNPet_CLI

python3 -m venv .venv
source .venv/bin/activate          # Linux / macOS
# .venv\Scripts\activate           # Windows

pip install -r pwnpet_cli/requirements.txt
chmod +x pwnpet                    # Linux / macOS

./pwnpet --version

El script pwnpet se invoca desde la raíz del repositorio. Para llamarlo desde cualquier directorio, agrégalo al PATH, crea un symlink en ~/.local/bin o define un alias en tu shell.

En Linux, si hay problemas de permisos BLE:

sudo usermod -aG bluetooth $USER   # cerrar sesión y volver a entrar

Flujo básico

pwnpet scan                              # busca badges PwnPet cercanos
pwnpet target set AA:BB:CC:DD:EE:1A      # guarda el badge objetivo (o por nombre)
pwnpet                                   # abre la sesión interactiva (modo por defecto)

scan lista nombre, dirección MAC, especie y estado emocional de cada badge visible:

Name            Address            Species             State
PwnPet_3C4D     AA:BB:CC:DD:EE:2B  0x0003 (Pwn Llama)  temeroso

La sesión interactiva (pwnpet session, o pwnpet a secas) mantiene la conexión BLE abierta y evita pagar los ~5–10 s de reconexión por comando. Al conectar imprime el estado actual y deja el prompt (pwnpet). Se cierra con exit, quit o Ctrl+D; Ctrl+C sólo cancela el comando en curso.

Comandos de la sesión

ComandoQué hace
statusMuestra todos los campos públicos: dueño, especie, nombre, felicidad, hambre, salud, estado, XP, sensor y misiones
feedAlimenta a la criatura (porción fija). Sube hungry y felicidad — cuidado con sobrealimentar
petAcaricia: sube felicidad y otorga algo de XP
play <hex>Juega escribiendo un valor mágico de 32 bits y lee la respuesta; ciertos valores son parte de los retos
rename <nombre>Cambia el nombre de la criatura (máx. 16 bytes UTF-8)
owner [<nombre>]Lee o define el nombre del dueño del badge (máx. 20 bytes UTF-8)
missionsLista las misiones y su estado (completada / pendiente)
missions --hint <id>Pide al firmware la pista oficial de una misión
flag <id>Recoge la bandera de una misión ya completada
passkey <código>Envía el passkey mostrado en el OLED para desbloquear contenido protegido
read <nombre|0xNNNN>Lee una característica por nombre público o por UUID corto
write <nombre|0xNNNN> <hex>Escribe una característica
friendship …count, list, remove <MAC>, block <MAC>, proximity [on|off]
ariseRestablecimiento de fábrica; sólo aparece si la criatura está muerta
helpLista completa de comandos

Ejemplo:

(pwnpet) owner Ada Lovelace
owner: Ada Lovelace
(pwnpet) feed
ok
(pwnpet) missions
Missions (Pwn Llama):
  [ ] mission 1
  [X] mission 2
(pwnpet) flag 2
PWNPET{xxxxxxxxxxxx}

La CLI sólo nombra las características públicas. Las que contienen banderas no tienen nombre por diseño: se alcanzan únicamente por su UUID crudo (read 0xNNNN) y devuelven datos vacíos hasta que se cumplen sus condiciones de acceso.

Comando arise — revivir una criatura muerta

Si la criatura muere (estado muerto (salud) o muerto (gordito)), el comando arise aparece en la sesión:

(pwnpet) arise
WARNING: This will wipe all saved data and reboot the device.
Type yes to confirm: yes
Factory reset initiated. Device will reboot in ~1 s.

Es un restablecimiento completo de fábrica: borra XP, misiones, nombres y estado, y reinicia el badge. La criatura renace en temeroso con todo en cero.

Si aparece Arise blocked, la criatura murió hace demasiado poco. Espera 3 minutos y vuelve a intentarlo.

Subcomandos sueltos (sin sesión)

Para scripting, cada acción existe como subcomando independiente:

pwnpet status
pwnpet feed
pwnpet pet
pwnpet owner "Ada Lovelace"
pwnpet missions
pwnpet flag 2
pwnpet read happiness
pwnpet write 0xC001 32                 # payload en hex (0x32 = 50 decimal)

Todos aceptan --target <addr|nombre> para sobrescribir el objetivo guardado, y -d / --debug para ver el traceback completo. Cada invocación suelta paga la latencia de escaneo + conexión + desconexión: para varias acciones seguidas, la sesión interactiva es mucho más rápida.

Códigos de salida

CódigoSignificado
0OK
1Error de uso (argumentos incorrectos)
2Objetivo no encontrado (timeout de escaneo)
3Fallo de conexión (adaptador BLE o timeout)
4Error GATT (lectura/escritura rechazada por el firmware)
5Timeout de notificación / valor mágico incorrecto

Qué se puede resolver desde la CLI y qué no

El firmware evalúa las misiones en dos modos, y eso decide dónde se resuelve cada una:

  • Por tick — misiones de tiempo y de sensor: avanzan con el reloj o con el mundo físico, no con comandos.
  • Por evento — misiones de escritura BLE y de botones: las de escritura BLE se completan enteras desde la CLI (play, write); las de botones exigen tocar el badge.

En resumen: la CLI es el camino para las misiones de interacción BLE y para observar el progreso de todas; las de sensor y las de botones se completan en el plano físico.


Firmware

El firmware vive en el repositorio ElectronicCats/pwnpet, en la variante ch573/unknownSecurityConference-2026.

Opción A — binario precompilado (recomendado)

Descarga el .bin correspondiente a unknownSecurityConference-2026 de la página de releases de pwnpet y flashéalo con un programador WCH-LinkE por SWD (header J4).

Opción B — compilar desde fuente

Requisitos: Linux x64, curl, git, python3 >= 3.10 y un programador WCH-LinkE.

git clone https://github.com/ElectronicCats/pwnpet.git
cd pwnpet
./scripts/bootstrap.sh                      # instala arduino-cli, wlink y el core fijado

PWNPET_VARIANT=ch573/unknownSecurityConference-2026 ./scripts/build.sh
./scripts/flash_swd.sh                      # flasheo por SWD (camino canónico)

PWNPET_VARIANT es obligatorio para este badge: el valor por defecto del script de compilación es ch573/panama_dojocon_2026, que genera una Pwn Cat con el panel configurado como SH1106.

Variables de compilación útiles:

VariablePor defectoPara qué sirve
PWNPET_VARIANTch573/panama_dojocon_2026Usar ch573/unknownSecurityConference-2026 para este badge
PWNPET_SPECIES_SPECexample_specEspecie instanciada (example_spec + HAS_LLAMA = "Pwn Llama")
PWNPET_DEV_MODE10 para build de producción (quita los comandos DEV:)

Para el badge de evento se recomienda PWNPET_DEV_MODE=0, que elimina los comandos de depuración capaces de forzar misiones y flags.

Documentación completa del firmware: build, protocolo BLE/CDC, seguridad y flags, hardware.


Clonar este repositorio

Con HTTPS:

git clone https://github.com/ElectronicCats/Badge-UnknownSecurity-Conference-2026.git

Con SSH:

git clone [email protected]:ElectronicCats/Badge-UnknownSecurity-Conference-2026.git

Notas de comportamiento

  • El OLED se refresca a 1 Hz. Una trama completa de 128×64 por I²C tarda ~455 ms; refrescar más rápido dejaría sin tiempo de radio al stack BLE. Las pulsaciones de botón sí se pintan de inmediato (rompen el gate de 1 Hz), y un botón presionado durante un refresco lo aborta para responder al instante.
  • Durante una conexión BLE activa el OLED no se redibuja, para no robarle tiempo de radio al descubrimiento GATT. Los cambios de estado sí se pintan.
  • Mientras se introduce una secuencia de botones el refresco pesado se suspende, para que el detector de pulsaciones no pierda eventos.
  • Si el KAT de AES o el de derivación de flags falla al arrancar, el firmware se detiene a propósito en vez de seguir con criptografía rota (se ve en el banner de la consola serie).

Automatización del hardware (CI)

Los workflows de GitHub Actions detectan automáticamente los archivos de KiCad en hardware/:

  • DRC y ERC: se ejecutan en cada push y pull_request para validar el diseño.
  • Archivos de fabricación: se generan al publicar un release.

Para desactivar DRC/ERC, edita hardware/electroniccats_sch.kibot.yaml:

run_erc: false
run_drc: false

Maintainer

Electronic Cats invests time and resources providing this open source design, please support Electronic Cats and open-source hardware by purchasing products from Electronic Cats!


License

Designed by Electronic Cats.

Hardware released under an CERN Open Hardware Licence v1.2. See the LICENSE file for more information.

Electronic Cats is a registered trademark, please do not use if you sell these PCBs.

Comments

No comments yet. Be the first to ask about this board.

Ask about this board

Sign in to BoardRepo

New here? Signing in creates your account; there is no separate sign-up.