Surfing the Waves picoCTF 2021 Solution

Published: April 2, 2026

Description

While going through FBI servers you find an interesting WAV file. Can you find the flag?

Download the WAV audio file.

bash
wget <url>/wave.wav
  1. Step 1Inspect the sample values
    Open wave.wav in Audacity or load it in Python. Notice that all sample values are positive and discrete - they cluster at exactly 16 distinct levels. This is not normal audio; the samples encode data.
    python
    python3 << 'EOF'
    import scipy.io.wavfile as wav
    import numpy as np
    
    rate, data = wav.read("wave.wav")
    print(f"Sample rate: {rate}, shape: {data.shape}")
    print(f"Unique values: {sorted(np.unique(data))}")
    print(f"Count: {len(np.unique(data))}")
    EOF
    Learn more

    The 16 discrete sample values range from 10 to 85 in steps of 5 (10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85). This is 16 levels, which maps naturally to hexadecimal digits 0 through 15. The encoding is: hex_digit = (sample_value / 5) - 2.

  2. Step 2Decode the hex string and convert to ASCII
    Map each sample to a hex digit (0-15) using the formula (value/5 - 2). Build a hex string from all samples, then decode it to ASCII to reveal the flag.
    python
    python3 << 'EOF'
    import scipy.io.wavfile as wav
    import string
    
    rate, data = wav.read("wave.wav")
    
    hex_digits = string.hexdigits[:16]  # '0123456789abcdef'
    hex_string = ""
    for sample in data:
        # Map sample value to hex digit: (value / 5) - 2 gives 0-15
        idx = int(sample / 5) - 2
        hex_string += hex_digits[idx]
    
    # Decode hex string to ASCII
    flag = bytes.fromhex(hex_string).decode("ascii", errors="ignore")
    print(flag)
    EOF
    Learn more

    The WAV file encodes flag data not as audio but as a sequence of quantized levels. Each sample represents one hex nibble. Concatenating the nibbles gives a complete hex string that decodes directly to the flag text. The script generated the WAV file by encoding the flag characters as hex and representing each hex digit as an amplitude level.

    This kind of covert channel is a form of steganography that uses the sample values themselves (not the audio content) to carry information. The audio would sound bizarre to anyone listening but tools like audacity revealing the discrete level pattern is the giveaway.

Flag

picoCTF{...}

The WAV samples encode hex digits as 16 discrete amplitude levels. Map each level to a nibble, concatenate into a hex string, and decode as ASCII to get the flag.

Want more picoCTF 2021 writeups?

Useful tools for Forensics

Related reading

What to try next