Untrusted Node
Untrusted Node is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Untrusted Node attack path
Untrusted Node 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 Quantum evidence, validation, and reusable operator lessons.
Walkthrough flow
Circuit constraints
State manipulation
Measurement strategy
Proof captured
Source coverage
High source coverage
Status: complete. This article is generated from 6 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.
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.
- Quantum/Untrusted-Node/writeup.md
- htb-challenge/Quantum/Untrusted-Node/notes.md
- htb-challenge/Quantum/Untrusted-Node/memory-summary.md
- htb-challenge/Quantum/Untrusted-Node/hypothesis-board.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Quantum__Untrusted-Node__memory-summary.md.8000a4afd7.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Quantum__Untrusted-Node__notes.md.aaf2fa2b32.md
Technical Walkthrough
Writeup
Challenge
- Name: Untrusted-Node
- Category: Quantum
- Difficulty: Medium
- Mode: hybrid
Summary
The service implements a BB84-like key negotiation with an intentionally
compromised trusted node. The transmitter sends multiple identical qubits for
each logical key bit and prints a sync_signal that reveals the chunk sizes.
The trusted node can measure selected copies, the receiver later prints its
measurement bases, and the node can still choose the final basis list sent back
to the transmitter for match calculation.
That order breaks the protocol. By measuring sacrificial copies in known bases,
leaving other copies for the receiver, then forging the final basis list after
seeing the receiver bases, the node can make the transmitter and receiver agree
on a key that the node also knows. The recovered shared key decrypts/encrypts
the receiver command channel and allows a request for the secret.
Artifact Inventory
Reference analysis/artifact-inventory.json and summarize the relevant files or remote surface.
files/a12c73b2-3fe5-4b00-b65d-53626f395ad9.zip: original HTB ZIP.analysis/extracted/quantum_untrusted_node/server.py: terminal protocol and
trusted-node interception flow.
analysis/extracted/quantum_untrusted_node/transmitter.py: duplicated-qubit
generation, sync signal, match selection, entropy check, and command XOR.
analysis/extracted/quantum_untrusted_node/receiver.py: receiver measurement,
filtering, command processing, and secret command branch.
analysis/local-simulation.txt: local protocol simulation showing the attack
succeeds reliably before remote execution.
analysis/remote-solve-run.txt: gated remote solve transcript without raw
flag exposure.
Analysis
The transmitter creates 128 logical key bits. For each bit it draws
k = poisson(lambda) + 2, then emits k identical one-qubit circuits prepared
with the same bit and basis. Those k values are printed as the sync signal in
server.py, so the compromised node knows how to group physical qubits back
into logical key bits.
The trusted node has two chances to interfere:
- Before receiver measurement, it may measure chosen physical qubits in a Z or X
basis. Measured qubits are replaced with None, so the receiver treats them
as lost.
- After receiver measurement, the receiver's bases are printed, and the node
supplies the basis list that Transmitter.get_matches() trusts for key
filtering.
The exploit uses that ordering. For each chunk, it measures one sacrificial copy
in Z and, when available, one in X. The remaining copies are left for the
receiver. Once receiver bases are printed, the exploit chooses final transmitter
gates so that the selected match is a receiver-measured copy whose basis is also
known from a sacrificial measurement. If both Z and X receiver copies exist, the
bit is recovered regardless of the transmitter's hidden basis. If only one
usable receiver basis exists, the bit is included only when that basis matches.
The source entropy check requires at least 64 balanced bits before hashing.
The local simulation in analysis/local-simulation.txt showed 49 successes in
50 trials, with known matched key lengths comfortably above the threshold. The
remote solve then used the derived SHA256 key to encrypt TX|FETCH|SECRET for
Receiver.process_command().
Solve
The solver is solve/solve.py. It has a local simulator and a remote mode:
cd <local workspace>
python3 Quantum/Untrusted-Node/solve/solve.py --simulate --attempts 50
python3 Quantum/Untrusted-Node/solve/solve.py \
--host <TARGET> \
--port 31565 \
--output Quantum/Untrusted-Node/loot/flag-candidate.txt \
--attempts 8The remote command saves the candidate flag under loot/. It was captured with
the harness:
python3 scripts/challenge_harness.py capture-flag Quantum/Untrusted-Node --from loot/flag-candidate.txtFlag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
Repeated qubits make a BB84-style protocol vulnerable when an intermediate node
can selectively measure copies and later influence basis reconciliation. The
important weakness was not quantum math complexity; it was protocol ordering:
the compromised node saw the receiver bases before submitting the gate list used
by the transmitter to decide which measurements form the final key.
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: Untrusted-Node
- Category: Quantum
- Difficulty: Medium
- Mode: hybrid
- Remote instance: <TARGET>:31565
- Start time: 2026-06-11T08:08:38Z
- 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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c73b2-3fe5-4b00-b65d-53626f395ad9.zip | 4799 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 5 shown in artifact inventory JSON |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-11T08:08:38Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-11T08:08:38Z | artifact inventory | analysis/artifact-inventory.json | 1 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-11T08:08:38Z | session bootstrap | notes.md | Challenge metadata, scenario, and prior context seeded into workspace | High | Record initial hypothesis and research |
| 2026-06-11T08:08:38Z | hypothesis recorded | hypothesis-board.md | initial triage from supplied challenge metadata | Medium | inventory files / inspect app surface / map routes depending on category |
| 2026-06-11T08:08:38Z | research task | analysis/research/task-20260611T080838416081Z-9f5487bf.md | Research task created for advisory investigation | Medium | Record research output |
| 2026-06-11T08:11:06Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-11T08:11:06Z | checkpoint recorded | analysis/checkpoint-analysis-20260611T081106950589Z-d9a73102.md | Checkpoint for ANALYSIS | High | Use checkpoint to drive next decision |
| 2026-06-11T08:11:25Z | RAG query | analysis/rag/rag-query-20260611T081107001414Z-137a5ddc.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-11T08:11:55Z | RAG record | analysis/rag-records.md | Retrieved memory tagged MISSING | Medium | Validate or reject with live evidence |
| 2026-06-11T08:12:06Z | local memory search | analysis/research/local-memory-search-20260611T081206055822Z-870089b6.md | Found 8 safe prior-note result(s) | Medium | Record useful result or skip |
| 2026-06-11T08:12:25Z | hypothesis recorded | hypothesis-board.md | duplicated-qubit trusted-node MITM | Medium | Simulate chunk strategy locally: measure sacrificial Z/X copies, leave receiver copies, derive selected key bits from printed matches, then encrypt TX\ |
| 2026-06-11T08:12:59Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-11T08:13:19Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-11T08:15:46Z | instrumentation plan | analysis/instrumentation-plan.md | Exploit the compromised trusted node by measuring sacrificial duplicated qubits, leaving receiver copies intact, and forging the final gate list so both endpoints derive a key known to the attacker. | High | Stop after two remote failures without a new parsing/protocol fact; do not brute force key material or continue blind probes. |
| 2026-06-11T08:15:46Z | evaluator | analysis/evaluator-20260611T081546945869Z-edf8a31a.md | Proceed | High | Run gated remote solve and capture flag candidate into loot/. |
| 2026-06-11T08:16:21Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-11T08:16:21Z | checkpoint recorded | analysis/checkpoint-analysis-20260611T081621078007Z-2f33df9e.md | Checkpoint for ANALYSIS | High | Use checkpoint to drive next decision |
| 2026-06-11T08:17:12Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
-
RAG / Advisory Memory
RAG output is advisory only. Record evaluated retrievals with:
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.
Scenario
At the heart of Qubitrix's empire lies their quantum key distribution network. Normally unbreakable — except one relay was compromised. It is the weak link. Impersonate the trusted node, insert yourself between transmitter and receiver, and hijack their negotiation. If you succeed, you'll hold their crown-jewel keys in your hands. This is where the real war begins.
Operator Question
HTB Quantum Medium Untrusted Node QKD compromised relay trusted node impersonation hybrid source remote solve path
Memory Summary
Metadata
- Platform: HackTheBox Challenges
- Category: Quantum
- Challenge: Untrusted-Node
- 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.
Reusable Lessons
-
Dead Ends
-
Tool Quirks
-
Evidence Paths
-
Ingestion Decision
- Proposed for LightRAG: yes/no
- 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.
| Rank | Path | Evidence | Missing Proof | Cheapest Validation | Confidence | Status |
|---|---|---|---|---|---|---|
| 1 | initial triage from supplied challenge metadata | challenge name, category, difficulty, scenario, and remote target were provided by operator | inventory files / inspect app surface / map routes depending on category | Medium | Active | |
| 1 | duplicated-qubit trusted-node MITM | server.py prints sync_signal and receiver gates; Transmitter.get_matches trusts the second attacker-supplied gate list; each logical key bit has k>=2 identical transmitted circuits. | Simulate chunk strategy locally: measure sacrificial Z/X copies, leave receiver copies, derive selected key bits from printed matches, then encrypt TX\ | FETCH\ | SECRET. |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|
Memory Summary
approval_required: true
Sanitized Memory Summary
Metadata
- Platform: HackTheBox Challenges
- Category: Quantum
- Challenge: Untrusted-Node
- 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.
Reusable Lessons
-
Dead Ends
-
Tool Quirks
-
Evidence Paths
-
Ingestion Decision
- Proposed for LightRAG: yes/no
- Requires user approval before ingestion: yes
Notes
Notes
Scope
- Challenge: Untrusted-Node
- Category: Quantum
- Difficulty: Medium
- Mode: hybrid
- Remote instance: <TARGET>:31565
- Start time: 2026-06-11T08:08:38Z
- 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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c73b2-3fe5-4b00-b65d-53626f395ad9.zip | 4799 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 5 shown in artifact inventory JSON |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-11T08:08:38Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-11T08:08:38Z | artifact inventory | analysis/artifact-inventory.json | 1 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-11T08:08:38Z | session bootstrap | notes.md | Challenge metadata, scenario, and prior context seeded into workspace | High | Record initial hypothesis and research |
| 2026-06-11T08:08:38Z | hypothesis recorded | hypothesis-board.md | initial triage from supplied challenge metadata | Medium | inventory files / inspect app surface / map routes depending on category |
| 2026-06-11T08:08:38Z | research task | analysis/research/task-20260611T080838416081Z-9f5487bf.md | Research task created for advisory investigation | Medium | Record research output |
| 2026-06-11T08:11:06Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-11T08:11:06Z | checkpoint recorded | analysis/checkpoint-analysis-20260611T081106950589Z-d9a73102.md | Checkpoint for ANALYSIS | High | Use checkpoint to drive next decision |
| 2026-06-11T08:11:25Z | RAG query | analysis/rag/rag-query-20260611T081107001414Z-137a5ddc.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-11T08:11:55Z | RAG record | analysis/rag-records.md | Retrieved memory tagged MISSING | Medium | Validate or reject with live evidence |
| 2026-06-11T08:12:06Z | local memory search | analysis/research/local-memory-search-20260611T081206055822Z-870089b6.md | Found 8 safe prior-note result(s) | Medium | Record useful result or skip |
| 2026-06-11T08: <REDACTED>, leave receiver copies, derive selected key bits from printed matches, then encrypt TX\ | FETCH\ | SECRET. | |||
| 2026-06-11T08:12:59Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-11T08:13:19Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-11T08:15:46Z | instrumentation plan | analysis/instrumentation-plan.md | Exploit the compromised trusted node by measuring sacrificial duplicated qubits, leaving receiver copies intact, and forging the final gate list so both endpoints derive a key known to the attacker. | High | Stop after two remote failures without a new parsing/protocol fact; do not brute force key material or continue blind probes. |
| 2026-06-11T08: <REDACTED> | |||||
| 2026-06-11T08: <REDACTED> | |||||
| 2026-06-11T08:16:21Z | checkpoint recorded | analysis/checkpoint-analysis-20260611T081621078007Z-2f33df9e.md | Checkpoint for ANALYSIS | High | Use checkpoint to drive next decision |
| 2026-06-11T08:17:12Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
-
RAG / Advisory Memory
RAG output is advisory only. Record evaluated retrievals with:
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.
Scenario
At the heart of Qubitrix's empire lies their quantum key distribution network. Normally unbreakable — except one relay was compromised. It is the weak link. Impersonate the trusted node, insert yourself between transmitter and receiver, and hijack their negotiation. If you succeed, you'll hold their crown-jewel keys in your hands. This is where the real war begins.
Operator Question
HTB Quantum Medium Untrusted Node QKD compromised relay trusted node impersonation hybrid source remote solve path
Technical analogy
How to remember this solve
Think of the quantum circuit like a fragile sequence of switches. The solve is about arranging the switches so the final measurement lands in the one state that unlocks the flag.
For Untrusted Node, 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.