Noisy
HackTheBox
"Encrypting data with discrete values is all very well and good, but there'll always be a finite number of outputs, and I hate anything you can brute force. That's why I use continuous values to store my flags! It's just... quite hard to get them back again..."
$ ls tags/ techniques/
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
Noisy — HackTheBox
Description
"Encrypting data with discrete values is all very well and good, but there'll always be a finite number of outputs, and I hate anything you can brute force. That's why I use continuous values to store my flags! It's just... quite hard to get them back again..."
Files: encrypt.py, encrypted.wav
Analysis
The encrypt.py script encodes each flag character as a sine wave and sums them into a single WAV file:
import numpy as np from scipy.io.wavfile import write from secret import flag N = 1_000_000 T = .0001 x = np.linspace(0.0, N*T, N, endpoint=False) final_waveform = 0 count_used = dict() for i, c in enumerate(flag): count_used[c] = count_used.get(c, 0) + 1 multiplier = .1 * c * (4**(count_used[c]-1)) final_waveform += (i+1) * np.sin(2 * np.pi * x * multiplier) write("encrypted.wav", 20_000_000, final_waveform)
Encoding Parameters
For each character c at position i:
| Parameter | Formula | Purpose |
|---|---|---|
| Frequency | 0.1 * ASCII(c) * 4^(occurrence - 1) | Unique frequency for each character; repeated characters get exponentially higher frequencies (x4 each time) |
| Amplitude | i + 1 | Character position in the flag (1-indexed) |
| Signal | amplitude * sin(2*pi*freq*x) | Standard sine wave |
The resulting WAV = sum of 39 sine waves (one per flag character).
Key Observation
This is a classic inverse Fourier transform problem: sum of sine waves -> FFT -> individual frequency components with amplitudes. FFT is the exact mathematical inverse of the encoding process.
Solution
Step 1: FFT Decomposition
Apply Fast Fourier Transform to the WAV file to decompose the summed signal into individual sinusoidal components:
fft_result = np.fft.rfft(data) freqs = np.fft.rfftfreq(N, d=T) magnitudes = np.abs(fft_result)
Step 2: Peak Detection
...
$ grep --similar