Read more

CVE-2023-36664 : Ghostscript RCE

Posted on:December 12, 2023 at 09:48 PM

CVE-2023-36664 was published on June the 25, 2023. It concerns Ghostscript interpreter andallows for remote code execution until version 10.01.2. Details concerning this CVE can be found here.

Table of contents

Context

Scope

As part of the watch course I followed in my master cybersecurity at Aix-Marseille University, I had the opportunity to work on this CVE.

To put it simply, the aim of this course is to work on a recent vulnerability for which a proof of concept has been published. The aim of this work is to understand the emergence of the vulnerability, its exploitability and to produce a reproducible demonstration in order to present all this during a seminar.

What you’ll find in this article is simply a small summary of the work I’ve done to highlight my personal contributions. The explanations are deliberately reduced and simplified, but should enable a general understanding of the problem. A more detailed source of explanations is available here.

If there are any errors or if the postlacks key details for understanding you can contact me.

What is Ghostscript ?

Ghostscript is an interpreter for the PostScript language developed by Adobe. It is an open source software maintained under a GNU Affero GPL licence but also under a commercial licence by the company Artifex.

The source code is available on the Github page of Artifex Software.

Vulnerability

Overview

Artifex Ghostscript through 10.01.2 mishandles permission validation for pipe devices (with the %pipe% prefix or the | pipe character prefix).

When we dive into the previous description, we understand that the vulnerability lies in a bad validation of permissions during the use of a pipe.

In fact, when we look a little bit closer to the correction commit, we can identify the validation function that seems to pose a problem. It is the function gp_validate_path_len.

The validation mechanism of this function is quite simple. It takes an access path as a parameter (among other things) and reduces it using the gp_file_name_reduce function. This reduction consists in simplifying the access path by removing references to the current directory and the parent directory (respectively ./ and ../). Access permissions are then validated on this reduced path before opening the pipe and using the full path.

This is where the problem lies, since the validated path is one that has received one more treatment than the path used.

Payload

If it is still not very clear at this point, you can read this article which explains very well how to bypass path validation with an offensive goal.

First of all, it’s important to specify that the Ghostscript interpreter can only read and write certain predefined files. This applies, for example, to the %rom%lib/ directory, which is read-only.

To summarize what happens in practice, let’s take the command (%pipe%firefox;/../%rom%lib/test) (r) file, which is a simple command to open a file for writing, using a pipe. The reduced path is then %rom%lib/test, but we saw in the previous paragraph that the %rom%lib/ directory is readable. Validation is therefore successful and Firefox is triggered when the file is opened. If this command is inserted in a .ps or .eps file describing an image, Firefox is triggered when the image is opened.

Proof of concept

The article accessible here explains very well the vulnerability but does not share the code for the proof of concept, I’ve taken the liberty of developing a very simplified one that is freely accessible on my Github.

It will certainly be updated as time permits, with a new image to make it easier to test the operation. In the meantime, you can convert any image into an .eps file using an online converter, and then use it.

In terms of prerequisites, only version 10.01.1 of Ghostscript is required and can be installed with the commands below.

git clone -b gs10.01.1 https://github.com/ArtifexSoftware/ghostpdl.git
cd ghostpdl
sh autogen.sh
make
make install

For more information on usage, please refer to the README of the corresponding Github repository.

A word of caution

The proof-of-concept presented in this article is highly simplified and developed for educational purposes only (for testing in a virtual machine).

This work was inspired by the resources cited throughout the article, and errors may have crept in. If so, please let me know.