Writeup: Wired SPI Exfil - EspilonCTF (Hardware)
Solution
Step 1: Connect and Enumerate
Connected to the SPI probe interface and issued help to list available commands:
cs <0|1> Assert/deassert chip select
tx <hex bytes> SPI transaction
status Show interface status
Step 2: Identify the Flash Chip
Read the JEDEC ID using opcode 9F:
> tx 9F
RX: EF 40 18
This identifies a Winbond W25Q128 (128Mbit / 16MB SPI flash).
Step 3: Read the Bootloader
Read from address 0x000000:
> tx 03 00 00 00
WIRED-MED BOOTLOADER v2.3
Build: 2024-03-15
Target: ESP32-S3
Partition table at 0x008000
Step 4: Read the Partition Table
Read from 0x008000:
# WIRED-MED Partition Table
# name, type, subtype, offset, size
boot, app, ota_0, 0x010000, 0x010000
config, data, nvs, 0x020000, 0x010000
# End of partition table
Only two partitions listed — the hint says there are more.
Step 5: Scan for Hidden Partitions
Read at 0x030000 (the next 64KB boundary beyond the listed partitions):
> tx 03 03 00 00
RX:
WIRED_HIDDEN_PARTITION.....+:'x.#(k 8.d14t(+!d=d-/
Found a hidden partition with encoded data after the label.
Step 6: Decode the Flag
The encoded bytes after the WIRED_HIDDEN_PARTITION\x00 marker:
12 1A 02 0C 08 10 1D 2B 3A 27 78 0D 23 28 6B 20 38 16 64 31 34 74 28 2B 21 64 3D 64 2D 2F
Working backwards from the known flag prefix ESPILON{, I derived the XOR key byte-by-byte:
| Cipher | XOR | Plain | Key byte |
|---|---|---|---|
| 0x12 | ^ | E | W |
| 0x1A | ^ | S | I |
| 0x02 | ^ | P | R |
| 0x0C | ^ | I | E |
| 0x08 | ^ | L | D |
| 0x10 | ^ | O | _ |
| 0x1D | ^ | N | S |
| 0x2B | ^ | { | P |
| 0x3A | ^ | s | I |
The repeating XOR key is WIRED_SPI.
data = bytes([0x12, 0x1A, 0x02, 0x0C, 0x08, 0x10, 0x1D, 0x2B,
0x3A, 0x27, 0x78, 0x0D, 0x23, 0x28, 0x6B, 0x20,
0x38, 0x16, 0x64, 0x31, 0x34, 0x74, 0x28, 0x2B,
0x21, 0x64, 0x3D, 0x64, 0x2D, 0x2F])
key = b'WIRED_SPI'
result = bytes([d ^ key[i % len(key)] for i, d in enumerate(data)])
print(result.decode())
Flag
ESPILON{sp1_fl4sh_3xf1ltr4t3d}