Ghostscript bug might permit rogue paperwork to run system instructions – Bare Safety


Even when you haven’t heard of the venerable Ghostscript undertaking, chances are you’ll very properly have used it with out figuring out.

Alternatively, you will have it baked right into a cloud service that you just supply, or have it preinstalled and able to go when you use a package-based software program service resembling a BSD or Linux distro, Homebrew on a Mac, or Chocolatey on Home windows.

Ghostscript is a free and open-source implementation of Adobe’s widely-used PostScript doc composition system and its even-more-widely-used PDF file format, brief for Moveable Doc Format. (Internally, PDF recordsdata depend on PostScript code to outline how you can compose a doc.)

For instance, the favored open-source graphics program Inkscape makes use of Ghostscript behind the scenes to import EPS (Embedded PostScript) vector graphics recordsdata, resembling you may obtain from a picture library or obtain from a design firm.

Loosely put, Ghostscript reads in PostScript (or EPS, or PDF) program code, which describes how you can assemble the pages in a doc, and converts it, or renders it (to make use of the jargon phrase), right into a format extra appropriate for displaying or printing, resembling uncooked pixel knowledge or a PNG graphics file.

Sadly, till the most recent launch of Ghostscript, now at model 10.01.2, the product had a bug, dubbed CVE-2023-36664, that might permit rogue paperwork not solely to create pages of textual content and graphics, but additionally to ship system instructions into the Ghostscript rendering engine and trick the software program into working them.

Pipes and pipelines

The issue took place as a result of Ghostscript’s dealing with of filenames for output made it doable to ship the output into what’s identified within the jargon as a pipe somewhat than an everyday file.

Pipes, as you’ll know when you’ve ever achieved any programming or script writing, are system objects that faux to be recordsdata, in that you may write to them as you’d to disk, or learn knowledge in from them, utilizing common system capabilities resembling learn() and write() on Unix-type programs, or ReadFile() and WriteFile() on Home windows…

…however the knowledge doesn’t truly find yourself on disk in any respect.

As an alternative, the “write” finish of a pipe merely shovels the output knowledge into a brief block of reminiscence, and the “learn” finish of it sucks in any knowledge that’s already sitting within the reminiscence pipeline, as if it had come from a everlasting file on disk.

That is super-useful for sending knowledge from one program to a different.

While you wish to take the output from program ONE.EXE and use it because the enter for TWO.EXE, you don’t want to save lots of the output to a brief file first, after which learn it again in utilizing the > and < characters for file redirection, like this:


 C:Usersduck> ONE.EXE > TEMP.DAT
 C:Usersduck> TWO.EXE < TEMP.DAT

There are a number of hassles with this method, together with these:

  • It’s a must to anticipate the primary command to complete and shut off the TEMP.DAT file earlier than the second command can begin studying it in.
  • You may find yourself with an enormous intermediate file that eats up extra disk area than you need.
  • You may get messed round if another person fiddles with non permanent file between the primary program terminating and the second launching.
  • It’s a must to make sure that the non permanent filename doesn’t conflict with an current file you wish to maintain.
  • You’re left with a brief file to wash up later that might leak knowledge if it’s forgotten.

With a memory-based intermediate “pseudofile” within the type of a pipe, you’ll be able to condense this type of course of chain into:


 C:Usersduck> ONE.EXE | TWO.EXE

You’ll be able to see from this notation the place the names pipe and pipeline come from, and likewise why the vertical bar image (|) chosen to signify the pipeline (in each Unix and Home windows) is extra generally identified within the IT world because the pipe character.

As a result of files-that-are-actually-pipes-at-the-operating-system-level are nearly at all times used for speaking between two processes, that magic pipe character is mostly adopted not by a filename to write down into for later use, however by the identify of a command that may eat the output instantly.

In different phrases, when you permit remotely-supplied content material to specify a filename for use for output, then you should watch out when you permit that filename to have a particular kind that claims, “Don’t write to a file; begin a pipeline as a substitute, utilizing the filename to specify a command to run.”

When options flip into bugs

Apparently, Ghostscript did have such a “characteristic”, whereby you may say you needed to ship output to a specially-formatted filename beginning with %pipe% or just |, thereby providing you with an opportunity of sneakily launching a command of your alternative on the sufferer’s laptop.

(We haven’t tried this, however we’re guessing that you may additionally add command-line choices in addition to a command identify to execute, thus providing you with even finer management over what kind of rogue behaviour to impress on the different finish.)

Amusingly, if that’s the proper phrase, the “typically patches want patches” drawback popped up once more within the technique of fixing this bug.

In yesterday’s article a few WordPress plugin flaw, we described how the makers of the buggy plugin (Final Member) have not too long ago and quickly gone by means of 4 patches attempting to squash a privilege escalation bug:

We’ve additionally not too long ago written about file-sharing software program MOVEit pushing out three patches in fast succession to take care of a command injection vulnerability that first confirmed up as a zero-day within the arms of ransomware crooks:

On this case, the Ghostscript workforce first added a verify like this, to detect the presence of the damaging textual content %pipe... at the beginning of a filename:


/* "%pipe%" don't comply with the traditional guidelines for path definitions, so we
   do not "scale back" them to keep away from surprising outcomes */

if (len > 5 && memcmp(path, "%pipe", 5) != 0) {
   . . . 

Then the programmers realised that their very own code would settle for a plain | character in addition to the prefix %pipe%, so the code was up to date to take care of each circumstances.

Right here, as a substitute of checking that the variable path doesn’t begin with %pipe... to detect that that the filename is “protected”, the code declares the filename unsafe if it begins with both a pipe character (|) or the dreaded textual content %pipe...:


/* "%pipe%" don't comply with the traditional guidelines for path definitions, so we
   do not "scale back" them to keep away from surprising outcomes */

if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) {
   . . .
Above, you’ll see that if memcmp() returns zero, it signifies that the comparability was TRUE, as a result of the 2 reminiscence blocks you’re evaluating match precisely, regardless that zero in C applications is conventionally used to signify FALSE. This annoying inconsistency arises from the truth that memcmp() truly tells you the order of the 2 reminiscence blocks. If the primary block would kind alphanumerically earlier than the second, you get a destructive quantity again, to be able to inform that aardvark precedes zymurgy1. In the event that they’re the opposite approach round, you get a optimistic quantity, which leaves zero to indicate that they’re an identical. Like this:


#embody <string.h>
#embody <stdio.h>

int primary(void) {
   printf("%dn",memcmp("aardvark","zymurgy1",8));
   printf("%dn",memcmp("aardvark","00NOTES1",8));
   printf("%dn",memcmp("aardvark","aardvark",8));
   return 0;
}
---output---
-1
1
0

What to do?

  • In case you have a standalone Ghostcript package deal that’s managed by your Unix or Linux distro (or by the same package deal supervisor such because the abovementioned Homebrew on macOS), be sure you’ve bought the most recent model.
  • In case you have software program that comes with a bundled model of Ghostscript, verify with the supplier for particulars on upgrading the Ghostscript element.
  • In case you are a programmer, don’t settle for any immediately-obvious bugfix as the start and finish of your vulnerability-squashing work. Ask your self, because the Ghostscript workforce did, “The place else might the same type of coding blunder have occurred, and what different tips might be used to set off the bug we already find out about.”

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles