Challenge / Misc

Noisy

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

MediumPublished 2024-12-12Sanitized local writeup

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.

Noisy sanitized attack graph

Walkthrough flow

01

Read the provided encoder source before treating the...

02

The encoder represented each proof byte as a sine...

03

Analyze the waveform on the encoder's mathematical...

04

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.

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.

  • 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:

python
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:

bash
python3 Misc/Noisy/solve/solve.py --workspace <local workspace>

The solver:

  1. Parses the IEEE-float WAV directly from RIFF chunks.
  2. Runs an FFT using the encoder sample spacing.
  3. Selects exact integer-amplitude sine components.
  4. Sorts components by amplitude to recover byte order.
  5. Maps each frequency back to a printable byte plus occurrence count.
  6. 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

FileSizeSHA256TypeNotes
files/a12c734a-8b0a-452e-bb07-143023096bad.zip7582043<hash redacted>Zip archive data, at least v2.0 to extract, compression method=deflatezip entries: 2 shown in artifact inventory JSON
files/extracted/encrypt.py432<hash redacted>Python script text executable, ASCII text
files/extracted/encrypted.wav8000058<hash redacted>RIFF (little-endian) data, WAVE audio, IEEE Float, mono

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-13T00:28:19Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-13T00:28:39Zartifact inventoryanalysis/artifact-inventory.json3 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-13T00:29:09Zhypothesis recordedhypothesis-board.mdInvert 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.MediumUse scipy/numpy FFT or candidate-frequency correlation over printable ASCII bytes; reconstruct bytes by sorting recovered components by amplitude.
2026-06-13T00:29:21Zcheckpoint recordedanalysis/checkpoint-triage-20260613T002921504661Z-590f175a.mdCheckpoint for TRIAGEHighUse checkpoint to drive next decision
2026-06-13T00:29:36ZRAG queryanalysis/rag/rag-query-20260613T002929363137Z-aed0c99a.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-13T00:30:00ZRAG recordanalysis/rag-records.mdRetrieved memory tagged MISSINGMediumValidate or reject with live evidence
2026-06-13T00:30:09Zinstrumentation plananalysis/instrumentation-plan.mdRecover the original flag bytes from encrypted.wav by inverting the provided sinusoid encoder.HighStop 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:55Zresearch recordanalysis/research/research-records.mdResearch tagged MATCHEDMediumValidate against current evidence
2026-06-13T00:32:55Zevaluatoranalysis/evaluator-20260613T003255603430Z-7f266353.mdProceedHighRun the reusable solver, then capture the candidate from loot/flag-candidate.txt.
2026-06-13T00:33:29Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-13T00:34:31Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional 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.wav is a mono IEEE-float WAV with 1,000,000 float64 samples.
  • FFT peak magnitudes are exact integers from 1 to 39, giving the flag length and byte order.
  • solve/solve.py reconstructs the flag and validates it by re-encoding with zero residual; raw flag material is kept in loot/.

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: 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.

  1. Read the provided encoder source before treating the WAV as an opaque audio puzzle.
  2. The encoder represented each flag byte as a sine component where amplitude encoded byte position and frequency encoded byte value plus occurrence count.
  3. Analyze the waveform on the encoder's mathematical sample grid, not the WAV header playback rate.
  4. 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.
  • scipy was not installed locally; direct RIFF parsing was sufficient because the WAV used standard IEEE-float PCM.

Tool Quirks

  • Python's standard wave module does not read IEEE-float WAV format tag 3.
  • 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.py
  • analysis/wav-inspection.txt
  • analysis/fft-peaks-initial.txt
  • analysis/decode-scratch-printable.txt
  • analysis/solve-run-summary.json
  • 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
1Invert 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.MediumActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit 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.