Challenge / Hardware

Trace

Trace is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

MediumPublished 2024-11-06Sanitized local writeup

Scenario

Trace attack path

Trace is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

Objective

Challenge walkthrough focused on Hardware evidence, validation, and reusable operator lessons.

Trace sanitized attack graph

Walkthrough flow

01

Extract the challenge archive and identify traces.csv...

02

Render or inspect the Gerbers to identify the board...

03

Infer the row/column GPIO mapping from Gerber traces...

04

Split the GPIO CSV into 8-sample frames; each frame...

05

Reconstruct visible LEDs using selected row high plus...

Source coverage

High source coverage

Status: complete. This article is generated from 4 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.

100% coverage
Evidence verdict

High confidence: the page is reconstructed from a primary walkthrough plus multiple supporting notes or evidence sources. Treat the chain as source-backed, while still checking the listed source files for sensitive values.

  • Hardware/Trace/writeup.md
  • htb-challenge/Hardware/Trace/notes.md
  • htb-challenge/Hardware/Trace/memory-summary.md
  • htb-challenge/Hardware/Trace/hypothesis-board.md

Technical Walkthrough

Writeup

Challenge

  • Name: Trace
  • Category: Hardware
  • Difficulty: Medium
  • Mode: file

Summary

The capture was a multiplexed 8x8 LED matrix trace rather than a normal serial protocol. The Gerber files identified the board as a Raspberry Pi HAT carrying a common-anode matrix, and the CSV recorded the row/column GPIO states over one complete message cycle. Reconstructing each group of eight row scans revealed the displayed HTB flag.

Artifact Inventory

  • files/a12c7358-7d8b-4b0d-a16c-5a05f7669a6f.zip: original challenge archive.
  • analysis/extracted/traces.csv: GPIO state capture with 336 samples and 16 GPIO signal columns.
  • analysis/extracted/Gerber_module/: PCB fabrication files used to infer the matrix wiring.
  • analysis/render-top-silk.png: rendered silkscreen showing the common-anode matrix and Raspberry Pi HAT context.
  • analysis/netlist-inference.txt: local GPIO row/column mapping inference.

Analysis

The CSV has 336 rows. The timing gaps and one-hot row behavior split naturally into 42 frames of 8 samples each, matching a multiplexed 8x8 LED matrix. The Gerber-derived mapping identified physical rows as GPIO 12, 25, 24, 22, 27, 17, 18, 23 and columns as GPIO 16, 5, 6, 13, 19, 26, 20, 21.

Because the board is common-anode, a visible LED occurs when the selected row is high and the column line is low. After applying that active-low rule and rotating the reconstructed matrix into display orientation, the first four glyphs rendered as HTB{, validating the mapping. The remaining frames decoded as leetspeak dot-matrix glyphs.

Public Trace write-up material was used only as advisory confirmation of the same wiring approach. The actual decoded candidate came from the local CSV and Gerber-derived mapping.

Solve

Run the decoder from the challenge workspace:

bash
cd <local workspace>
./solve/solve.py --output analysis/flag-candidate.txt --dump-glyphs analysis/decoded-glyph-bytes.txt

The script parses traces.csv, groups samples into 8-row frames, reconstructs visible pixels using the common-anode active-low column rule, rotates the matrix, maps each recovered glyph byte pattern to its displayed character, and writes the HTB-format candidate. The harness then captures it into loot/flag.txt.

One important ambiguity was corrected after validation: the glyph byte pattern 00 00 7f 49 49 7f 00 00 is digit 8 in this matrix font, not letter B.

Flag

Raw flag is stored in loot/flag.txt and intentionally not reproduced here.

Lessons

  • For LED matrix captures, infer the electrical topology before reading pixels; common-anode/common-cathode changes whether a GPIO high or low means illuminated.
  • Gerber files are useful evidence for pin mapping, especially when the trace itself only exposes GPIO names.
  • Validate orientation with a known flag prefix before committing to ambiguous glyphs.
  • Keep an indexed rendered sheet for dot-matrix challenges so visually similar leetspeak characters can be checked without guessing.
  • Cross-check ambiguous LED glyphs against an exact font table; 8 and B are easy to confuse in this challenge's rendered style.

Source-Backed Dossier

The sections below are merged from companion Markdown notes for the same case. They are rendered after sanitization so the article stays precise without publishing raw flags, credentials, or target-specific secrets.

Notes

Scope

  • Challenge: Trace
  • Category: Hardware
  • Difficulty: Medium
  • Mode: file
  • Remote instance: none
  • Start time: 2026-06-13T11:38:59Z
  • Operator: harness
  • State file: challenge-state.json

Harness Status

  • Current phase: see challenge-state.json
  • Next allowed actions: see next-action.json
  • Raw flags and sensitive material stay in loot/ only. Do not paste them here.

Artifact Inventory

FileSizeSHA256TypeNotes
files/a12c7358-7d8b-4b0d-a16c-5a05f7669a6f.zip19303<hash redacted>Zip archive data, at least v2.0 to extract, compression method=storezip entries: 13 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-13T11:38:59Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-13T11:38:59Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-13T11:57:06Zhypothesis recordedhypothesis-board.mdDecode traces.csv as a multiplexed common-anode 8x8 LED matrix using the Gerber-derived Raspberry Pi GPIO row/column mapping.MediumRun solve/solve.py to reconstruct active-low visible pixels, rotate into display orientation, map glyph bytes to ASCII, and write analysis/flag-candidate.txt.
2026-06-13T11:57:06Zinstrumentation plananalysis/instrumentation-plan.mdReproduce the debug matrix display from the captured GPIO trace.HighStop if glyph bytes do not begin with HTB{ or if any recovered glyph is not mapped; do not guess ambiguous characters without a rendered/indexed validation sheet.
2026-06-13T11:57:14Zresearch taskanalysis/research/task-20260613T115714687382Z-7791a574.mdResearch task created for advisory investigationMediumRecord research output
2026-06-13T11:57:28Zresearch recordanalysis/research/research-records.mdResearch tagged MATCHEDMediumValidate against current evidence
2026-06-13T11:57:28Zcheckpoint recordedanalysis/checkpoint-analysis-20260613T115728337980Z-3c9bdaea.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-13T11:57:39Zevaluatoranalysis/evaluator-20260613T115739182240Z-051b391d.mdProceedHighCapture flag from analysis/flag-candidate.txt, then complete writeup and final gate.
2026-06-13T11:57:51Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-13T11:59:04Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval
2026-06-13T12:39:07Zbranch closedhypothesis-board.mdGlyph was misclassified as B when it is the digit 8 in the matrix font.HighRerank hypotheses
2026-06-13T12:39:07Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-13T12:39:42Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • The ZIP contains traces.csv plus Gerber fabrication files for the debug matrix PCB.
  • traces.csv has 336 GPIO samples across 16 GPIO columns, which splits cleanly into 42 frames of 8 row scans.
  • The top silkscreen identifies the board as a Raspberry Pi 3B+ HAT and a common-anode 8x8 LED matrix.
  • Gerber/netlist inspection maps rows to GPIO 12, 25, 24, 22, 27, 17, 18, 23 and columns to GPIO 16, 5, 6, 13, 19, 26, 20, 21.
  • Visible LED pixels are active-low on the column lines while the selected row is high.
  • solve/solve.py reconstructs the frames, rotates them into display orientation, decodes the glyph bytes, and writes an HTB-format flag candidate.
  • The final flag was captured through the harness into loot/flag.txt.
  • Correction after submission feedback: glyph bytes 00 00 7f 49 49 7f 00 00 are digit 8, not letter B; the visible segment is PC85, not PCB5.

RAG / Advisory Memory

RAG output is advisory only. Record evaluated retrievals with:

bash
scripts/challenge_harness.py rag-record <workspace> --query "..." --tag MATCHED|PARTIAL|MISSING|<secret redacted>|GENERIC --validation "..."

Secrets/Flags

Raw flags and sensitive material stay in loot/ only. Use scripts/challenge_harness.py capture-flag to validate and record flag capture without printing the value.

Memory Summary

Metadata

  • Platform: HackTheBox Challenges
  • Category: Hardware
  • Challenge: Trace
  • Difficulty: Medium
  • Source workspace: <local workspace>

Validated Solve Chain

Concepts only. Do not include raw flags, reusable credentials, tokens, cookies, private keys, or live secrets.

  1. Extract the challenge archive and identify traces.csv plus Gerber fabrication files.
  2. Render or inspect the Gerbers to identify the board as a Raspberry Pi HAT with a common-anode 8x8 LED matrix.
  3. Infer the row/column GPIO mapping from Gerber traces and Raspberry Pi pin labels.
  4. Split the GPIO CSV into 8-sample frames; each frame represents one displayed glyph.
  5. Reconstruct visible LEDs using selected row high plus active-low column lines, then rotate into display orientation.
  6. Decode the recovered 8x8 glyph byte patterns into the displayed HTB-format message.
  7. Verify visually similar glyphs against the exact byte table before final capture; in this challenge, the byte pattern for digit 8 can be mistaken for letter B.

Reusable Lessons

  • Common-anode LED matrices invert the intuitive column state: selected rows are high, visible columns are low.
  • A valid HTB{ prefix is a strong orientation and polarity check before decoding the rest of a dot-matrix message.
  • Public write-ups can confirm the approach, but the current CSV/Gerber artifacts must remain the source of truth.
  • Exact glyph byte matching matters more than semantic reading of the phrase; a visually plausible B was actually digit 8.

Dead Ends

  • Direct OCR on rendered dot-matrix strips was unreliable for this challenge because the 8x8 glyphs are low-resolution and leetspeak-heavy.
  • Treating the electrical high column state as the visible LED state produces the inverse/complement display.
  • Misclassifying the digit-8 glyph as letter B produced a rejected candidate.

Tool Quirks

  • Tesseract did not read the rendered matrix strip reliably; manual glyph-byte mapping plus indexed render sheets worked better.
  • The challenge harness requires a filled writeup and solve script before completion even for file-only challenges.

Evidence Paths

  • analysis/extracted/traces.csv
  • analysis/render-top-silk.png
  • analysis/netlist-inference.txt
  • analysis/decoded-glyph-bytes.txt
  • analysis/decoded-flag-verification.png
  • solve/solve.py
  • loot/flag.txt

Ingestion Decision

  • Proposed for LightRAG: yes
  • Requires user approval before ingestion: yes

Hypothesis Board

Keep no more than 3 active hypotheses on Easy/Medium and 5 on Hard unless the user explicitly asks for breadth.

RankPathEvidenceMissing ProofCheapest ValidationConfidenceStatus
1Decode traces.csv as a multiplexed common-anode 8x8 LED matrix using the Gerber-derived Raspberry Pi GPIO row/column mapping.traces.csv has 336 samples, grouping into 42 frames of 8 row scans; top silkscreen says Common Anode Matrix; netlist inference maps rows/columns; first decoded glyphs render as HTB{Run solve/solve.py to reconstruct active-low visible pixels, rotate into display orientation, map glyph bytes to ASCII, and write analysis/flag-candidate.txt.MediumActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit Condition
Frame 23 decoded as letter B, producing PC B5analysis/decoded-flag-verification.png and user submission feedbackRejected candidate used PCB5; exact 8x8 digit table maps 00 00 7f 49 49 7f to digit 8.Glyph was misclassified as B when it is the digit 8 in the matrix font.Only revisit if the corrected PC85 candidate is rejected.

Technical analogy

How to remember this solve

Think of the hardware challenge like following copper tracks on a circuit board. The useful clue is usually where signals enter, where they are transformed, and which debug or storage path exposes hidden state.

For Trace, keep the mental model simple: identify the trusted assumption, prove it with the smallest safe test, then automate or repeat only the part that directly leads to the flag.