Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,85 @@

Check further details in [**https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html**](https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html)

ImageMagick, a versatile image processing library, presents a challenge in configuring its security policy due to its extensive options and lack of detailed online documentation. Users often create policies based on fragmented internet sources, leading to potential misconfigurations. The library supports a vast array of over 100 image formats, each contributing to its complexity and vulnerability profile, as demonstrated by historical security incidents.
ImageMagick is commonly used behind upload, thumbnailing, document-conversion, and CI/CD pipelines. That makes it a high-value target whenever untrusted images, SVGs, EPS, PS, or PDFs reach `magick` / `convert`.

Classic **ImageTragick**-style payloads are only part of the story. A modern chain can start from a **single SVG** and end in **arbitrary file write** by abusing how ImageMagick generates MVG plus how it delegates EPS/PS parsing to Ghostscript.

## SVG -> MVG injection -> `msl:` execution

When ImageMagick rasterizes SVG, it first emits an intermediate **MVG** script. If attacker-controlled SVG data reaches that generated MVG without normalizing both LF and CR, an XML-encoded carriage return (`
`) can become a **new MVG line**.

A practical injection point is the `<polyline points="...">` attribute because the points string is copied into MVG almost verbatim. A payload like:

```xml
<polyline points="0,0 50,50&#13;image Over 0,0 1,1 'msl:/tmp/payload.msl'&#13;100,0"/>
```

can turn one SVG attribute into attacker-controlled MVG commands.

The most useful primitive is:

```text
image Over X,Y W,H 'URL'
```

This does **not** only load remote HTTP resources. It can also trigger internal coders / protocol handlers such as `data:` and `msl:`.

If `msl:` is reachable, an attacker can execute **Magick Scripting Language** from disk and turn the bug into **arbitrary file write**:

```xml
<image>
<read filename="xc:red[10x10]"/>
<write filename="png:/var/www/html/poc.png"/>
</image>
```

This is different from older ImageTragick payloads: instead of directly trying to get shell metacharacters into a delegate command, the chain abuses **MVG line injection** and then pivots into a **second-stage MSL script**.

## Ghostscript delegate as the file dropper

ImageMagick usually sends **EPS/PS/PDF** work to a **Ghostscript delegate**. That matters even for an SVG upload, because injected MVG can load an embedded:

```text
data:image/x-eps;base64,...
```

payload.

In the published **ImagePanick** repro, Ghostscript `10.06.0` running under SAFER can be abused as a file dropper:

- `.tempfile` creates a writable temp file and also extends the read/write/control permit lists for that temp path.
- `writestring` stores attacker-controlled MSL bytes.
- `renamefile` moves the random temp name to a predictable filename such as `/tmp/payload.msl`.

Then a second injected MVG line loads:

```text
msl:/tmp/payload.msl
```

and ImageMagick executes the MSL, producing **arbitrary file write**. From there, writing into a web root, cron path, shell init file, or `authorized_keys` is usually enough for practical RCE or persistence.

For more Ghostscript-centric notes, see [Ghostscript Injection](../../pentesting-web/formula-csv-doc-latex-ghostscript-injection.md).

## Quick triage

If a target processes untrusted images, first check which dangerous coders and delegates are still available:

```bash
magick -list policy
identify -list format | grep -E 'SVG|MSL|PS|EPS|PDF'
convert -list delegate | grep -iE 'gs|ghostscript'
find / -iname policy.xml 2>/dev/null
```

If the application accepts SVG and the backend simply does:

```bash
magick input.svg output.png
```

that alone may be enough to trigger the chain when weak policies and a Ghostscript delegate are present.

## Towards Safer Policies

Expand Down Expand Up @@ -43,11 +121,25 @@ A restrictive policy template has been proposed, focusing on stringent resource

The effectiveness of a security policy can be confirmed using the `identify -list policy` command in ImageMagick. Additionally, the [evaluator tool](https://imagemagick-secevaluator.doyensec.com/) mentioned earlier can be used to refine the policy based on individual needs.

For **untrusted uploads**, prefer an **allowlist**. If SVG / EPS / PS are not required, explicitly block the dangerous coders instead of trying to blacklist individual bad payloads:

```xml
<policy domain="coder" rights="none" pattern="{SVG,EPS,PS,MSL}" />
```

Additional hardening:

- Disable the Ghostscript delegate in `delegates.xml` if EPS / PS support is not needed.
- Keep coder names upper-cased because policy patterns are **case sensitive**.
- Prefer a dedicated SVG rasterizer such as `librsvg` for untrusted SVG instead of full ImageMagick + Ghostscript.
- Run conversions in a sandbox (`nsjail`, `firejail`, container, read-only filesystem, restricted tmpdir).

## References

- [https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html**](https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html)
- [ImageMagick Security Policy Evaluator](https://blog.doyensec.com/2023/01/10/imagemagick-security-policy-evaluator.html)
- [ImagePanick: From SVG to RCE Chaining Weak Policies and Bugs in ImageMagick and Ghostscript](https://blog.deephacking.tech/en/posts/imagepanick-from-svg-to-rce-imagemagick-ghostscript/)
- [ImagePanick PoC / Docker lab](https://github.com/e1abrador/ImagePanick/)

{{#include ../../banners/hacktricks-training.md}}