Hacker News new | past | comments | ask | show | jobs | submit login
Weaponizing PostScript (lamehackersguide.blogspot.com)
140 points by remx on Feb 22, 2017 | hide | past | favorite | 28 comments

NeXTStep with its DisplayPostScript based WindowServer was an amazing playground for these kinds of shenanigans. Perhaps the most extreme was "Project Akira", a fully functioning NFS server you could launch by opening an EPS file. ( http://www.wizards.de/~frank/franksprojects.html )

Slightly less malicious were a whole bunch of EPS files that would play havoc with your screen: "gravity", which would make all your windows drop to the bottom of the screen, "black hole", etc.

Fun times.

Maybe I should release my Postscript tools for OS X?

> Slightly less malicious were a whole bunch of EPS files that would play havoc with your screen: "gravity", which would make all your windows drop to the bottom of the screen, "black hole", etc.

I was just searching for those on the USENET archives to point to them here. NeXTSTEP users would usually post to the USENET with NewsGrazer, and one of its options was to post (and view) "rich text" messages to the USENET in the form of a uuencoded tarball of an RTF directory, much to the consternation of non-NeXT users. This was immediately before the introduction of MIME, and Mark Crispin was quite vocal about how bad style this was.

Anyway, I think it was Glenn Reid (maybe?) who started inserting these evil EPS attachments his Newsgrazer RTF postings, so you'd view his messages and your screen would melt, or all the icons in your dock would fall down. It was amazing. IIRC this seemed to be the impetus for NeXT to include a few security measures in their next Display Postscript revision, breaking all the fun.

NeXT also had an open, unprotected port through which you could send Display Postscript commands, mostly to do remote screen stuff a-la X. I remember once posting about how I didn't think this was a big issue, and the next day someone mailed me the entire directory contents of my hard drive.

I don't have anything of substance to say here, but I just want to mention how delightful the phrasing of your last sentence is.

You could do a whole lot more window manipulation, user interface customization, event handling, object oriented programming, debugging, multithreaded programming and networking with the NeWS window system than with Display PostScript.

At Sun in 1991, we wrote a NeWS window manager that not only supported advanced features implemented in PostScript, like tabbed windows and pie menus [1], panning across a large virtual desktop, switching between different rooms, plugging together all kinds of other extensions and gui toolkit customizations that could be applied to all NeWS applications (like globally replacing all linear menus with pie menus, or melting the screen [2], or watching your cursor with round eyeballs [3]), and framing arbitrarily shaped windows [4], but it could also wrap and manage all of your X11 windows, too.

Plus it performed much better than any X11 window manager could, because it was running in the same address space as the window system, so didn't have to send asynchronous messages to the window manager, lock the input queue until it received a response from the wm, send asynchronous messages to the wm over the network, and switch context back and forth between the window server and the wm, as all X11 window managers must unfortunately do. [5]

NeWS was architecturally similar to what is now called AJAX, except that NeWS coherently:

+ used PostScript code instead of JavaScript for programming.

+ used PostScript graphics instead of DHTML and CSS for rendering.

+ used PostScript data instead of XML and JSON for data representation.

Here's another example that was written 100% in NeWS PostScript, of the kind of thing that you just couldn't do in Display PostScript:

The Shape of PSIBER Space: PostScript Interactive Bug Eradication Routines - October 1989 [6]

The PSIBER Space Deck is an interactive visual user interface to a graphical programming environment, the NeWS window system. It lets you display, manipulate, and navigate the data structures, programs, and processes living in the virtual memory space of NeWS. It is useful as a debugging tool, and as a hands on way to learn about programming in PostScript and NeWS.

Sun sold a PostScript printer called NeWSPrint, which used a sandboxed version of the NeWS server running on a Sun workstation as a rendering engine, sandboxed so you didn't have access to the file and networking operators. But I figured out a way to cause and catch an error with "stopped" that left some privileged code on the operand stack (PostScript is homoiconic, so code is data, like an executable array of operators), from which I was able to fish out a reference to the 'file' operator that could open sockets as well. So I made a small PostScript file you could print, which connected to the local "finger" daemon, and printed out a list of everyone who was logged in to the print server.

[1] https://www.youtube.com/watch?v=tMcmQk-q0k4

[2] http://www.donhopkins.com/home/archive/news-tape/fun/melt/me...

[3] http://www.donhopkins.com/home/archive/news-tape/fun/eye/eye...

[4] http://www.donhopkins.com/home/catalog/images/pizzatool.gif

[5] http://www.art.net/~hopkins/Don/unix-haters/x-windows/disast...

[6] http://www.donhopkins.com/drupal/node/97

Post script is Turing complete. So this is not a long shot at all, in fact since most people consider documents safe, it's a very exploitable attack vector.

Pdfs also allow arbitrary code execution, which is not a new result.

Here's an older hackernews discussion about the subject: https://news.ycombinator.com/item?id=4910113

> Post script is Turing complete.

That's irrelevant. Turing machines are pretty benign. They can't read or write to your files. The worst they could do is to run forever.

The problem with PostScript is that it allows to much OS interaction, such as file IO. But that has nothing to do with Turing completeness.

I see your point in the second argument. That said, a Turing complete language, with out os-level checks, is not. For a language thought up to print and display things, it's hard to argue that postscript is as harmless as HTML, for example.

The problem with Turing complete implementations is that it is impossible to decide what the code is going to do without running it.

It's not a problem. If there are no commands for file IO, then there can be no file IO. The only thing you can not decide in the general case is if there are file IO commands if they will get executed or not. But even that is no problem, as you can just block/not implement the file IO commands.

But Turing Completeness! ;)

There's one thing I don't understand: Given documents like pdf allow for turing-complete scripting, but is not intended for extensive computation, why not simply sandbox its execution? I'm thinking about something like a virtual machine simulating stack and stack pointers, and just providing whatever is safe and necessary. It doesn't appear extremely hard to do for something like PostScript - of course, performance might be bad, but that's probably not too relevant for documents anyway.

The "PDF language" itself is not that complex per se and ofc. executes in a VM. PDF also allows to embed various stuff, including Flash and JavaScript, which both execute in a VM as well.

No PDF reader was supposed to just execute x86 instructions from a PDF file (wouldn't be very Portable, would it?), although many PDF readers had enough security issues that it's an arguable viewpoint.

Reason gives way to production deadlines and some measures were implemented at viewer/av/printer levels. That said, it comes down to budgets, effort and deadlines. As to why doesn't one of us do it.. We I had a friend who wrote a pdf parser and he tells of the nightmare still. Pdfs apparently vary in their implementation, and there's no sure fire way to parse them all in the same.e way. Differences are usually small things, but it's enough to cause a non trivial amount of issues and cases to account for. The specification is also apparently a nightmare. Least to say, he would never touch pdfs again.

Pdf is a curious case, sort of like flash, but has no real html5 variant, if that makes sense.

That's definitely possible (and advisable) in GhostScript - the article itself touches on this in the end, when it mentions you need to use -dNOSAFER for the example to work in ps2pdf.


The SAFER and NOSAFER options are described here, and SAFER is essentially a sandbox. So, the problem described isn't so much a problem with PostScript, as a problem with anybody that writes an app that fails to invoke their PostScript interpreter appropriately. Apparently some unnamed web application had this problem, but ps2pdf does not.

What you've described sounds exactly like a PostScript interpreter! You can easily write a metacircular PostScript interpreter in PostScript!


And here is a PostScript quine:

    {{[ exch /dup load /exec load ] cvx} dup exec}
If you wanted to produce "safe" PostScript file for printing, that used a standard header file and didn't require a Turing complete printer with loops, conditionals, functions, etc, you could write a partial evaluator for PostScript that projects it against the stencil-paint imaging model, optimizes the graphics, and prints out another "safe" PostScript program using a standard header, with all the loops unrolled and conditionals evaluated and functions called and graphics in the same coordinate system. That would enable you to capture anything you draw on the screen, independent of the PostScript algorithmic procedures and classes and libraries and application required to draw it.


Glenn Reid, who also wrote books on PostScript like Thinking in PostScript, pioneered that idea in his "PostScript Language Distillery", which is the idea that grew into PDF.


Here's a post I wrote about printing and debugging PostScript in the NeWS window system:


And here's a paper I wrote in 1989 that describes the NeWS version of Distillery and the metacircular PostScript evaluator. At Sun we later built a PostScript distillery into the NeWS toolkit to support printing NeWS applications as PostScript:


The Shape of PSIBER Space: PostScript Interactive Bug Eradication Routines - October 1989


Printing Distilled PostScript

The data structure displays (including those of the Pseudo Scientific Visualizer, described below) can be printed on a PostScript printer by capturing the drawing commands in a file.

Glenn Reid's "Distillery" program is a PostScript optimizer, that executes a page description, and (in most cases) produces another smaller, more efficient PostScript program, that prints the same image. [Reid, The Distillery] The trick is to redefine the path consuming operators, like fill, stroke, and show, so they write out the path in device space, and incremental changes to the graphics state. Even though the program that computes the display may be quite complicated, the distilled graphical output is very simple and low level, with all the loops unrolled.

The NeWS distillery uses the same basic technique as Glenn Reid's Distillery, but it is much simpler, does not optimize as much, and is not as complete.


The Metacircular Postscript Interpreter

A program that interprets the language it is written in is said to be "metacircular". [Abelson, Structure and Interpretation of Computer Programs] Since PostScript, like Scheme, is a simple yet powerful language, with procedures as first class data structures, implementing "ps.ps", a metacircular PostScript interpreter, turned out to be straightforward (or drawrofthgiarts, with respect to the syntax). A metacircular PostScript interpreter should be compatible with the "exec" operator (modulo bugs and limitations). Some of the key ideas came from Crispin Goswell's PostScript implementation. [Goswell, An Implementation of PostScript]

The metacircular interpreter can be used as a debugging tool, to trace and single step through the execution of PostScript instructions. It calls a trace function before each instruction, that you can redefine to trace the execution in any way. One useful trace function animates the graphical stack on the PSIBER Space Deck step by step.

The meta-execution stack is a PostScript array, into which the metacircular interpreter pushes continuations for control structures. (forall, loop, stopped, etc...) A continuation is represented as a dictionary in which the state needed by the control structure is stored (plus some other information to help with debugging).

It is written in such a way that it can interpret itself: It has its own meta-execution stack to store the program's state, and it stashes its own state on the execution stack of the interpreter that's interpreting it, so the meta-interpreter's state does not get in the way of the program it's interpreting.

It is possible to experiment with modifications and extensions to PostScript, by revectoring functions and operators, and modifying the metacircular interpreter.

The metacircular interpreter can serve as a basis for PostScript algorithm animation. One very simple animation is a two dimensional plot of the operand stack depth (x), against the execution stack depth (y), over time.


Woops, the right link to the NeWS distillery is:


And here is The NeWS Toolkit version of capture.ps that captures NeWS application window drawings as PostScript:


But Glenn Reid's original tour-de-force PostScript Distillery is still the gold standard, that does the most optimization and works with more PostScript documents, and led the way to PDF. (Adobe's Acrobat Distiller is actually built into a real PostScript interpreter, not written in PostScript like Glenn's Distillery, but he proved the possibility and usefulness of the concept, and the power and flexibility of PostScript, long before PDF was a thing.) It's a great read if you want to learn a lot about the inner workings of PostScript:


No one is assuming documents are safe.

Presentation and functional scripting in documents is often blocked or heavily restricted/monitored this includes PDF most mail scanners know very well to block or filter PDF files based on postscript.

Every now and then you'll see some av or email provider like gmail block PDF files in masses often ones that were generated by a very specific program or process and very often because their internal post script was iffy.

Any references to best coding practice for PS? For example is there a PS lint? (will start hunting for this)

update 1: latex http://www.latex-project.org and http://tex.stackexchange.com/questions/12668/where-do-i-star...

update 0: so open tools for postscript appear to be really interfacing AGPL ghostscript (postscript) api if you can handle the ^agpl^ restrictions ~ https://en.wikipedia.org/wiki/Ghostscript

When I worked on NeWS at Sun, we had very strict rules about PostScript coding practices, formatting, documentation, function and stack comments, naming conventions, object oriented programming techniques, etc.

I don't have a copy of the coding practices written down any more, but here are some examples:

I wrote pizzatool at Sun, as a programming example to show how to use the NeWS toolkit, so it was well commented and intended to be read by developers learning NeWS:



Here's a typical NeWS user interface widget that I wrote at Sun following the NeWS coding practices, including the OPEN LOOK slider and menu:




This is older code I wrote on my own before working at Sun, so it's not as rigorously formatted or well documented:



And here's a huge file of messy PostScript code I wrote, with a warning at the beginning about how ugly it is:


And here's some really old NeWS code written by James Gosling:


thank you @DonHopkins I'll be reading this with great interest. ... going through this, fantastic.

I've always wanted to trick someone into sending this to the printer:

  initgraphics clippath fill
  { copypage } loop
Please don't do this! It'll run you out of toner and paper as fast as possible.

I'm just surprised I haven't seen more things like this, especially back in the days when postscript was popular.

Had to write postscript for "introduction into stackbased programming" at university.

We choose to make complex cylcoid "animations". We controlled the "animation"-speed by using helper routines that slowed down the postscript-viewer by painting nonsense white on white.

Downside of this was that it crashed printers and macOS Preview.

And the professor actually wanted us to write a parser or something else that could use a stack, but we were pretty satisfied with ourselves.

At university there was floating around a Postscript file which would render a Mandelbrot image at 300dpi.

There were emails from the IT department begging people not to print it on the elderly Laserjet IIIs during peak runs because it would take about 30-45 minutes to run, and the job couldn't be cancelled without physically power cycling the printer.

Back in the day (we're talking 80s) I wrote similar postscript (I remember also some sort of Douglas Hofstadter-esque strange attractor?). The argument for doing this was entirely practical: The Apple LaserWriter in the computer lab had a 68000 processor, which was a darn lot faster than anything else in the room, plus the only way to do high-dpi raster output.

Some time ago Tavis Ormandy found a bunch of bugs in Ghostscript's sandbox, which would allow arbitrary code execution:


Hopefully these bugs are all fixed now, but I wouldn't be surprised if there was more to be found.

After seeing this post[1] of a postcript file, I was wondering if there was any way it could harm my computer, paranoid you could say. Apparently I need to watch out for postscript viewers that allow writing to files. Are there any that allow file writing by default?

[1] https://news.ycombinator.com/item?id=13678251

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact