# Lain_Br34kC0r3

| Field | Value |
|-------|-------|
| Category | IoT |
| Difficulty | Medium |
| Points | 500 |
| Author | neverhack |
| CTF | Espilon 2026 |

---

## Description

This challenge emulates a UART interface on a Lain router.
Open both connections, interact as if it was real hardware.

- **TX**: Read only
- **RX**: Write only

Maybe Lain can help you?

---

## TL;DR

Connect to the split UART interface. Use `settings` to get the XOR key, `dump_bin` to get
the obfuscated firmware, de-obfuscate to extract the AES key and IV from `.rodata`, then
use `flag` to get the ciphertext and AES-CBC decrypt it to recover the flag.

---

## Tools

| Tool | Purpose |
|------|---------|
| `nc` | Split UART connection |
| Python 3 + `pycryptodome` | XOR decoding and AES-CBC decryption |
| `strings` / Ghidra | Static analysis of deobfuscated firmware |

---

## Solution

### Step 1 — Connect

```bash
# Terminal 1 — TX (read output)
nc <host> 1111

# Terminal 2 — RX (send commands)
nc <host> 2222
```

![both terminals open, TX showing the device banner](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/lain_terminals.png)

### Step 2 — List available commands

```text
help
```

Commands available: `help`, `flag`, `dump_bin`, `settings`, `whoami`, `show config`

### Step 3 — Get the XOR key

```text
settings
```

Returns the XOR key used to obfuscate the firmware dump.

![settings command returning the XOR key](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/lain_xor_key.png)

### Step 4 — Dump and deobfuscate the firmware

```text
dump_bin
```

Save the hex output from TX, then deobfuscate:

```python
key = bytes.fromhex("<key_from_settings>")
firmware_enc = bytes.fromhex("<dump_from_dump_bin>")
firmware = bytes(b ^ key[i % len(key)] for i, b in enumerate(firmware_enc))
with open("firmware.bin", "wb") as f:
    f.write(firmware)
```

### Step 5 — Extract AES key and IV from firmware

Quick method:

```bash
strings -n 10 firmware.bin | grep -iE "key|iv|aes|lain"
```

Or open in Ghidra with Xtensa architecture, navigate to `app_main()` → AES setup
functions → locate `therapy_aes_key` and associated IV in `.rodata`.

![strings output showing the AES key and IV](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/lain_strings.png)

### Step 6 — Get the encrypted flag

```text
flag
```

Returns the ciphertext as a hex string on TX.

### Step 7 — Decrypt the flag

```python
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

key = b"<key_from_firmware>"   # 16 or 32 bytes
iv  = b"<iv_from_firmware>"    # 16 bytes
ciphertext = bytes.fromhex("<hex_from_flag_command>")

cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size)
print(plaintext.decode())
```

![Python script printing the decrypted flag](https://git.espilon.net/Eun0us/ESPILON-CTF-2026-Writeups/raw/branch/main/screens/lain_decrypt.png)

---

## Flag

`ECW{LAIN_Br34k_CryPT0}`
