Introduction
Steganography in CTF challenges is the art of finding data hidden inside files that appear completely ordinary at first glance: images, audio files, even PDFs. Unlike cryptography, which scrambles data, steganography conceals the very existence of the message.
CTF forensics categories are full of these challenges. A PNG that looks like a solid red rectangle, a JPEG of a Japanese woodblock print, a BMP embedded in a disk image. All of them have data tucked away in places the human eye never checks: unused bit planes, EXIF chunks, appended ZIP archives, or the least-significant bits of every pixel.
This guide covers the six tools you will reach for most often: what file types each one handles, how to install it, and the exact commands to run. Each tool section links directly to the picoCTF writeup where it was the key to solving the challenge, so you can see it working on a real example.
file suspicious.png and strings suspicious.png | grep -i pico. Sometimes the flag is sitting in plaintext metadata and no specialist tool is needed.zsteg: PNG and BMP bit-plane scanner
zsteg is the fastest way to extract data hidden in the least-significant (or most-significant) bits of PNG and BMP pixel values. It automatically checks dozens of channel/bit-depth/endianness combinations and prints anything that looks like text, so one command often reveals the flag outright.
Install
sudo apt install ruby ruby-devsudo gem install zsteg
Basic usage
zsteg image.png # scan all common channelszsteg -a image.png # exhaustive scan (slower, catches edge cases)
The output lists each channel it checks (e.g. b1,rgba,lsb,xy) alongside anything it extracts. Scan the text column for readable strings or a Base64 blob and copy it out for further decoding.
What to look for
If you see a long Base64 string in one of the channels, pipe it straight through base64 -d. If the output looks like compressed data, try zsteg -e "b1,rgba,lsb,xy" image.png | file - to identify the format before saving it.
Challenges that use zsteg
Stepic: Python LSB steganography
Stepic is a Python library and command-line tool that hides and extracts text using the standard LSB-of-RGBA algorithm. It is simpler than zsteg and only handles that one encoding, but if a challenge was created specifically with Stepic then it is the right tool to reach for, as zsteg may not recognise the exact byte layout.
Install
pip install stepic# or inside a virtual environment:python3 -m venv venv && source venv/bin/activatepip install stepic
Usage
stepic -i image.png -d # decode (extract hidden text)stepic -i cover.png -e -s secret.txt -o output.png # encode
Challenges that use Stepic
steghide: JPEG and BMP passphrase extraction
steghide embeds data inside JPEG and BMP files using a passphrase-based scheme. Unlike LSB tools, steghide modifies the DCT coefficients of JPEGs rather than raw pixel bits, making the embedding statistically harder to detect. In CTF challenges the passphrase is either blank (press Enter when prompted) or hidden somewhere else in the challenge: check IRC logs, metadata, or another file.
Install
sudo apt install steghide
Usage
steghide extract -sf image.jpg # prompts for passphrase (try blank first)steghide extract -sf image.jpg -p '' # blank passphrase, non-interactivesteghide extract -sf image.jpg -p 'secretpassword'steghide info image.jpg # check if any payload is embedded
After extraction, steghide writes a file (often named in the embed step). Read it with cat or inspect it with file to determine the next step.
Challenges that use steghide
stegcracker: brute-force steghide passwords
stegcracker automates passphrase brute-forcing for steghide. You hand it an image and a wordlist and it tries every password until extraction succeeds. It is the steganography equivalent of Hashcat or John the Ripper.
Install
pip3 install stegcracker# requires steghide to be installed as wellsudo apt install steghide
Usage
stegcracker image.jpg wordlist.txt# Common wordlists to try:stegcracker image.jpg /usr/share/wordlists/rockyou.txt# Specify output file name:stegcracker image.jpg wordlist.txt --output extracted.txt
If the wordlist doesn't work, look for clues in the challenge about how the password was constructed. In some challenges the password follows a predictable pattern (for example, concatenated words from a specific category) and you can generate a custom wordlist with a small Python script.
# Example: generate candidate passwords from a list of wordspython3 -c "words = open('words.txt').read().splitlines()for a in words:for b in words:print('prefix' + a + b)" > custom_wordlist.txtstegcracker image.bmp custom_wordlist.txt
Challenges that use stegcracker
Stegsolve: bit-plane visualiser
Stegsolve is a Java GUI tool that lets you visually inspect every bit plane of an image. While zsteg extracts text data automatically, Stegsolve shines when the hidden content is encoded in the most-significant bits (MSB) rather than the LSB, or when you need to visualise what the different planes look like to understand the encoding scheme.
Its Analyse > Data Extract panel is the main workhorse: you select which colour channels and which bit positions to include, choose row or column order, and Stegsolve assembles the bits into a byte stream you can save to a file or search with strings.
Install
wget http://www.caesum.com/handbook/Stegsolve.jar -O stegsolve.jarchmod +x stegsolve.jarjava -jar stegsolve.jar
Extracting MSB data
- Open the image via File > Open.
- Go to Analyse > Data Extract.
- In the bit selection grid, tick Red 7, Green 7, Blue 7 (bit 7 = MSB).
- Set Bit Order to MSB First.
- Click Preview and look for readable text at the top.
- Use Save Text then
grep picoto isolate the flag.
Challenges that use Stegsolve
binwalk: embedded file carving
binwalk is not a steganography tool in the traditional sense. It does not look at pixel bit planes. Instead, it scans any file for known file-format magic bytes (ZIP signatures, PNG headers, ELF headers, etc.) and reports every embedded file it finds, along with its byte offset. When a PNG has a ZIP archive stitched on after the image data ends, binwalk will catch it instantly.
Install
sudo apt install binwalk
Usage
binwalk image.png # list embedded files and their offsetsbinwalk -e image.png # automatically extract everything foundbinwalk -Me image.png # recursive extraction (extract from extracted files too)
After running binwalk -e image.png, check the created _image.png.extracted/ directory for the carved-out files. If the extracted archive is password-protected, look elsewhere in the challenge for the key.
You can also extract manually if automatic extraction fails. Use dd with the byte offset from binwalk's output:
# Example: extract ZIP starting at offset 39804dd if=image.png bs=1 skip=39804 of=embedded.zipunzip embedded.zip
Challenges that use binwalk
Quick reference
Not sure which tool to start with? Use this table as a decision guide based on the file type you receive.
Files: PNG, BMP
Technique: LSB / MSB pixel bits
Files: PNG
Technique: LSB-of-RGBA (Python)
Files: JPEG, BMP
Technique: DCT coefficient embedding
Files: JPEG, BMP
Technique: Brute-force steghide passphrase
Files: PNG, BMP, JPEG
Technique: Visual bit-plane inspection
Files: Any binary file
Technique: Embedded file carving
Recommended first-pass workflow
file image.pngto confirm the format is what the extension says.strings image.png | grep -i picoto grab any plaintext flag hiding in metadata.binwalk image.pngto check for embedded archives or other files.- PNG? Run
zsteg image.png. If nothing, tryzsteg -a. - JPEG/BMP? Run
steghide extract -sf image.jpg -p ''first (blank passphrase). - Still nothing? Open in Stegsolve and cycle through planes manually.
- Password-protected steghide? Try stegcracker with rockyou.txt, or build a custom wordlist from challenge clues.