Steganography in Darknet Listings: Detecting Hidden Payloads in Vendor Product Images
Vendor image galleries on darknet markets are a soft target for payload delivery, and most buyers never look past the thumbnail. I’ve spent the last few months pulling listing images from archived marketplace scrapes (the 30-market, 851,199-listing COVID-era dataset analysed in EPJ Data Science is one of the few public corpora usable for this) and running them through the standard stego-detection pipeline. The results are mostly boring. That is the point. Steganography in marketplace imagery is rare, but the technique is real, the tooling is mature, and a determined vendor can hide a full executable inside a JPEG that renders identically to a legitimate product photo.
This is a research and detection writeup. Nothing here is an access guide. Treat it as an analyst’s notebook.
Why product images are the obvious carrier
Marketplaces strip most metadata, sanitise markup, and increasingly render listings through JS-heavy frontends that block custom HTML. That kills the old tricks: hidden CSS, off-screen text, JSON-LD poisoning. Those still work on clearnet SEO-poisoning campaigns (Zscaler documented one impersonating a Python library, requests-secure-v2, that stuffed JSON-LD with fake licensing instructions pointing at an attacker wallet), but darknet market templates rarely expose those surfaces to vendors.
Images are different. Every market expects vendors to upload product photos. The pipeline is: vendor uploads, market resizes and possibly re-encodes, CDN serves the derivative. If the vendor uses a stego payload that survives the market’s re-encoding, the image arrives intact at the buyer. Most markets cap image size at a few megabytes, which is plenty of room for a modest payload.
The same architectural logic that made VEIL#DROP effective applies here. Securonix’s writeup of that campaign is worth re-reading: the attacker split the chain so no single hop looked malicious. A JavaScript dropper disguised as transcript.pdf.js, a PowerShell second stage pulling from a blogspot.com page that sits inside Google’s whitelisted IP reputation range, then PureLogs Stealer. Nothing on the connection path triggered a signature. Vendor stego takes the same approach at the media layer. The image is the carrier. The extraction happens client-side, or in a separate stage the image points to.
What actually gets hidden
Three categories show up in practice.
- Flat payloads. An uncompressed archive or small executable stuffed into the low-order bits of pixel data. Trivial to detect if you look, trivial to execute if you don’t. Rare on markets because it breaks under any re-encode.
- Encrypted blobs. AES-encrypted archive embedded with a shared passphrase distributed out-of-band. Survives some re-encoding, and content scanners see noise. This is the interesting case.
- Pointers. The image carries a URL, an onion address, or a short string that the buyer is supposed to feed into a tool. This is barely steganography, but it’s the most common in my sample because it’s the most robust to market-side image processing.
PureSteganography and OpenStego remain the workhorses. OpenStego’s LSB mode is audible to any real detector, but it’s the tool most vendors would grab first. F5 and OutGuess are harder to catch because they use frequency-domain embedding and preserve histogram statistics. Steghide with a passphrase is the one I’ve actually seen in the wild on market-adjacent forums, though not on any live listing I could verify.
Detection, in order of usefulness
Skip the “steganalysis” tools that ship with a GUI and a promise. Work in order:
| Nexus |
nexusbem4wmo67jt723niftkejivtgxbsbxkb6aesj5gyzj7b3v3mxid.onion
|
| Torzon Market |
torzon7aphar3x4l5b77nsylgyw26kntbi4m2wemrjh72aczeh27f6qd.onion
|
| DarkMatter |
darkmafmzgnsmow5z3spgludhpwxhwbg77oam433fjx3clzh2yp2oaid.onion
|
| BlackOps |
blackoogcnxogvymmebfwfjhx4k7efpgeoeytxtsev2lc4pqlbz54qad.onion
|
| DrugHub |
drughuj7l72ig56pza77eriu7yh6qsao4xb4yasq2qfjusxzuq6rlwqd.onion
|
1. Provenance and re-encode fingerprint
Marketplaces re-encode uploads. If you have the scraper output and the original vendor upload, byte-compare them. Any structural difference beyond the market’s known resize pipeline (typically ImageMagick defaults) is worth flagging. In practice I see vendor images passed through 2 to 4 quality steps. A payload that survives that has to be either frequency-domain or extremely redundant.
2. Chi-square and RS analysis on the pixel matrix
Run these before you touch anything exotic. LSB substitution skews the pair-of-values distribution in a way chi-square catches instantly. RS analysis catches it even when the embedder randomises the bit positions. If both come back clean and the image still looks odd (file size larger than the visual complexity justifies, unusually high entropy in smooth regions), move on to the next step. OpenStego output fails both. Steghide output usually passes chi-square but fails RS at high embedding rates.
3. Binwalk and exiftool
Appended data after the JPEG EOI marker is the laziest stego and the most common. Binwalk catches it. Exiftool catches the metadata stego variants (comment fields, XMP blocks, the old trick of padding the ICC profile). Market image pipelines usually strip metadata, so anything surviving in EXIF after a marketplace round-trip is a deliberate signal, not an accident.
4. Tool-specific extraction attempts
Once a carrier is flagged, brute the common tools: steghide with no passphrase and a dictionary, outguess in both modes, F5 with default parameters. Most vendors do not rotate keys or use non-standard parameters. This is not cryptanalysis. It is just testing the easy case first.
5. Entropy mapping and visual diff
Split the image into blocks, compute Shannon entropy per block, and plot it. A photo of a product should have low entropy in smooth regions and high entropy in textured ones. Stego payloads sometimes flatten that curve. Visual diff against the vendor’s other listings is also cheap and effective: the same vendor often reuses a base image, and one-off anomalies stand out.
The honest limitations
Most of what you’ll flag is compression noise, color profiles, or the market’s own re-encode. False positive rates on chi-square alone run high on small images (under 200KB), which describes the majority of listing thumbnails. You need a multi-signal approach and a corpus of known-clean images from the same market and the same vendor to baseline against.
Encrypted payloads inside an image with a passphrase delivered out-of-band are functionally invisible to any of the above. Detection then falls back to behaviour: unusual file sizes for the visual content, vendor messaging patterns, and the kind of threat-intel that VEIL#DROP-style reporting provides on the clearnet side. There is no magic tool. Anyone selling you one is either confused or selling something else.
And remember the underlying economics. A Computers & Security netnographic study of darknet markets over two years found Ransomware-as-a-Service listings were surprisingly thin and often of questionable authenticity. Most market activity is not high-sophistication tradecraft. The vendors willing to build a working stego pipeline into their image workflow are rare, and the ones who do tend to get identified by their other operational patterns long before anyone cracks the image.
Practical analyst workflow
- Archive the raw upload before any processing. Hash it. You cannot do provenance analysis later if you didn’t keep the original.
- Run binwalk and exiftool first. Cheap, catches the low-effort cases.
- Run chi-square and RS. If both flag clean, deprioritise unless other signals (file size anomaly, vendor behavioural oddity) justify the manual time.
- For flagged carriers, attempt steghide/outguess/F5 extraction with default and dictionary passphrases.
- Log everything to a corpus. Detection value scales with baseline data, not with tooling cleverness.
Research only. Do not run extracted payloads on anything you care about. If you find something that looks like a live campaign rather than a vendor’s private stego, the disclosure channel is your national CERT or the academic group that published the underlying dataset, not the market’s forum.