Challenge / Hardware

Project Power

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

MediumPublished 2024-10-15Sanitized local writeup

Scenario

Project Power attack path

Project Power 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.

Project Power sanitized attack graph

Walkthrough flow

01

Provided hardware challenge exposed a socket...

02

Live trace probe confirmed base64-encoded NumPy...

03

Collected a moderate batch of random chosen plaintext...

04

Recovered the AES-128 key with first-round SubBytes...

05

Submitted the recovered key to the remote verifier...

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/Project-Power/writeup.md
  • htb-challenge/Hardware/Project-Power/notes.md
  • htb-challenge/Hardware/Project-Power/memory-summary.md
  • htb-challenge/Hardware/Project-Power/hypothesis-board.md

Technical Walkthrough

Writeup

Challenge

  • Name: Project-Power
  • Category: Hardware
  • Difficulty: Medium
  • Mode: hybrid

Summary

Project Power is a remote hardware side-channel challenge. The provided interface allows chosen 16-byte plaintext encryption on a standard AES-128 device and returns a captured power trace. A second option verifies a submitted AES key and returns the flag if the key is correct.

The solution was to collect aligned power traces for random chosen plaintexts, run correlation power analysis against the first AES round S-box Hamming-weight leakage model, recover the 16-byte AES key, and submit it to the verifier. Raw key material and the flag are kept in loot/.

Artifact Inventory

The original ZIP is preserved at files/a12c737e-f8bd-4499-a3e1-14de70ffc81a.zip. Extraction produced:

  • analysis/extracted/socket_interface.py: sample socket client with option 1 for trace collection and option 2 for key verification.
  • analysis/extracted/remote_lab_layout.png: lab diagram confirming standard AES-128 encryption and oscilloscope power-trace capture.

The extracted file types and hashes are recorded in analysis/file-types.txt and analysis/sha256sums.txt.

Analysis

socket_interface.py documents the protocol: send option 1 with a 16-byte plaintext to receive base64-encoded NumPy trace data, or send option 2 with a hex-encoded AES key to verify it. The lab diagram confirms the device encrypts arbitrary 16-byte plaintexts with standard AES-128.

The first probe in analysis/trace-probe-1.txt validated the live response format. Each trace decoded as 1042 float64 samples. Since plaintext is chosen and AES is standard, the cheapest key-recovery path is first-round CPA:

  1. For each trace and key-byte guess, compute SBOX[plaintext_byte ^ guess].
  2. Convert that hypothetical intermediate to Hamming weight.
  3. Correlate the hypothetical leakage vector with every trace sample.
  4. Select the byte guess with the highest absolute correlation.

The final run used 250 traces saved in analysis/traces/project_power_250.npz. The redacted CPA summary in analysis/cpa-summary-redacted.txt shows all 16 bytes recovered with strong score separation. Raw recovered key material was moved to loot/.

Solve

The reproducible solver is solve/solve.py. It can collect traces, run CPA, write the recovered key to loot/, and submit the key for verification.

Example:

bash
cd <local workspace>
python3 solve/solve.py --host <TARGET> --port 32006 --count 250 --delay 0.03 --force-collect

For the completed run, the saved traces can be reused without recollecting:

bash
python3 solve/solve.py --traces analysis/traces/project_power_250.npz --no-verify

The successful key-check response was saved to loot/flag-candidate.txt and captured by the harness into loot/flag.txt.

Flag

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

Lessons

  • For AES power traces with chosen plaintext, first-round S-box Hamming-weight CPA is the right first validation before trying more complex alignment or later-round models.
  • Do not wait for EOF if a remote lab socket keeps connections open; stop reading once the base64 trace decodes to a valid float64 array.
  • Treat recovered keys like challenge secrets: keep raw key and flag material in loot/, and use redacted analysis summaries for documentation.

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: Project-Power
  • Category: Hardware
  • Difficulty: Medium
  • Mode: hybrid
  • Remote instance: <TARGET>:32006
  • Start time: 2026-06-13T11:06:19Z
  • 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/a12c737e-f8bd-4499-a3e1-14de70ffc81a.zip250380<hash redacted>Zip archive data, at least v2.0 to extract, compression method=deflatezip entries: 2 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-13T11:06:19Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-13T11:06:19Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-13T11:07:27Zhypothesis recordedhypothesis-board.mdRecover the AES-128 key using chosen-plaintext power traces from option 1, then submit the recovered hex key to option 2.MediumCollect a small set of traces for controlled plaintexts, inspect NumPy dtype/shape and trace alignment, then test first-round SubBytes CPA using plaintext byte hypotheses.
2026-06-13T11:07:27Zinstrumentation plananalysis/instrumentation-plan.mdRecover the AES-128 encryption key from remote power traces using local CPA instrumentation, then validate with the remote key-check option.HighStop remote collection after two failed CPA/key-check cycles without a new signal; record failure and pivot to trace alignment/preprocessing or alternative leakage model.
2026-06-13T11:07:27Zresearch taskanalysis/research/task-20260613T110727769619Z-88a186e8.mdResearch task created for advisory investigationMediumRecord research output
2026-06-13T11:07:27Zcheckpoint recordedanalysis/checkpoint-analysis-20260613T110727825607Z-292df97f.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-13T11:07:44ZRAG queryanalysis/rag/rag-query-20260613T110736065008Z-09bc6b27.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-13T11:08:03Zresearch recordanalysis/research/research-records.mdResearch tagged MATCHEDMediumValidate against current evidence
2026-06-13T11:08:24ZRAG recordanalysis/rag-records.mdRetrieved memory tagged MISSINGMediumValidate or reject with live evidence
2026-06-13T11:08:44Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-13T11:08:44Zevaluatoranalysis/evaluator-20260613T110844277480Z-77d19370.mdProceedHighCollect trace metadata and build solve/solve.py for CPA recovery.
2026-06-13T11:09:01Ztrace probeanalysis/trace-probe-1.txtOption 1 returned base64-encoded float64 NumPy traces with 1042 samples for chosen 16-byte plaintexts.HighBuild first-round AES CPA collector/analyzer.
2026-06-13T11:13:27Zsolver smoke testanalysis/cpa-test20-redacted.txt20-trace CPA run validated collection and analysis plumbing but was not used as final evidence. Raw candidate material moved to loot/.MediumCollect a larger aligned trace set.
2026-06-13T11:18:58ZCPA recoveryanalysis/cpa-summary-redacted.txt250 aligned traces produced stable first-round AES S-box CPA scores for all 16 key bytes; raw recovered key material stored in loot/.HighSubmit recovered key through option 2.
2026-06-13T11:19:43Zkey verificationloot/flag-candidate.txtOption 2 accepted the recovered key and returned the challenge flag.HighCapture flag through harness.
2026-06-13T11:19:43Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-13T11:22:02Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • The lab exposes a chosen-plaintext AES-128 encryption oracle that returns power traces, plus a separate key verification option.
  • Power traces decode as fixed-length float64 arrays with 1042 samples.
  • First-round AES S-box Hamming-weight CPA over chosen plaintexts was sufficient; 250 traces gave clear per-byte correlation margins.
  • Raw recovered AES key material and raw flag responses are stored under loot/ only.

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: Project-Power
  • 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. Provided hardware challenge exposed a socket interface for chosen-plaintext AES trace collection and a separate key verification endpoint.
  2. Live trace probe confirmed base64-encoded NumPy float64 power traces with fixed sample length.
  3. Collected a moderate batch of random chosen plaintext traces.
  4. Recovered the AES-128 key with first-round SubBytes Hamming-weight correlation power analysis.
  5. Submitted the recovered key to the remote verifier and captured the flag.

Reusable Lessons

  • For chosen-plaintext AES power traces, first-round S-box Hamming-weight CPA should be the first validation path.
  • Socket trace readers should stop on valid decoded trace data instead of assuming the service closes the connection.
  • Store raw recovered keys and verifier responses in loot/; keep analysis outputs redacted.

Dead Ends

  • Private CTF RAG had no useful prior memory for this challenge; direct artifacts and local CPA validation were sufficient.
  • A 20-trace smoke test validated the implementation but was not enough for a reliable final key.

Tool Quirks

  • binwalk was unavailable locally, but the archive contained only a PNG diagram and Python socket client, so firmware carving was not required.
  • The socket service could be slow per trace; 250 traces took several minutes but produced stable CPA margins.

Evidence Paths

  • analysis/extracted/socket_interface.py
  • analysis/extracted/remote_lab_layout.png
  • analysis/trace-probe-1.txt
  • analysis/traces/project_power_250.npz
  • analysis/cpa-summary-redacted.txt
  • solve/solve.py
  • loot/aes-key.txt
  • 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
1Recover the AES-128 key using chosen-plaintext power traces from option 1, then submit the recovered hex key to option 2.analysis/extracted/socket_interface.py exposes trace collection and key-check options; remote_lab_layout.png states standard AES-128 and power consumption traces.Collect a small set of traces for controlled plaintexts, inspect NumPy dtype/shape and trace alignment, then test first-round SubBytes CPA using plaintext byte hypotheses.MediumActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit Condition

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 Project Power, 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.