write-up: Hardware/Signal_Tap_Lain/README.md
This commit is contained in:
parent
1ebd714cf5
commit
3388b2a7d6
@ -1,57 +1,150 @@
|
|||||||
# Signal Tap Lain — Solution
|
# Signal Tap Lain
|
||||||
|
|
||||||
## Overview
|
| Field | Value |
|
||||||
|
|-------|-------|
|
||||||
|
| Category | Hardware |
|
||||||
|
| Difficulty | Medium-Hard |
|
||||||
|
| Points | 500 |
|
||||||
|
| Author | Eun0us |
|
||||||
|
| CTF | Espilon 2026 |
|
||||||
|
|
||||||
A logic analyzer capture is streamed with 3 channels. Channel 1 (ch1) contains
|
---
|
||||||
UART data at 9600 baud, 8N1 format. The player must identify the protocol from
|
|
||||||
signal timing and decode the ASCII message.
|
|
||||||
|
|
||||||
## Steps
|
## Description
|
||||||
|
|
||||||
1. Connect and capture the data:
|
A debug probe is capturing signals from Lain's NAVI.
|
||||||
|
Three channels are being recorded, but what protocol is in use?
|
||||||
|
|
||||||
|
- Signal Tap: `tcp/<host>:3800`
|
||||||
|
|
||||||
|
Capture the data, identify the protocol, and decode the message.
|
||||||
|
|
||||||
|
Format: **ESPILON{...}**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
Download a multi-channel logic analyzer CSV capture. Identify that channel 1 carries UART
|
||||||
|
at 9600 baud by measuring the bit period. Implement UART 8N1 decoding (LSB-first) and
|
||||||
|
extract the ASCII flag, which is repeated 3 times in the stream.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
| Tool | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `nc` | Capture the signal tap data |
|
||||||
|
| Python 3 / numpy | Logic analysis and UART decoding |
|
||||||
|
| `info` command | Get channel metadata from the service |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
### Step 1 — Connect and capture
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
nc <host> 3800 > capture.csv
|
nc <host> 3800 > capture.csv
|
||||||
```
|
```
|
||||||
|
|
||||||
Wait for `--- END OF CAPTURE ---`.
|
Wait for `--- END OF CAPTURE ---` then press Ctrl+C.
|
||||||
|
|
||||||
1. Analyze the capture. Use `info` command for metadata:
|
### Step 2 — Get metadata
|
||||||
|
|
||||||
|
Connect again and issue:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
info
|
info
|
||||||
```
|
```
|
||||||
|
|
||||||
Shows 3 channels: ch0 (reference), ch1 (data), ch2 (noise).
|
Output:
|
||||||
|
|
||||||
1. Focus on ch1. Look for patterns:
|
```
|
||||||
|
Channels: 3
|
||||||
|
ch0: reference clock (always HIGH)
|
||||||
|
ch1: data line
|
||||||
|
ch2: noise channel
|
||||||
|
Sample rate: 1 MHz
|
||||||
|
```
|
||||||
|
|
||||||
- Idle state is HIGH (1)
|
> 📸 `[screenshot: info command output listing the three channels]`
|
||||||
- Periodic falling edges = start bits
|
|
||||||
- Measure time between start bits to find character period
|
|
||||||
|
|
||||||
1. Calculate baud rate:
|
### Step 3 — Analyze channel 1
|
||||||
|
|
||||||
- Bit period ≈ 104.17 μs → 9600 baud
|
Focus on ch1. The key observations:
|
||||||
- Character frame = 10 bits (1 start + 8 data + 1 stop) = ~1041.67 μs
|
|
||||||
|
|
||||||
1. Decode UART 8N1:
|
- Idle state is **HIGH** (logic 1) — consistent with UART
|
||||||
|
- Periodic **falling edges** = start bits
|
||||||
|
- Measure the time between the start bit falling edge and the next bit transition
|
||||||
|
|
||||||
- Start bit: falling edge (HIGH → LOW)
|
### Step 4 — Calculate baud rate
|
||||||
- Sample data bits at center of each bit period (1.5 × bit_period after start)
|
|
||||||
- 8 data bits, LSB first
|
|
||||||
- Stop bit: HIGH
|
|
||||||
|
|
||||||
1. Script or manually decode the ch1 data to ASCII. The message contains the flag
|
Measure the minimum pulse width in the ch1 column:
|
||||||
repeated 3 times.
|
|
||||||
|
|
||||||
## Key Concepts
|
```
|
||||||
|
Bit period ≈ 104.17 μs
|
||||||
|
Baud rate = 1 / 0.00010417 ≈ 9600 baud
|
||||||
|
```
|
||||||
|
|
||||||
- **Logic analysis**: Reading digital signals and identifying protocols from timing patterns
|
A 10-bit UART frame (1 start + 8 data + 1 stop) = ~1041.67 μs.
|
||||||
- **UART 8N1**: Universal Asynchronous Receiver/Transmitter — start bit, 8 data bits LSB-first, no parity, 1 stop bit
|
|
||||||
- **Baud rate detection**: Measuring the shortest pulse width gives the bit period → baud rate
|
> 📸 `[screenshot: Python script measuring bit periods from ch1 transitions]`
|
||||||
- **Signal separation**: In a multi-channel capture, identifying which channel carries useful data
|
|
||||||
|
### Step 5 — Decode UART 8N1
|
||||||
|
|
||||||
|
```python
|
||||||
|
import csv
|
||||||
|
|
||||||
|
# Load capture
|
||||||
|
with open("capture.csv") as f:
|
||||||
|
reader = csv.DictReader(f)
|
||||||
|
rows = list(reader)
|
||||||
|
|
||||||
|
timestamps = [float(r["timestamp_us"]) for r in rows]
|
||||||
|
ch1 = [int(r["ch1"]) for r in rows]
|
||||||
|
|
||||||
|
BIT_PERIOD = 104.17 # microseconds at 9600 baud
|
||||||
|
chars = []
|
||||||
|
i = 0
|
||||||
|
while i < len(ch1) - 1:
|
||||||
|
# Find start bit (falling edge: HIGH → LOW)
|
||||||
|
if ch1[i] == 1 and ch1[i+1] == 0:
|
||||||
|
start_time = timestamps[i+1]
|
||||||
|
# Sample 8 data bits at center of each bit period
|
||||||
|
bits = []
|
||||||
|
for b in range(8):
|
||||||
|
sample_time = start_time + BIT_PERIOD * (1.5 + b)
|
||||||
|
# Find closest sample
|
||||||
|
j = min(range(len(timestamps)),
|
||||||
|
key=lambda k: abs(timestamps[k] - sample_time))
|
||||||
|
bits.append(ch1[j])
|
||||||
|
# LSB first
|
||||||
|
byte = int("".join(map(str, reversed(bits))), 2)
|
||||||
|
if 32 <= byte <= 126:
|
||||||
|
chars.append(chr(byte))
|
||||||
|
i += int(BIT_PERIOD * 10 / (timestamps[1] - timestamps[0]))
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
print("".join(chars))
|
||||||
|
```
|
||||||
|
|
||||||
|
The decoded message contains the flag repeated three times.
|
||||||
|
|
||||||
|
> 📸 `[screenshot: decoded UART output showing the flag repeated]`
|
||||||
|
|
||||||
|
### Key concepts
|
||||||
|
|
||||||
|
- **Logic analysis**: Reading digital waveforms and identifying protocols from timing patterns
|
||||||
|
- **UART 8N1**: Start bit (HIGH→LOW), 8 data bits LSB-first, no parity bit, 1 stop bit (HIGH)
|
||||||
|
- **Baud rate detection**: The shortest pulse width in the signal equals one bit period
|
||||||
|
- **Signal separation**: Channel 0 is a reference clock, channel 1 carries data, channel 2 is noise;
|
||||||
|
only ch1 has meaningful transitions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Flag
|
## Flag
|
||||||
|
|
||||||
`ESPILON{s1gn4l_t4p_l41n}`
|
`ESPILON{s1gn4l_t4p_d3c0d3d}`
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user