| name | ctf-stego |
| description | Steganography techniques for CTF challenges. Use when data is hidden in images, audio, video, or other media files. |
| user-invocable | false |
| allowed-tools | ["Bash","Read","Write","Edit","Glob","Grep","Task","WebFetch","WebSearch"] |
CTF Steganography
Quick Start — Try These First
file image.png
exiftool image.png
strings image.png | grep -iE "flag|ctf"
binwalk image.png
xxd image.png | tail
steghide extract -sf image.jpg
steghide extract -sf image.jpg -p ""
zsteg image.png
stegsolve
Image Steganography
LSB (Least Significant Bit)
The most common image stego technique. Data hidden in the least significant bits of pixel values.
from PIL import Image
img = Image.open('image.png')
pixels = list(img.getdata())
bits = ''
for pixel in pixels:
for channel in pixel[:3]:
bits += str(channel & 1)
flag = bytes(int(bits[i:i+8], 2) for i in range(0, len(bits), 8))
print(flag)
Tools:
zsteg — Automated LSB analysis for PNG/BMP (try zsteg -a image.png)
stegsolve — Visual analysis, toggle bit planes
Stegano — Python library: pip install stegano
Pixel Value Encoding
from PIL import Image
img = Image.open('image.png')
pixels = list(img.getdata())
flag = ''.join(chr(p[0]) for p in pixels if 32 <= p[0] < 127)
Image Format Tricks
PNG chunks:
pngcheck -v image.png
python3 -c "
import struct
with open('image.png', 'rb') as f:
data = f.read()
# Look for custom chunks (tEXt, zTXt, iTXt)
idx = data.find(b'tEXt')
if idx > 0:
print(data[idx:idx+100])
"
JPEG markers:
python3 -c "
with open('image.jpg', 'rb') as f:
data = f.read()
eof = data.find(b'\xff\xd9')
if eof > 0 and eof + 2 < len(data):
print(f'Data after EOF: {data[eof+2:eof+102]!r}')
"
BMP:
xxd image.bmp | head -5
GIF:
ffmpeg -i image.gif frame_%03d.png
identify -verbose image.gif
Image Dimension Tricks
Wrong dimensions in header:
import struct, zlib
with open('image.png', 'rb') as f:
data = bytearray(f.read())
struct.pack_into('>I', data, 20, 1000)
with open('fixed.png', 'wb') as f:
ihdr_data = data[12:29]
crc = zlib.crc32(ihdr_data) & 0xffffffff
struct.pack_into('>I', data, 29, crc)
f.write(data)
Steghide (JPEG/WAV/BMP/AU)
steghide extract -sf file.jpg -p "password"
steghide info file.jpg
stegcracker file.jpg wordlist.txt
stegseek file.jpg wordlist.txt
Visual Steganography
- Flags as tiny/low-contrast text in images
- Black text on dark background, white on light
- Check ALL corners and edges at full resolution
- Profile pictures and avatars are common hiding spots
- Zoom in on what looks like solid color areas
Audio Steganography
Spectrogram Analysis
sox audio.wav -n spectrogram -o spectrogram.png
SSTV (Slow-Scan Television)
qsstv
pip install sstv
sstv -d audio.wav -o output.png
DTMF Tones
multimon-ng -t wav -a DTMF audio.wav
sox audio.wav -t raw -r 22050 -e signed-integer -b 16 -c 1 - | multimon-ng -t raw -a DTMF -
Audio LSB
import wave
import struct
wav = wave.open('audio.wav', 'rb')
frames = wav.readframes(wav.getnframes())
samples = struct.unpack(f'<{len(frames)//2}h', frames)
bits = ''.join(str(s & 1) for s in samples)
data = bytes(int(bits[i:i+8], 2) for i in range(0, len(bits), 8))
print(data[:100])
Morse Code
pip install morse-audio-decoder
Text/Data Steganography
Whitespace Stego
python3 -c "
with open('text.txt', 'rb') as f:
data = f.read()
# Zero-width space: U+200B, Zero-width joiner: U+200D
for b in data:
if b in [0xe2]: # Start of multi-byte UTF-8
print(f'Found zero-width char at position')
"
snow -C -p "password" stego.txt
Unicode Stego
- Homoglyph substitution (Cyrillic а vs Latin a)
- Invisible Unicode characters between visible text
- Variation selectors and combining characters
File Concatenation / Polyglots
binwalk suspicious_file
foremost suspicious_file
unzip image.png
Network Steganography
PCAP Hidden Data
- DNS queries encoding data in subdomain labels
- ICMP payloads carrying hidden messages
- TCP sequence numbers encoding data
- HTTP headers with encoded data
- TLS certificate fields
DNS Exfiltration
tshark -r capture.pcap -Y "dns.qry.name" -T fields -e dns.qry.name | \
sed 's/\.example\.com//' | tr -d '\n' | base64 -d
Common Patterns
| Clue | Technique |
|---|
| "Look closer" / "More than meets the eye" | LSB or visual stego |
| Image looks normal but file is huge | Embedded/appended data |
| Audio with static/noise sections | Spectrogram or SSTV |
| "Password protected" | Steghide with password |
| PNG with wrong colors or glitches | Bit plane analysis |
| Text file with trailing whitespace | Whitespace stego |
| Challenge says "nothing to see here" | Definitely stego |