Alpha - author: deltabluejay - embedded - misc

Challenge Description

Embedded in this challenge is an Arduino sketch that drives a 14-segment LED display via I²C. Using a Saleae logic analyzer capture (flag_capture.sal), your task is to interpret the I²C commands and recover the hidden flag.

Files provided:

Background: I²C and 14-Segment Displays

I²C (Inter-Integrated Circuit) is a two‑wire serial protocol with:

A 14-segment LED module uses a bitmask where each bit toggles one segment (A through N, plus DP). A ‘1’ lights the segment; ‘0’ leaves it off.

Capturing the Data

  1. Open flag_capture.sal in Saleae Logic 2.
  2. Observe the SCL and SDA waveforms.
  3. Each I²C write frame transmits 18 bytes:
    • Bytes 0–1: I²C address and starting register.
    • Bytes 2–17: Segment data for up to four characters (2 bytes per character).

Segment-to-Bit Assignments

Derived from the Adafruit LED Backpack library’s alphafonttable, the bit positions are:

Segment Bit Index
A 0
B 1
C 2
D 3
E 4
F 5
G1 6
G2 7
H 8
J 9
K 10
L 11
M 12
N 13
DP 14

Combine each pair of bytes into a 16-bit little-endian value to look up the displayed character.

Decoding Automation

Below is a Python example to reverse the capture into readable text:

# Reverse lookup from bitmask to character
segment_map = {value: char for char, value in alphafonttable.items()}

with open("frames_dump.txt") as f:
    for line in f:
        raw = [int(x, 16) for x in line.split()]
        payload = raw[2:]  # skip address/register
        text = ""
        for i in range(0, len(payload), 2):
            val = payload[i] | (payload[i+1] << 8)
            text += segment_map.get(val, "?")
        print(text)
  1. Export raw hex frames from Logic 2 into frames_dump.txt.
  2. Run the script; it prints each display update.
  3. Concatenate outputs to form the final message.

Retrieved Flag

The decoded output spells:

byuctf{4r3n7_h4rdw4r3_pr070c0l5_c00l?}