write-up: ESP/ESP_Start/README.md
This commit is contained in:
parent
9748b31923
commit
85b3e4a1a3
@ -1,3 +1,131 @@
|
||||
# test
|
||||
# ESP Start
|
||||
|
||||
hello world
|
||||
| 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
|
||||
```
|
||||
|
||||
> 📸 `[screenshot: esptool.py flashing — progress bar reaching 100%]`
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
> 📸 `[screenshot: serial terminal showing the encrypted flag and XOR key on boot]`
|
||||
|
||||
### 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}`
|
||||
|
||||
> 📸 `[screenshot: Python decryption script running and printing the flag]`
|
||||
|
||||
### 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}`
|
||||
|
||||
Loading…
Reference in New Issue
Block a user