Noisy Vault
Noisy Vault is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Noisy Vault attack path
Noisy Vault 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/Noisy-Vault/writeup.md
- htb-challenge/Quantum/Noisy-Vault/notes.md
- htb-challenge/Quantum/Noisy-Vault/memory-summary.md
- htb-challenge/Quantum/Noisy-Vault/hypothesis-board.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Quantum__Noisy-Vault__memory-summary.md.b28150c63c.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Quantum__Noisy-Vault__notes.md.bb3ac55d53.md
Technical Walkthrough
Writeup
Challenge
- Name: Noisy-Vault
- Category: Quantum
- Difficulty: Easy
- Mode: hybrid
Summary
This challenge is a source-led hybrid oracle solve, not a complicated quantum-correction problem. The provided server.py contradicts the scenario blurb and shows the real service: 64 data qubits, 16 ancillas, a single oracle query, and one exact 64-bit unlock attempt. The solve is to submit a validator-safe layer of 16 data-controlled CNOTs into the ancillas, collect the noisy measurement counts, reverse each Qiskit count key to align it with the server's stored 64-bit access code, majority-vote each bit, and submit the recovered code once.
Artifact Inventory
Relevant artifacts and surfaces:
files/extracted/quantum_noisy_vault/server.py: authoritative challenge logicanalysis/source-audit.md: condensed source-derived behavior summaryanalysis/local-validation.txt: local Qiskit proof that the returned count string must be reversedanalysis/oracle-counts.json: sanitized live oracle counts from the single remote queryanalysis/remote-session.txt: sanitized remote interaction transcript with the flag redacted- Remote target:
<TARGET>:31538
Analysis
The key correction is that the scenario text is wrong for this artifact set. server.py defines visible_bits = 64 and ancilla_qubits = 16, prepares a 64-bit computational-basis access code on data qubits 0..63, and allows exactly one oracle call plus one exact unlock attempt. Those facts come directly from files/extracted/quantum_noisy_vault/server.py and are summarized in analysis/source-audit.md.
The validator does not care about quantum usefulness; it checks structural activity after transpilation. A candidate circuit must preserve at least 16 data-ancilla links and at least 4 active ancillas in the compiled circuit. A simple layer of CX:0,64; ... ; CX:15,79 satisfies both requirements while keeping the data register unchanged in the ideal circuit, because the data qubits are controls and the ancillas are targets.
The only subtlety that can burn the one unlock attempt is Qiskit bit ordering. The server measures qubit i into classical bit i, but Qiskit displays count strings with the highest classical bit on the left. analysis/local-validation.txt proves this locally with a seeded 64-bit bitstring: the noiseless count string matches that seeded value only after reversing the returned bitstring.
With that bit-order proof in hand, the live path is straightforward. The oracle returns a large counts dictionary over 4096 shots. Reversing each count key before tallying per-qubit votes yields the 64-bit access code. The sanitized remote evidence is stored in analysis/oracle-counts.json and analysis/remote-session.txt.
Solve
The full solve lives in solve/solve.py.
It performs these steps:
- Connect to the remote service.
- Send menu option
1. - Submit the fixed 16-gate CNOT layer from data qubits
0..15into ancillas64..79. - Parse the returned counts JSON.
- Reverse each count key, majority-vote each bit position, and reconstruct the 64-bit access code.
- Send menu option
2. - Submit the recovered code once and write the returned flag to
analysis/flag-candidate.txtfor harness capture.
After capture, transient artifacts were sanitized so the raw flag remains only in loot/flag.txt.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- For HTB source-backed hybrid challenges, treat the provided source as the authority when it conflicts with the scenario text.
- When a quantum service returns Qiskit counts, validate classical-bit ordering before using a one-shot decoded answer.
- Structural validator challenges can often be solved by the cheapest circuit that satisfies the policy while preserving the measured register in the ideal case.
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: Noisy-Vault
- Category: Quantum
- Difficulty: Easy
- Mode: hybrid
- Remote instance: <TARGET>:31538
- Start time: 2026-06-07T16:45:31Z
- 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/a160415e-eefd-4508-86a0-e2322131b4c9.zip | 2849 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 2 shown in artifact inventory JSON |
files/extracted/quantum_noisy_vault/server.py | 9239 | <hash redacted> | Python script text executable, Unicode text, UTF-8 text |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-07T16:45:31Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-07T16:45:54Z | artifact inventory | analysis/artifact-inventory.json | 2 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T16:45:54Z | hypothesis recorded | hypothesis-board.md | Analyze server.py to understand the 13-qubit noisy process, then construct a 13-bit/9-bit answer strategy that mitigates or decodes the noise before making the one-shot remote submission. | Medium | Read server.py, identify exact input/output protocol, qubit roles, noise model, scoring condition, and local simulation requirements. |
| 2026-06-07T16:46:25Z | checkpoint recorded | analysis/checkpoint-hypothesis_ready-20260607T164625723210Z-5c67def4.md | Checkpoint for <secret redacted> | High | Use checkpoint to drive next decision |
| 2026-06-07T16:46:25Z | research task | analysis/research/task-20260607T164625725654Z-c674d622.md | Research task created for advisory investigation | Medium | Record research output |
| 2026-06-07T16:47:00Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-07T16:49:56Z | RAG query | analysis/rag/rag-query-20260607T164948196417Z-7db78a4e.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-07T16:53:56Z | branch closed | hypothesis-board.md | Source code disproves the scenario text: the real service uses 64 data qubits, 16 ancillas, and one exact 64-bit unlock attempt. | High | Rerank hypotheses |
| 2026-06-07T16:53:57Z | hypothesis recorded | hypothesis-board.md | Use 16 data-controlled CNOTs into ancillas to satisfy structural validation while preserving the 64 data bits, then reverse each returned Qiskit count key and majority-vote the remote oracle output to recover the exact 64-bit access code. | High | Run the single oracle query with the 16 CX layer, parse counts, reverse each bitstring, and compute per-qubit majority before the one unlock attempt. |
| 2026-06-07T16:54:07Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-07T16:54:08Z | RAG record | analysis/rag-records.md | Retrieved memory tagged GENERIC | Medium | Validate or reject with live evidence |
| 2026-06-07T16:54:14Z | evaluator | analysis/evaluator-20260607T165414554775Z-05d22d98.md | Proceed | High | Implement solve/solve.py, run the exploit gate, query the remote oracle once, decode the key, and submit it immediately. |
| 2026-06-07T17:00:24Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-07T17:02:08Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
server.pyis the authority, not the scenario text: the service uses 64 data qubits, 16 ancillas, one oracle call, 4096 shots, and one exact 64-bit unlock submission.- A layer of 16
CX:data,ancillagates satisfies the validator because it creates 16 data-ancilla links and touches all 16 ancillas while leaving the data qubits unchanged in the ideal circuit. analysis/local-validation.txtproves the Qiskit count strings must be reversed before reconstructing the access code: the noiseless measurement key matches the seeded local bitstring only after reversing the returned bitstring.- The live oracle output was captured in
analysis/oracle-counts.json; reversing each count key and majority-voting across the 4096-shot distribution recovered the correct access code. solve/solve.pyreproduced the full hybrid path against the live target and the validated flag was captured intoloot/flag.txt.
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.
Memory Summary
Metadata
- Platform: HackTheBox Challenges
- Category: Quantum
- Challenge: Noisy-Vault
- Difficulty: Easy
- 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 | Analyze server.py to understand the 13-qubit noisy process, then construct a 13-bit/9-bit answer strategy that mitigates or decodes the noise before making the one-shot remote submission. | Challenge provides source code and a live target; scenario describes 13 qubits, 9-bit access code, and ancilla-based noise mitigation. | Read server.py, identify exact input/output protocol, qubit roles, noise model, scoring condition, and local simulation requirements. | Medium | Active | |
| 1 | Use 16 data-controlled CNOTs into ancillas to satisfy structural validation while preserving the 64 data bits, then reverse each returned Qiskit count key and majority-vote the remote oracle output to recover the exact 64-bit access code. | files/extracted/quantum_noisy_vault/server.py,analysis/local-validation.txt | Remote oracle must return counts consistent with the locally validated bit ordering and majority-vote assumption. | Run the single oracle query with the 16 CX layer, parse counts, reverse each bitstring, and compute per-qubit majority before the one unlock attempt. | High | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|---|---|---|---|
| Analyze server.py to understand the 13-qubit noisy process, then construct a 13-bit/9-bit answer strategy that mitigates or decodes the noise before making the one-shot remote submission. | files/extracted/quantum_noisy_vault/server.py | Source code disproves the scenario text: the real service uses 64 data qubits, 16 ancillas, and one exact 64-bit unlock attempt. | Only if the deployed remote behavior contradicts the provided source. |
Memory Summary
approval_required: true
Sanitized Memory Summary
Metadata
- Platform: HackTheBox Challenges
- Category: Quantum
- Challenge: Noisy-Vault
- Difficulty: Easy
- 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: Noisy-Vault
- Category: Quantum
- Difficulty: Easy
- Mode: hybrid
- Remote instance: <TARGET>:31538
- Start time: 2026-06-07T16:45:31Z
- 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/a160415e-eefd-4508-86a0-e2322131b4c9.zip | 2849 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 2 shown in artifact inventory JSON |
files/extracted/quantum_noisy_vault/server.py | 9239 | <hash redacted> | Python script text executable, Unicode text, UTF-8 text |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-07T16:45:31Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-07T16:45:54Z | artifact inventory | analysis/artifact-inventory.json | 2 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-07T16:45:54Z | hypothesis recorded | hypothesis-board.md | Analyze server.py to understand the 13-qubit noisy process, then construct a 13-bit/9-bit answer strategy that mitigates or decodes the noise before making the one-shot remote submission. | Medium | Read server.py, identify exact input/output protocol, qubit roles, noise model, scoring condition, and local simulation requirements. |
| 2026-06-07T16:46:25Z | checkpoint recorded | analysis/checkpoint-hypothesis_ready-20260607T164625723210Z-5c67def4.md | Checkpoint for <secret redacted> | High | Use checkpoint to drive next decision |
| 2026-06-07T16:46:25Z | research task | analysis/research/task-20260607T164625725654Z-c674d622.md | Research task created for advisory investigation | Medium | Record research output |
| 2026-06-07T16:47:00Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-07T16:49:56Z | RAG query | analysis/rag/rag-query-20260607T164948196417Z-7db78a4e.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-07T16:53:56Z | branch closed | hypothesis-board.md | Source code disproves the scenario text: the real service uses 64 data qubits, 16 ancillas, and one exact 64-bit unlock attempt. | High | Rerank hypotheses |
| 2026-06-07T16:53:57Z | hypothesis recorded | hypothesis-board.md | Use 16 data-controlled CNOTs into ancillas to satisfy structural validation while preserving the 64 data bits, then reverse each returned Qiskit count key and majority-vote the remote oracle output to recover the exact 64-bit access code. | High | Run the single oracle query with the 16 CX layer, parse counts, reverse each bitstring, and compute per-qubit majority before the one unlock attempt. |
| 2026-06-07T16:54:07Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-07T16:54:08Z | RAG record | analysis/rag-records.md | Retrieved memory tagged GENERIC | Medium | Validate or reject with live evidence |
| 2026-06-07T16:54:14Z | evaluator | analysis/evaluator-20260607T165414554775Z-05d22d98.md | Proceed | High | Implement solve/solve.py, run the exploit gate, query the remote oracle once, decode the key, and submit it immediately. |
| 2026-06-07T17: <REDACTED> | |||||
| 2026-06-07T17:02:08Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
server.pyis the authority, not the scenario text: the service uses 64 data qubits, 16 ancillas, one oracle call, 4096 shots, and one exact 64-bit unlock submission.- A layer of 16
CX:data,ancillagates satisfies the validator because it creates 16 data-ancilla links and touches all 16 ancillas while leaving the data qubits unchanged in the ideal circuit. analysis/local-validation.txtproves the Qiskit count strings must be reversed before reconstructing the access code: the noiseless measurement key matches the seeded local bitstring only after reversing the returned bitstring.- The live oracle output was captured in
analysis/oracle-counts.json; reversing each count key and majority-voting across the 4096-shot distribution recovered the correct access code. solve/solve.pyreproduced the full hybrid path against the live target and the validated flag was captured intoloot/flag.txt.
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.
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 Noisy Vault, 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.