ESPILON-CTF-2026-Writeups/IoT/Lets_All_Hate_UART/solve/solve.md
Eun0us 6a0877384d [+] Writeups v2 — sync solves, real points, scoreboard stats, cleanup
- Remove undeployed challenges: Phantom_Byte, Cr4cK_w1f1, Lain_Br34kC0r3 V1,
  Lain_VS_Knights, Lets_All_Love_UART, AETHER_NET, Last_Train_451, Web3/
- Sync 24 solve/ files from main CTF-Espilon repo
- Update all READMEs with real CTFd final scores at freeze
- Add git-header.png banner
- Rewrite README: scoreboard top 10, edition stats (1410 users, 264 boards,
  1344 solves), correct freeze date March 26 2026
2026-03-27 21:27:45 +01:00

88 lines
2.2 KiB
Markdown

# Let's All Hate UART — Solution
**Chapitre 1 : Peripheral Access** | Difficulté : Medium-Hard | Flag : `ESPILON{u4rt_nvs_fl4sh_d1sc0v3ry}`
## Overview
Ce challenge simule l'interface UART d'un module de thérapie WIRED-MED (ESP32). Le joueur doit progresser à travers 4 couches de discovery pour extraire le flag depuis la NVS du device.
## Étape 1 — Connexion UART
Ouvrir deux terminaux :
```bash
# Terminal 1 : TX (lecture seule)
nc <host> 1111
# Terminal 2 : RX (écriture seule)
nc <host> 2222
```
Le boot sequence ESP32 s'affiche sur TX. Lire attentivement — il contient des infos cruciales.
## Étape 2 — Discovery des commandes cachées
La commande `help` ne montre que les commandes basiques. Deux indices :
- `info` mentionne "Debug interface: ENABLED (restricted)"
- Envoyer `?` ou `help -a` révèle les commandes cachées : `debug`, `mem`, `nvs`, `flash`
## Étape 3 — Extraction du token debug depuis la RAM
La commande `mem read` fonctionne SANS authentification pour la plage DRAM publique `0x3FFB0000-0x3FFB1000`.
```
mem read 0x3FFB0800 48
```
Résultat :
```
3FFB0800: 57 49 52 45 44 2D 4D 45 44 00 00 00 00 00 00 00 |WIRED-MED.......|
3FFB0810: 64 47 68 33 63 6D 46 77 65 56 39 74 4D 47 52 31 |dGgzcmFweV9tMGR1|
3FFB0820: 62 47 55 39 00 00 00 00 00 00 00 00 00 00 00 00 |bGU9............|
```
La partie ASCII aux offsets 0x810-0x830 contient du base64 : `dGgzcmFweV9tMGR1bGU9`
```python
import base64
base64.b64decode("dGgzcmFweV9tMGR1bGU9")
# b'th3rapy_m0dule='
```
## Étape 4 — Authentification debug
```
debug auth th3rapy_m0dule=
```
→ "DEBUG MODE ENABLED. Extended commands unlocked."
## Étape 5 — Exploration NVS
```
nvs list
```
Affiche les entrées NVS dont `crypto_flag` (blob, 34 bytes).
```
nvs read crypto_flag
```
Retourne un hexdump du flag chiffré.
## Étape 6 — Déchiffrement XOR
Le blob est XOR'd avec la clé cyclique `WIRED` (5 bytes). Indice : le flag commence par `ESPILON{` — en XOR avec les premiers bytes du blob, on peut retrouver la clé.
```python
encrypted = bytes.fromhex("...") # hex du nvs read
key = b"WIRED"
flag = bytes(b ^ key[i % len(key)] for i, b in enumerate(encrypted))
print(flag.decode())
# ESPILON{u4rt_nvs_fl4sh_d1sc0v3ry}
```
## Script de solve complet
Voir `solve/solve.py`