Steganography

Discover hidden data in images, audio, and other file types

Introduction to Steganography

Steganography is the practice of concealing messages or information within other non-secret data. Unlike cryptography, which scrambles data to make it unreadable, steganography hides the very existence of the data.

Types of Steganography
  • Image Steganography: Hiding data within image files (PNG, JPEG, BMP)
  • Audio Steganography: Concealing information in audio files (WAV, MP3)
  • Video Steganography: Embedding data within video files
  • Text Steganography: Using whitespace, formatting, or linguistic patterns
  • Network Steganography: Hiding data in network protocol headers
Common Techniques
  • LSB (Least Significant Bit): Replacing the least significant bits of pixels
  • Metadata Embedding: Hiding data in EXIF or other metadata fields
  • Frequency Domain: Hiding data in DCT coefficients (JPEG)
  • Palette Manipulation: Modifying color palettes in indexed images
  • File Appending: Concatenating data at the end of files

Image Steganography

Basic Image Analysis
# Check file format and properties
file image.png
identify image.png             # ImageMagick
exiftool image.png             # Metadata analysis

# View hex dump
xxd image.png | head
xxd image.png | tail           # Check for appended data

# Extract strings
strings image.png
strings -n 8 image.png

# Compare file size with expected size
ls -lh image.png
steghide - Hide/Extract Data

Steghide is a popular tool for embedding and extracting data from JPEG and BMP files.

# Extract hidden data (without password)
steghide extract -sf image.jpg

# Extract with password
steghide extract -sf image.jpg -p password123

# Get information about embedded data
steghide info image.jpg

# Embed data into an image
steghide embed -cf image.jpg -ef secret.txt -p password123

# Try common passwords
for pass in password 123456 admin secret; do
  steghide extract -sf image.jpg -p $pass 2>/dev/null && echo "Password found: $pass" && break
done
zsteg - PNG/BMP Analysis

Zsteg detects hidden data in PNG and BMP files using various LSB techniques.

# Analyze image for hidden data
zsteg image.png

# All detection methods
zsteg -a image.png

# Extract specific bits
zsteg -E b1,rgb,lsb image.png

# Save extracted data
zsteg -E b1,rgb,lsb image.png > extracted.txt

# Check all color channels
zsteg -E b1,r,lsb image.png
zsteg -E b1,g,lsb image.png
zsteg -E b1,b,lsb image.png
stegsolve - Visual Analysis Tool

Stegsolve is a Java-based GUI tool for analyzing images visually.

# Launch stegsolve
java -jar stegsolve.jar

# Features:
# - Browse through color planes
# - Extract LSB data
# - Analyze bit planes
# - Image combiner
# - Stereogram solver
LSB Extraction with Python
from PIL import Image

def extract_lsb(image_path):
    img = Image.open(image_path)
    pixels = img.load()
    width, height = img.size
    
    binary_data = ""
    for y in range(height):
        for x in range(width):
            pixel = pixels[x, y]
            # Extract LSB from each color channel
            r, g, b = pixel[:3]
            binary_data += str(r & 1)
            binary_data += str(g & 1)
            binary_data += str(b & 1)
    
    # Convert binary to text
    text = ""
    for i in range(0, len(binary_data), 8):
        byte = binary_data[i:i+8]
        text += chr(int(byte, 2))
    
    return text

# Usage
hidden_text = extract_lsb("image.png")
print(hidden_text)

Advanced Image Techniques

Analyzing Color Channels
# Using ImageMagick to split color channels
convert image.png -separate channel_%d.png

# Results in:
# channel_0.png (Red)
# channel_1.png (Green)
# channel_2.png (Blue)

# View individual channels
display channel_0.png

# Analyze bit planes
for i in {0..7}; do
  convert image.png -depth 8 -white-threshold $((2**i))% -black-threshold $((2**i))% plane_$i.png
done
EXIF Data Analysis
# Extract all EXIF metadata
exiftool image.jpg

# Extract specific fields
exiftool -Comment image.jpg
exiftool -UserComment image.jpg
exiftool -ImageDescription image.jpg

# Export all metadata to JSON
exiftool -json image.jpg > metadata.json

# Remove all metadata
exiftool -all= image.jpg

# Check for GPS coordinates
exiftool -GPS* image.jpg
Outguess - JPEG Steganography
# Extract hidden data
outguess -r image.jpg output.txt

# Extract with key
outguess -k "password" -r image.jpg output.txt

# Embed data
outguess -d secret.txt image.jpg stego_image.jpg
Detecting Modified Images
# Compare original and modified images
compare original.png modified.png difference.png

# Calculate image entropy (detect randomness)
convert image.png -format "%[entropy]" info:

# Error Level Analysis (ELA)
# Higher compression artifacts indicate modification
convert image.jpg -quality 95 resaved.jpg
compare image.jpg resaved.jpg -compose src ela_result.png

Audio Steganography

Audio File Analysis
# Get audio file information
file audio.wav
mediainfo audio.wav
soxi audio.wav                # SoX audio info

# View waveform
audacity audio.wav

# Extract strings
strings audio.wav

# Check for appended data
xxd audio.wav | tail -n 50
Spectrogram Analysis

Hidden messages are often embedded in the frequency domain, visible in spectrograms.

# Generate spectrogram with SoX
sox audio.wav -n spectrogram -o spectrogram.png

# View spectrogram in Audacity
# Analyze -> Plot Spectrum
# Or change to Spectrogram view

# Generate with detailed settings
sox audio.wav -n spectrogram -x 3000 -y 513 -z 120 -w Kaiser -o spectrogram.png
LSB Audio Extraction
# Using steghide for WAV files
steghide extract -sf audio.wav

# Python script for LSB extraction
# Create a file: extract_audio_lsb.py
import wave
import struct

def extract_lsb_audio(wav_file):
    audio = wave.open(wav_file, 'r')
    frames = audio.readframes(-1)
    audio_data = struct.unpack(f'{len(frames)//2}h', frames)
    
    # Extract LSB from each sample
    binary_data = ''.join([str(sample & 1) for sample in audio_data])
    
    # Convert to text
    message = ''
    for i in range(0, len(binary_data), 8):
        byte = binary_data[i:i+8]
        if len(byte) == 8:
            message += chr(int(byte, 2))
    
    return message

# Usage
hidden_message = extract_lsb_audio('audio.wav')
print(hidden_message)
DTMF Tone Analysis
# Decode DTMF tones (phone dial tones)
multimon-ng -a DTMF audio.wav

# Using Python
# pip install dtmf-decoder

File-Based Steganography

Detecting Hidden Archives
# Check for embedded ZIP files
binwalk image.png
binwalk -e image.png           # Extract embedded files

# Check for RAR archives
binwalk -D 'rar:rar' image.png

# Manual extraction by offset
dd if=image.png of=extracted.zip bs=1 skip=12345

# Try to extract with unzip
unzip image.png
7z x image.png
Polyglot Files

Files that are valid in multiple formats simultaneously.

# Check if file is a polyglot
file image.png
unzip -l image.png
pdfinfo image.png

# Create a polyglot (PNG + ZIP)
cat image.png archive.zip > polyglot.png

# Extract the ZIP portion
unzip polyglot.png
Analyzing File Structure
# Compare actual size vs expected size
identify -verbose image.png | grep -i filesize
ls -lh image.png

# Check for trailing data after file end
# PNG ends with: 00 00 00 00 49 45 4E 44 AE 42 60 82
# JPEG ends with: FF D9

# Find JPEG end marker
xxd image.jpg | grep "ffd9"

# Extract data after end marker
# If FFD9 is at offset 50000:
dd if=image.jpg of=hidden.data bs=1 skip=50002
Foremost for File Carving
# Carve all file types
foremost -i image.png -o carved_output/

# Specify file types
foremost -t jpg,png,zip,pdf -i image.png -o output/

Text Steganography

Whitespace Steganography
# Detect hidden spaces/tabs
cat -A file.txt                # Shows tabs as ^I, spaces as visible

# Convert tabs to visible characters
sed 's/\t/[TAB]/g' file.txt

# Detect trailing whitespace
cat -A file.txt | grep " $"

# Extract binary from whitespace
# Space = 0, Tab = 1
Unicode Steganography
# Check for zero-width characters
# U+200B (Zero Width Space)
# U+200C (Zero Width Non-Joiner)
# U+200D (Zero Width Joiner)
# U+FEFF (Zero Width No-Break Space)

# Detect in file
hexdump -C file.txt | grep "e2 80"

# Python script to detect
python3 -c "
text = open('file.txt', 'r', encoding='utf-8').read()
zwc = [c for c in text if c in '\u200b\u200c\u200d\ufeff']
print(f'Found {len(zwc)} zero-width characters')
print(''.join(['0' if c=='\u200b' else '1' for c in zwc]))
"
Homoglyph Detection
# Detect look-alike characters
# Latin 'a' vs Cyrillic 'а' (U+0430)
# Latin 'o' vs Greek 'ο' (U+03BF)

# Show unicode codepoints
xxd -p file.txt

# Python script
python3 -c "
text = open('file.txt', 'r', encoding='utf-8').read()
for i, char in enumerate(text):
    print(f'{i}: {char} (U+{ord(char):04X})')
"
Letter Frequency Analysis
# Analyze first letters of each line
awk '{print substr($0,1,1)}' file.txt | tr -d '\n'

# Extract first word of each line
awk '{print $1}' file.txt

# Get capital letters only
grep -o '[A-Z]' file.txt | tr -d '\n'

Automated Steganalysis Tools

StegCracker - Password Bruteforce
# Install
pip3 install stegcracker

# Bruteforce steghide password
stegcracker image.jpg wordlist.txt

# Using rockyou.txt
stegcracker image.jpg /usr/share/wordlists/rockyou.txt
StegExpose - Steganalysis
# Download and run
java -jar StegExpose.jar image.jpg

# Batch analysis
java -jar StegExpose.jar directory/
Stegseek - Fast Steghide Cracker
# Much faster than stegcracker
stegseek image.jpg wordlist.txt

# With output file
stegseek image.jpg wordlist.txt -xf output.txt
Aletheia - Image Steganalysis
# Install
pip3 install aletheia

# Detect steganography
aletheia.py spa image.png

# LSB matching detection
aletheia.py lsbm-sim image.png
Creating Your Own Analysis Script
#!/usr/bin/env python3
import os
import subprocess

def analyze_image(filename):
    print(f"[+] Analyzing {filename}")
    
    # Check file type
    os.system(f"file {filename}")
    
    # Extract strings
    os.system(f"strings {filename} > {filename}_strings.txt")
    
    # Check metadata
    os.system(f"exiftool {filename}")
    
    # Run binwalk
    os.system(f"binwalk {filename}")
    
    # Try zsteg for PNG
    if filename.endswith('.png'):
        os.system(f"zsteg -a {filename}")
    
    # Try steghide
    os.system(f"steghide info {filename} 2>/dev/null")
    
    print(f"[+] Analysis complete for {filename}\n")

# Usage
analyze_image("suspicious.png")

Steganography Analysis Checklist

For Image Files
  • Check file type and format
  • Extract and analyze metadata (EXIF)
  • Run strings command
  • Check file size vs expected size
  • Look for appended data at end of file
  • Analyze with binwalk
  • Try steghide extraction
  • Run zsteg (PNG/BMP)
  • Analyze color channels separately
  • View in stegsolve
  • Check LSB bit planes
  • Try common passwords
For Audio Files
  • Check file format and metadata
  • Generate and view spectrogram
  • Extract strings
  • Check for appended data
  • Try steghide extraction
  • Analyze DTMF tones
  • Listen to audio for anomalies
For Text Files
  • Check for whitespace patterns
  • Look for zero-width characters
  • Detect homoglyphs
  • Analyze first letters of lines
  • Check Unicode codepoints

Practice Challenges

Beginner Level
  • Hidden in Pixels
    Extract LSB data from images
  • Metadata Mystery
    Find secrets in EXIF data
  • Sound of Silence
    Discover hidden spectrogram messages
Advanced Level
  • Polyglot Puzzle
    Extract from multi-format files
  • Channel Surfer
    Analyze complex color channel hiding
  • Unicode Cipher
    Decode zero-width character messages