Even if you happen to haven’t heard of the venerable Ghostscript mission, chances are you’ll very nicely have used it with out realizing.
Alternatively, you will have it baked right into a cloud service that you just provide, or have it preinstalled and able to go if you happen to use a package-based software program service corresponding to 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, quick for Moveable Doc Format. (Internally, PDF information depend on PostScript code to outline learn how to 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 information, corresponding to you would possibly 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 learn how to 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, corresponding to uncooked pixel information or a PNG graphics file.
Sadly, till the newest 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 operating 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 slightly than a daily file.
Pipes, as you’ll know if you happen to’ve ever completed any programming or script writing, are system objects that fake to be information, in which you could write to them as you’d to disk, or learn information in from them, utilizing common system features corresponding to learn()
and write()
on Unix-type methods, or ReadFile()
and WriteFile()
on Home windows…
…however the information doesn’t truly find yourself on disk in any respect.
As an alternative, the “write” finish of a pipe merely shovels the output information into a brief block of reminiscence, and the “learn” finish of it sucks in any information 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 information from one program to a different.
Once you need 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 look forward to 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 momentary file between the primary program terminating and the second launching.
- It’s a must to be certain that the momentary filename doesn’t conflict with an present file you need to preserve.
- You’re left with a brief file to scrub up later that might leak information 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 may see from this notation the place the names pipe and pipeline come from, and likewise why the vertical bar image (|
) chosen to symbolize 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 virtually all the time used for speaking between two processes, that magic pipe character is mostly adopted not by a filename to jot down into for later use, however by the identify of a command that can eat the output instantly.
In different phrases, if you happen to permit remotely-supplied content material to specify a filename for use for output, then you could watch out if you happen to permit that filename to have a particular type 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 pc.
(We haven’t tried this, however we’re guessing which you could 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 “generally patches want patches” drawback popped up once more within the strategy of fixing this bug.
In yesterday’s article a couple of WordPress plugin flaw, we described how the makers of the buggy plugin (Final Member) have not too long ago and quickly gone by 4 patches making an attempt 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 cope with a command injection vulnerability that first confirmed up as a zero-day within the arms of ransomware crooks:
On this case, the Ghostscript staff 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 sudden 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 cope with each instances.
Right here, as a substitute of checking that the variable path doesn’t begin with %pipe...
to detect that that the filename is “secure”, 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 sudden outcomes */ if (path[0] == '|' || (len > 5 && memcmp(path, "%pipe", 5) == 0)) { . . .
memcmp()
returns zero, it signifies that the comparability was TRUE
, as a result of the 2 reminiscence blocks you’re evaluating match precisely, despite the fact that zero in C applications is conventionally used to symbolize 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 type alphanumerically earlier than the second, you get a unfavourable quantity again, in an effort to inform that aardvark
precedes zymurgy1
. In the event that they’re the opposite means round, you get a constructive quantity, which leaves zero to indicate that they’re an identical. Like this:
#embody <string.h> #embody <stdio.h> int fundamental(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?
- You probably have a standalone Ghostcript bundle that’s managed by your Unix or Linux distro (or by the same bundle supervisor such because the abovementioned Homebrew on macOS), ensure you’ve acquired the newest model.
- You probably have software program that comes with a bundled model of Ghostscript, verify with the supplier for particulars on upgrading the Ghostscript element.
- If you’re 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 staff did, “The place else may the same type of coding blunder have occurred, and what different tips could possibly be used to set off the bug we already learn about.”