Steganography detection (steganalysis) is the practice of identifying hidden data within carrier files and extracting that data for analysis. For malware analysts, this means applying a combination of structural analysis, entropy measurement, statistical tests, and format-specific extraction methods to recover payloads that attackers have concealed in images. The goal is not just detection but extraction: obtaining the hidden content in a form that can be analysed, deobfuscated, and used to generate indicators of compromise.
Steganography creates an information asymmetry. Attackers choose the embedding technique, the carrier format, the encoding scheme, and any encryption applied to the payload. Defenders must identify that hidden data exists, determine which technique was used, extract the data successfully, and handle any post-extraction encoding or encryption. No single tool or technique catches everything. Effective steganalysis requires a methodical approach that applies multiple detection methods in sequence, using the results of each to guide subsequent analysis.
Technique categories
Steganographic techniques cluster into categories based on where and how they embed data. Understanding these categories shapes the detection approach.
Starting point: structural analysis
Begin every analysis with structural examination. This catches the simplest techniques and provides context for more sophisticated analysis.
For PNG files, parse the chunk sequence. A valid PNG contains IHDR (header), one or more IDAT (image data), and IEND (end marker), plus optional ancillary chunks. Flag any data after IEND. Flag private chunks (those with lowercase second letters in the type code). Flag ancillary chunks with unusually large sizes or high-entropy content.
For JPEG files, locate the EOI marker (0xFFD9) and examine anything following it. Legitimate JPEG software does not append data after EOI. Also examine EXIF metadata for embedded code patterns: strings containing eval, base64, exec, or script syntax suggest injection rather than photography metadata.
For BMP files, the header specifies exact file size. Compare this against actual file size. BMP has no termination marker, so appended data detection relies entirely on this size comparison. For GIF files, the trailer byte 0x3B marks the end. As with other formats, examine anything appended afterward.
The bytes immediately following an image termination often reveal the technique. GhostPoster variants used delimiter markers: three equals signs for Firefox extensions, four greater-than symbols for Chrome. Other campaigns use Base64-encoded content, hex-encoded data, or raw encrypted bytes. The character set of appended data is your first clue to the encoding scheme.
Entropy analysis
Entropy measurement quantifies randomness in data. Clean image regions have structured entropy: gradients produce low entropy, textures produce medium entropy, and edges produce localised high entropy. Encrypted or compressed payloads have entropy approaching the theoretical maximum of 8.0 bits per byte.
Calculate Shannon entropy across different file regions. The overall file entropy provides a baseline. Most photographs have entropy between 7.0 and 7.8 due to compression. Synthetic images and icons often have lower entropy. Overall entropy above 7.9 warrants investigation.
Segment-specific entropy isolates anomalies. Calculate entropy for appended data separately from image data. Calculate entropy for individual PNG chunks. A chunk with entropy above 7.9 embedded in an image with overall entropy of 7.2 stands out.
IDAT chunk entropy catches IcedID-style embedding. This malware family embeds RC4-encrypted shellcode within PNG IDAT chunks. The encrypted payload has entropy approaching 8.0, significantly higher than typical compressed image data. Parsing IDAT chunks and measuring their individual entropy can flag this technique even without knowing the decryption key.
Entropy thresholds are guidelines, not absolutes. Values above 7.8 suggest encrypted or highly compressed content. Values between 7.0 and 7.8 are typical for compressed images. Values below 6.0 suggest plaintext or structured data. An icon file with entropy of 7.9 is more suspicious than a photograph with the same value. Context matters.
Statistical steganalysis for LSB detection
Least Significant Bit embedding produces statistical artefacts that specialised tests can detect. These methods apply specifically to pixel-based steganography.
Chi-square analysis examines pairs of pixel values. In clean images, adjacent values (like 254 and 255) occur with frequencies determined by the image content. LSB embedding forces these pairs toward equal frequency because embedding a 0 or 1 bit converts values between pair members. The chi-square statistic measures deviation from expected pair frequencies; high values indicate likely embedding.
RS analysis (Regular-Singular) exploits how LSB changes affect pixel group "smoothness." The analysis flips LSBs in pixel groups and measures whether groups become more regular (smoother) or more singular (noisier). Clean images show characteristic regular-singular ratios. Embedded data disrupts these ratios in predictable ways. RS analysis can estimate both presence and quantity of hidden data.
Sample Pair Analysis (SPA) refines chi-square testing using the observation that embedding creates specific patterns in how values transition between neighbouring pixels. SPA achieves higher accuracy than basic chi-square on images with non-uniform content.
Format-specific extraction
When structural or statistical analysis indicates hidden content, extraction requires technique-specific methods.
For appended data, locate the format termination marker and extract all bytes following it. For PNG, find the IEND chunk and extract everything after the four-byte CRC. For JPEG, find 0xFF 0xD9 and extract following bytes. The extracted data may require additional decoding.
For PNG chunks, parse the chunk structure. Each chunk has a four-byte length, four-byte type, data of the specified length, and four-byte CRC. Extract the data portions of suspicious chunks. For tEXt chunks, the format is keyword, null byte, text. For zTXt chunks, the text is zlib-compressed. For private chunks, extract raw bytes.
PNG chunk structure:
[4 bytes: length] [4 bytes: type] [N bytes: data] [4 bytes: CRC]
Critical chunks: IHDR → IDAT → IEND
Suspicious: tEXt with eval/exec, private chunks (xXxx),
IDAT with entropy > 7.9For pixel value extraction (as used by GHOSTPULSE v2), read RGB values as raw bytes, grouping them into 16-byte blocks. The first four bytes of each block contain a CRC32 hash of the remaining 12 bytes. Only blocks where the CRC validates contain payload data. Extraction requires iterating through pixel values in scan order, assembling blocks, validating CRC32, and concatenating the 12 payload bytes from valid blocks.
For LSB extraction, the challenge is determining the parameters: which colour channels, which bit positions, and which pixel traversal order. Without knowing parameters, try common configurations: RGB LSB in row order, then column order, then individual channels. Tools like zsteg automate this with flags to try all combinations.
| Technique | Detection Method | Extraction Approach |
|---|---|---|
| Appended EOF | File size vs expected size | Extract bytes after termination marker |
| Delimiter markers | Scan for known patterns | Extract bytes after delimiter sequence |
| PNG chunk abuse | Parse chunk structure, flag anomalies | Extract chunk data, decompress if zTXt |
| IDAT embedding | High entropy in IDAT, marker scanning | Locate marker, extract, decompress, decrypt |
| Pixel-level (GHOSTPULSE v2) | CRC validation patterns in pixel data | Extract RGB bytes, validate blocks, concatenate |
| LSB encoding | Chi-square, RS analysis, SPA | Extract low bits in correct order |
| Alpha channel | Alpha values deviating from 255 | Apply encoding formula to alpha pairs |
| Polyglot | Multiple format parsers validate | Extract according to secondary format |
Post-extraction processing
Extracted data is rarely ready for analysis. Attackers layer encoding and encryption to frustrate examination.
Base64 appears frequently, sometimes with character substitutions. GhostPoster swapped uppercase and lowercase letters and exchanged digits 8 and 9 before Base64 encoding. Detecting modified Base64 requires recognising the character set pattern and trying common substitution reversals.
XOR encryption is ubiquitous. Keys range from single bytes to multi-byte sequences. GhostPoster used the extension runtime ID as an XOR key. GHOSTPULSE uses four-byte keys extracted from the image itself. Without the key, XOR-encrypted data appears random. With common keys or key recovery methods, decryption is straightforward.
Do not assume extraction reveals the final payload. Steganographic concealment is typically one layer in a multi-layer chain. The extracted data may be XOR-encrypted, which reveals Base64 content, which decodes to compressed data, which decompresses to obfuscated JavaScript. Each layer requires its own decoder. Premature analysis of intermediate layers wastes time on incomplete intelligence.
Successful decoding often reveals further obfuscation. JavaScript payloads may be obfuscated with string concatenation, character code arrays, or esoteric encodings. PowerShell payloads may use Base64-encoded command parameters, compressed streams, or SecureString manipulation. The extracted steganographic payload is typically just the first layer; full analysis requires recursive deobfuscation.
Post-extraction payloads often use the same script obfuscation techniques covered in What is Script Obfuscation? and face the same multi-layer problem as any other obfuscated malware sample.
Tool selection
Individual tools address individual steps. Binwalk scans files for embedded signatures. StegExpose combines chi-square, RS, and sample pair analysis for LSB detection. pngcheck validates PNG structure. zsteg extracts data from multiple bit-plane configurations. These are useful when you know exactly what you are looking for and need fine-grained control over a single step.
The problem is that steganographic analysis rarely ends at extraction. The extracted payload is almost always obfuscated — XOR-encrypted, Base64-encoded, compressed, wrapped in string concatenation or esoteric JavaScript. A typical real-world sample requires chaining 3-5 tools manually, interpreting intermediate output at each stage, and knowing which decoder to apply next. This is where most analysis stalls or produces incomplete results.
KlaroSkope eliminates the tool-chaining problem entirely. Submit a suspicious image or paste extracted code, and the platform runs the full pipeline automatically: steganographic extraction, multi-layer deobfuscation (over 100 decoders, up to 25 layers deep), IOC extraction with C2 URLs and encryption keys, MITRE ATT&CK mapping, YARA and Sigma rule templates, and a complete analysis report in Markdown. The entire process completes in under a minute on the free tier.
Skip the tool-chaining. Get extraction, deobfuscation, IOCs, MITRE mapping, and detection rules in one automated pass. Analyse a Sample Free →
Practical workflow
Synthesise these techniques into a repeatable process.
- Step 1: Structural examination. Parse the image format. Check for data beyond termination markers. Examine metadata fields for injection. Flag anomalous chunks.
- Step 2: Size and entropy analysis. Compare file size against expected size for dimensions and format. Calculate overall and segment-specific entropy. Flag files with unexpected size overhead or high-entropy regions.
- Step 3: Statistical testing. If pixel manipulation is suspected, run chi-square, RS, or combined detectors. High detection scores warrant LSB extraction attempts across multiple parameter configurations.
- Step 4: Extraction. Based on findings, apply the appropriate extraction method. Try multiple methods if the technique is unclear.
- Step 5: Post-extraction analysis. Examine extracted bytes for encoding patterns. Apply decoding transformations. If the result is obfuscated code, continue to script deobfuscation. KlaroSkope automates steps 5 and 6 entirely: paste extracted content and it handles multi-layer deobfuscation through IOC generation in a single pass.
- Step 6: IOC generation. From successfully decoded payloads, extract indicators: URLs, domains, IP addresses, file hashes, registry keys, encryption keys. Generate YARA rules, Sigma rules, and MITRE ATT&CK mappings targeting both the carrier and the revealed payload.
Frequently Asked Questions
What tools do malware analysts use to detect steganography?
How can I tell if an image contains hidden malware without knowing the embedding technique?
What is the difference between chi-square and RS analysis for LSB detection?
Why is entropy analysis useful for finding hidden payloads?
How do attackers prevent their steganographic payloads from being detected?
Continue Learning
Ready to decode?
See KlaroSkope transform obfuscated scripts into actionable intelligence.
Try It Free