🔍 Contexte
Publié le 02/04/2026 par Octagon Networks sur pwn.ai, cet article détaille une recherche offensive autonome menée par l’agent IA pwn.ai pendant près de 5 jours, initiée lors d’un engagement client sur une application web minimaliste dont la seule surface d’attaque était une boîte d’upload traitant les fichiers via ImageMagick.
🎯 Découvertes principales
La recherche a abouti à la découverte de multiples zero-days dans ImageMagick affectant toutes les distributions Linux majeures (Ubuntu 22.04, Debian, Fedora, RHEL, Arch, Alpine, Amazon Linux, macOS Homebrew, Docker) ainsi que les installations WordPress.
Chaîne #1 — Politique par défaut (open policy)
- Bypass de détection par extension : ImageMagick détecte les formats par magic bytes, pas par extension. Un fichier
.jpgcontenant<?xmlest traité comme SVG. - Lecture de fichier arbitraire : le renderer MSVG passe les valeurs
xlink:hrefàReadImage(), permettant<image xlink:href="text:/etc/passwd"/>→ contenu rendu dans l’image de sortie. - Bypass de la blocklist PS/EPS : Ubuntu bloque PS, PS2, PS3, EPS, PDF, XPS mais pas EPSI, EPI, EPSF, qui invoquent le même binaire GhostScript.
- Bypass de détection PostScript : un préfixe
\n(0x0a) avant%!PSfait échouer la détection IM tout en étant exécuté normalement par GhostScript 9.55.0. - Écriture de fichier arbitraire : GhostScript sous
-dSAFERbloque l’exécution shell mais autorise les I/O fichiers → écriture arbitraire confirmée. - Résultat : webshell déposé, reverse shell établi.
Chaîne #2 — Politique limited (recommandée production)
- La limited policy bloque
{MSL, MVG, PS, SVG, TEXT, URL, XPS}mais oublie PDF. - Le module PDF invoque le même délégué GhostScript → écriture de fichier sur limited policy.
- Également : le format EPT (Encapsulated PostScript with TIFF preview), détecté par magic bytes
C5 D0 D3 C6, n’est pas dans la blocklist → RCE depuis un fichier.jpgavec limited policy active.
Chaîne #3 — Politique secure
- La secure policy ajoute
<policy domain="delegate" rights="none" pattern="*"/>bloquant les processus externes. - Sur Amazon Linux avec ImageMagick 6.9.13-40 compilé avec
--with-gslib, GhostScript est une bibliothèque liée (gslib), pas un binaire externe →ExternalDelegateCommand()n’est jamais appelé → la vérification de politique delegate ne se déclenche pas → écriture de fichier sur secure policy confirmée.
⛓️ Escalade vers RCE complet via MSL
La chaîne finale exploite le coder MSL (Magick Scripting Language) non restreint par -dSAFER :
- GhostScript écrit dans
/tmp/: un polyglot PHP/JPEG (JPEG valide avec<?php system(...) ?>dans le marqueur COM) + un fichier payload MSL. - ImageMagick traite le fichier MSL → copie le polyglot vers
/var/www/html/uploads/shell.php. - RCE obtenu.
💥 Impacts additionnels de l’écriture dans /tmp/
- DoS par épuisement RAM : /tmp est tmpfs (RAM), écriture de 1 To possible en moins d’une seconde.
- Empoisonnement de sessions PHP : injection dans les fichiers de session stockés dans /tmp.
- Corruption d’état applicatif : écrasement de fichiers lock, PID, fichiers temporaires d’applications.
📋 Type d’article
Publication de recherche offensive détaillant une chaîne de zero-days originaux dans ImageMagick, avec traces d’exécution de l’agent IA, preuves de concept et analyse des mécanismes de contournement des politiques de sécurité.
🧠 TTPs et IOCs détectés
TTP
- T1190 — Exploit Public-Facing Application (Initial Access)
- T1203 — Exploitation for Client Execution (Execution)
- T1083 — File and Directory Discovery (Discovery)
- T1005 — Data from Local System (Collection)
- T1505.003 — Server Software Component: Web Shell (Persistence)
- T1222 — File and Directory Permissions Modification (Defense Evasion)
- T1036 — Masquerading (Defense Evasion)
- T1059 — Command and Scripting Interpreter (Execution)
- T1499 — Endpoint Denial of Service (Impact)
IOC
- Chemins :
/tmp/ - Chemins :
/var/www/html/uploads/shell.php - Chemins :
/etc/passwd - Chemins :
/proc/self/environ
Malware / Outils
- GhostScript (tool)
- ImageMagick MSL coder (tool)
🔗 Source originale : https://pwn.ai/blog/imagemagick-from-arbitrary-file-read-to-rce-in-every-policy-zeroday