Noisy
Noisy is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Noisy attack path
Noisy 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 Misc evidence, validation, and reusable operator lessons.
Walkthrough flow
Read the provided encoder source before treating the...
The encoder represented each proof byte as a sine...
Analyze the waveform on the encoder's mathematical...
Use FFT peak magnitudes to recover positions, invert...
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.
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.
- Misc/Noisy/writeup.md
- htb-challenge/Misc/Noisy/notes.md
- htb-challenge/Misc/Noisy/memory-summary.md
- htb-challenge/Misc/Noisy/hypothesis-board.md
Technical Walkthrough
Writeup
Challenge
- Name: Noisy
- Category: Misc
- Difficulty: Medium
- Mode: file
Summary
The challenge provided the encoder and a float WAV output. The encoder maps each flag byte to a sine wave:
- amplitude: byte position,
i + 1 - frequency:
0.1 byte 4 ** previous_occurrences_of_that_byte
Recovering the flag is therefore a spectral-analysis problem. The FFT peaks in encrypted.wav expose exact integer amplitudes from 1 through 39, and those amplitudes define the original byte order. Each peak frequency maps back to a printable ASCII byte when accounting for how many times that byte has already appeared.
Artifact Inventory
Reference: analysis/artifact-inventory.json.
files/a12c734a-8b0a-452e-bb07-143023096bad.zip: original HTB archive.files/extracted/encrypt.py: provided encoder; source of truth for the waveform mapping.files/extracted/encrypted.wav: mono IEEE-float WAV containing 1,000,000 float64 samples.
Analysis
encrypt.py builds a sampled waveform with:
multiplier = .1 * c * (4**(count_used[c]-1))
final_waveform += (i+1) * np.sin(2 * np.pi * x * multiplier)The WAV header sample rate is not the encoder frequency axis. The encoder creates x with T = .0001, so the signal should be analyzed as if sampled at 10 kHz.
The initial FFT pass in analysis/fft-peaks-initial.txt showed exact integer peak magnitudes from 1 to 39. Those magnitudes are the original byte positions. The position-sorted peak frequencies were then inverted by trying printable ASCII bytes whose occurrence count matched the frequency multiplier.
The reusable solver validates the result by re-encoding the recovered bytes and comparing the rebuilt waveform against the original. analysis/solve-run-summary.json reports zero max absolute residual and zero RMS residual.
Solve
Run:
python3 Misc/Noisy/solve/solve.py --workspace <local workspace>The solver:
- Parses the IEEE-float WAV directly from RIFF chunks.
- Runs an FFT using the encoder sample spacing.
- Selects exact integer-amplitude sine components.
- Sorts components by amplitude to recover byte order.
- Maps each frequency back to a printable byte plus occurrence count.
- Re-encodes the candidate and requires a zero residual before writing output.
Recovered flag material is written 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 waveform challenges, trust the encoder’s mathematical sample spacing over the WAV playback rate when the file was written from a synthetic array.
- If the encoder gives position-dependent amplitudes, FFT magnitude can carry ordering information as well as content.
- Keep scratch logs sanitized: raw flags belong only in
loot/.
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
- Category: Misc
- Difficulty: Medium
- Mode: file
- Remote instance: none
- Start time: 2026-06-13T00:28: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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c734a-8b0a-452e-bb07-143023096bad.zip | 7582043 | <hash redacted> | Zip archive data, at least v2.0 to extract, compression method=deflate | zip entries: 2 shown in artifact inventory JSON |
files/extracted/encrypt.py | 432 | <hash redacted> | Python script text executable, ASCII text | |
files/extracted/encrypted.wav | 8000058 | <hash redacted> | RIFF (little-endian) data, WAVE audio, IEEE Float, mono |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-13T00:28:19Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-13T00:28:39Z | artifact inventory | analysis/artifact-inventory.json | 3 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-13T00:29:09Z | hypothesis recorded | hypothesis-board.md | Invert the provided sine-wave encoder by measuring frequency and amplitude peaks in encrypted.wav; amplitude encodes byte position and frequency encodes byte value plus occurrence count. | Medium | Use scipy/numpy FFT or candidate-frequency correlation over printable ASCII bytes; reconstruct bytes by sorting recovered components by amplitude. |
| 2026-06-13T00:29:21Z | checkpoint recorded | analysis/checkpoint-triage-20260613T002921504661Z-590f175a.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-13T00:29:36Z | RAG query | analysis/rag/rag-query-20260613T002929363137Z-aed0c99a.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-13T00:30:00Z | RAG record | analysis/rag-records.md | Retrieved memory tagged MISSING | Medium | Validate or reject with live evidence |
| 2026-06-13T00:30:09Z | instrumentation plan | analysis/instrumentation-plan.md | Recover the original flag bytes from encrypted.wav by inverting the provided sinusoid encoder. | High | Stop if candidate projection cannot distinguish components or reconstructed candidate fails re-encode residual validation; then pivot to higher precision least-squares/FFT peak matching. |
| 2026-06-13T00:32:55Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-13T00:32:55Z | evaluator | analysis/evaluator-20260613T003255603430Z-7f266353.md | Proceed | High | Run the reusable solver, then capture the candidate from loot/flag-candidate.txt. |
| 2026-06-13T00:33:29Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-13T00:34:31Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- The provided encoder is reversible: it encodes byte position in sine amplitude and byte value/occurrence count in sine frequency.
encrypted.wavis a mono IEEE-float WAV with 1,000,000 float64 samples.- FFT peak magnitudes are exact integers from
1to39, giving the flag length and byte order. solve/solve.pyreconstructs the flag and validates it by re-encoding with zero residual; raw flag material is kept inloot/.
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: Misc
- Challenge: Noisy
- 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.
- Read the provided encoder source before treating the WAV as an opaque audio puzzle.
- The encoder represented each flag byte as a sine component where amplitude encoded byte position and frequency encoded byte value plus occurrence count.
- Analyze the waveform on the encoder's mathematical sample grid, not the WAV header playback rate.
- Use FFT peak magnitudes to recover positions, invert frequencies under printable ASCII plus occurrence-count constraints, then re-encode to validate the recovered bytes.
Reusable Lessons
- Synthetic WAV CTF challenges may store a numeric array rather than meaningful audio playback.
- Exact integer FFT amplitudes can reveal ordering metadata when the encoder adds weighted sine waves.
- Re-encoding and checking residuals is a strong local validation signal before flag capture.
Dead Ends
- Private CTF LightRAG had no matching prior pattern for this specific continuous-value waveform encoder.
scipywas not installed locally; direct RIFF parsing was sufficient because the WAV used standard IEEE-float PCM.
Tool Quirks
- Python's standard
wavemodule does not read IEEE-float WAV format tag3. - The WAV header sample rate was 20 MHz, but the encoder's
x = np.linspace(..., T=.0001)means FFT analysis should use a 10 kHz sample grid.
Evidence Paths
files/extracted/encrypt.pyanalysis/wav-inspection.txtanalysis/fft-peaks-initial.txtanalysis/decode-scratch-printable.txtanalysis/solve-run-summary.jsonsolve/solve.pyloot/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.
| Rank | Path | Evidence | Missing Proof | Cheapest Validation | Confidence | Status |
|---|---|---|---|---|---|---|
| 1 | Invert the provided sine-wave encoder by measuring frequency and amplitude peaks in encrypted.wav; amplitude encodes byte position and frequency encodes byte value plus occurrence count. | files/extracted/encrypt.py defines multiplier=.1c4**(count_used[c]-1) and amplitude i+1 for each flag byte. | Use scipy/numpy FFT or candidate-frequency correlation over printable ASCII bytes; reconstruct bytes by sorting recovered components by amplitude. | Medium | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|
Technical analogy
How to remember this solve
Think of the challenge like a timed puzzle booth. If the task is too fast or repetitive for a person, the intended move is usually to write a small helper that performs the simple action perfectly.
For Noisy, 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.