| name | image-steganography |
| description | Analyze images for hidden data using steganography techniques. Use this skill whenever the user mentions image forensics, CTF challenges with images, hidden messages in pictures, PNG/JPEG/GIF analysis, LSB extraction, metadata extraction, or any task involving finding concealed content in image files. Trigger for file extensions like .png, .jpg, .jpeg, .gif, .bmp, .apng, or when users ask about steganography, hidden payloads, or image-based data hiding. |
Image Steganography Analysis
A systematic approach to finding hidden data in image files, optimized for CTF challenges and forensic analysis.
Quick Triage Workflow
Start here for any image steganography task. Run these checks in order:
1. Validate and Inspect Structure
file <image-file>
magick identify -verbose <image-file>
For PNG specifically:
pngcheck -v <image-file>
2. Extract Metadata and Strings
exiftool -a -u -g1 <image-file>
strings -n 6 <image-file> | head -50
3. Check for Embedded Content
binwalk <image-file>
tail -c 1000 <image-file> | xxd
4. Branch by File Type
- PNG/BMP: Run LSB/bit-plane analysis (see below)
- JPEG: Check metadata + DCT-domain tools
- GIF/APNG: Extract and analyze frames
LSB and Bit-Plane Analysis (PNG/BMP)
Primary Tool: zsteg
zsteg -a <image-file>
This enumerates many extraction patterns automatically. Look for:
- Readable text in output
- Base64-encoded strings
- Hex patterns that decode to ASCII
Manual Channel Isolation
If zsteg doesn't find anything, try isolating specific channels:
magick <image-file> -channel R -negate -evaluate multiply 128 -channel RGB -negate red_lsb.png
magick <image-file> -channel A -separate alpha.png
Common Patterns to Check
- Single channel LSB - payload in R, G, B, or A only
- Alpha-only - completely invisible in RGB view
- Compressed payload - extract then decompress (gzip, zlib, base64)
- XOR between planes - XOR two bit planes together
PNG Chunk Analysis
PNG files are chunked. Hidden data often lives in:
- Extra bytes after
IEND chunk
- Non-standard ancillary chunks
- Text chunks:
tEXt, iTXt, zTXt
- ICC profile:
iCCP
- EXIF data:
eXIf
Commands
pngcheck -vp <image-file>
magick identify -verbose <image-file> | grep -i "additional data"
exiftool -a -u -g1 <image-file> | grep -i "text\|comment\|description"
Fixing Corrupted PNGs
If pngcheck reports CRC errors:
- Note the offset from the error message
- Use a hex editor to inspect the chunk
- Sometimes removing the corrupted chunk fixes the file
- Try:
pngfix <image-file> (ImageMagick tool)
JPEG Analysis
JPEG uses DCT compression, so LSB techniques don't apply directly.
Quick Checks
exiftool <image-file>
strings -n 6 <image-file> | head
binwalk <image-file>
High-Signal Locations
- EXIF/XMP/IPTC metadata - often contains hidden text
- Comment segment (COM) - check with
exiftool -Comment
- APP segments - vendor data, sometimes payloads
DCT-Domain Tools
If metadata is clean, try stego tools:
outguess -e <image-file> <output-file>
stegseek <image-file> <wordlist-file>
Animated Images (GIF/APNG)
Extract Frames
ffmpeg -i <animated-file> frame_%04d.png
gifsicle --explode <animated-file>
Frame Differencing
Hidden data often appears only when comparing frames:
magick frame_0001.png frame_0002.png -compose difference -composite diff.png
python scripts/extract_frames.py <animated-file>
python scripts/diff_frames.py
Pixel Count Encoding (APNG)
Some challenges encode each byte as the count of a specific color per frame:
python scripts/extract_pixel_counts.py <frames-directory> <target-color>
Example target colors: (255, 0, 255) for magenta, (0, 255, 0) for green.
Password-Protected Embedding
StegHide
Supports JPEG, BMP, WAV, AU:
steghide info <image-file>
steghide extract -sf <image-file> --passphrase 'password'
stegcracker <image-file> <wordlist-file>
StegPy
Supports PNG, BMP, GIF, WebP, WAV:
stegpy -f <image-file> -w <wordlist-file>
Common Pitfalls
- Don't skip triage - 50%+ of challenges are metadata or trailing bytes
- Check all channels - not just RGB, also alpha
- Decompress extracted data - payloads are often gzip/zlib/base64 encoded
- Try multiple tools - zsteg might miss what manual extraction finds
- Look for patterns - repeated strings, flag formats, base64 blocks
Tool Installation
sudo apt install zsteg pngcheck exiftool binwalk ffmpeg gifsicle
sudo apt install steghide
pip install stegcracker
pip install stegpy
sudo apt install imagemagick
Quick Reference by Symptom
| Symptom | Likely Cause | Tool |
|---|
| Trailing data after IEND | Extra bytes | tail, xxd |
| CRC errors in PNG | Corrupted chunk | pngcheck, hex editor |
| No LSB findings | Metadata or DCT | exiftool, binwalk |
| Multiple frames | Frame-based hiding | ffmpeg, diff_frames.py |
| Password prompt | Encrypted embedding | steghide, stegcracker |
| Clean metadata, clean LSB | DCT-domain | outguess, stegseek |
Next Steps After Finding Data
- Decode if encoded - base64, hex, rot13
- Decompress if compressed - gzip, zlib, zip
- Check for flag format -
flag{}, CTF{}, FLAG{}
- Look for partial data - might need to combine multiple sources
- Verify integrity - checksums, file headers
Resources