ESPILON-CTF-2026-Writeups/IoT/Lain_Br34kC0r3/README.md
Eun0us 1c42421380 Add 107 terminal screenshots and replace all 📸 placeholders
- Generated screenshots for all 33 challenges (ESP, Hardware, IoT, OT, Misc, Web3)
- Replaced all 123 placeholder lines with actual PNG image references
- Cleaned duplicate images from previously partial updates
- All write-ups now have full illustrated solutions
2026-03-27 00:34:47 +00:00

3.0 KiB
Executable File

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

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

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

both terminals open, TX showing the device banner

Step 2 — List available commands

help

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

Step 3 — Get the XOR key

settings

Returns the XOR key used to obfuscate the firmware dump.

settings command returning the XOR key

Step 4 — Dump and deobfuscate the firmware

dump_bin

Save the hex output from TX, then deobfuscate:

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:

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

Step 6 — Get the encrypted flag

flag

Returns the ciphertext as a hex string on TX.

Step 7 — Decrypt the flag

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


Flag

ECW{LAIN_Br34k_CryPT0}