# ESP Start | Field | Value | |-------|-------| | Category | ESP | | Difficulty | Easy | | Points | 50 | | Author | Eun0us | | CTF | Espilon 2026 | --- ## Description Welcome to the ESP category. Flash this firmware onto an ESP32 and connect to the UART console at `115200` baud. The device outputs something on boot. Decode it. Format: **ESPILON{flag}** --- ## TL;DR Flash the provided firmware, read the XOR-encrypted flag and its key from the UART boot output, apply XOR, get the flag. --- ## Tools | Tool | Purpose | |------|---------| | `esptool.py` | Flash firmware to ESP32 | | `screen` / `minicom` | Read UART serial output | | Python 3 | XOR decryption | --- ## Solution ### Step 1 — Flash the firmware Install esptool and flash all three binary files at their correct offsets: ```bash pip install esptool esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z \ 0x1000 bootloader.bin \ 0x8000 partition-table.bin \ 0x10000 hello-espilon.bin ``` On Linux, add your user to the `dialout` group first if you get a permission error: ```bash sudo usermod -a -G dialout $USER ``` ![esptool.py flashing — progress bar reaching 100%](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/esptool_flash.png) ### Step 2 — Connect to the UART console Open a serial terminal at 115200 baud: ```bash screen /dev/ttyUSB0 115200 # or minicom -D /dev/ttyUSB0 -b 115200 ``` Press the RESET button on the ESP32. The boot output appears: ```text === Hello ESP === System ready. Encrypted flag: 09 12 19 07 00 0E 07 35 3F 35 7D 3C 38 1E 3D 26 7F 1E 3E 7F 3E 72 34 XOR Key: 4C 41 49 4E ``` ![serial terminal showing the encrypted flag and XOR key on boot](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/esp_start_uart.png) ### Step 3 — Identify the XOR key Convert the key bytes `4C 41 49 4E` to ASCII: ``` 0x4C = 'L' 0x41 = 'A' 0x49 = 'I' 0x4E = 'N' ``` Key = `LAIN` (the protagonist of the series). ### Step 4 — Decrypt the flag Apply the key cyclically to each byte of the encrypted output: ```python enc = bytes([ 0x09, 0x12, 0x19, 0x07, 0x00, 0x0E, 0x07, 0x35, 0x3F, 0x35, 0x7D, 0x3C, 0x38, 0x1E, 0x3D, 0x26, 0x7F, 0x1E, 0x3E, 0x7F, 0x3E, 0x72, 0x34 ]) key = b"LAIN" flag = bytes(b ^ key[i % len(key)] for i, b in enumerate(enc)) print(flag.decode()) ``` Output: `ESPILON{st4rt_th3_w1r3}` ![Python decryption script running and printing the flag](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/esp_start_decrypt.png) ### Key concepts - **ESP32 flashing**: `esptool.py` writes bootloader, partition table, and application binary at their respective flash offsets (`0x1000`, `0x8000`, `0x10000`). - **UART monitoring**: ESP32 default baud rate is 115200 baud, 8N1, no parity. - **XOR cipher**: The key `LAIN` is broadcast in plaintext — trivial for an intro challenge; the real-world lesson is that hardcoded keys in `.rodata` are easily extracted with `strings`. --- ## Flag `ESPILON{st4rt_th3_w1r3}`