PostScript
The PostScript (PS) language was invented by Adobe Systems between 1982 and 1984. It has been standardized as PostScript Level 1 [1], PostScript Level 2 [2], PostScript 3 [3] and in various language supplements. While PostScript has lost popularity in desktop publishing and as a document exchange format to PDF, it is still the preferred page description language for laser printers. The term `page description' may be misleading though, as PostScript is capable of much more than just creating vector graphics. PostScript is a stack-based, Turing-complete programming language consisting of almost 400 operators for arithmetics, stack and graphic manipulation and various data types such as arrays or dictionaries. Technically spoken, access to a PostScript interpreter can already be classified as code execution because any algorithmic function can theoretically be implemented in PostScript. Certainly, without access to the network stack or additional operating system libraries, possibilities are limited to arbitrary mathematical calculations like mining bitcoins. However, PostScript is capable of basic file system I/O to store frequently used code, graphics or font files. Originally designed as a feature, the dangers of such functionality were limited before printers got interconnected and risks were mainly discussed in the context of host-based PostScript interpreters. In this regard, Encapsulated PostScript (EPS) is also noteworthy as it can be included in other file formats to be interpreted on the host such as LaTeX documents. Like PJL and PCL, PostScript supports bidirectional communication been host and printer. Example PostScript code to echo Hello world to stdout is given below:
%!
(Hello world) print
While most printer manufacturers have implemented (as hardware modules or in software) and licensed original ‘Adobe PostScript’, Brother and Kyocera use their own PostScript clones: Br-Script and KPDL. Such flavours of the PostScript language are not 100% compatible, especially concerning security features like exiting the server loop. PostScript can be used for a variety of attacks such as denial of service (for example, through infinite loops), print job manipulation and retention as well as gaining access to the printer's file system.
Security features
Exiting the server loop
One intersting fact about PostScript when running in a printer is that the separtion of print ... can be bypassed
‘The conventional model of a PostScript interpreter is a “print server” — a single-threaded process that consumes and executes a sequence of “print jobs”, each of which is a complete, independent PostScript program. [...] A program can circumvent job encapsulation and alter the initial VM for subsequent jobs. To do so, it can use either startjob (LanguageLevel 2) or exitserver (available in all implementations that include a job server). This capability is controlled by a password.’ [4]
To exit the server loop using the default StartJobPassword (0
, compare credential disclosure),
true 0 startjob
serverdict begin 0 exitserver
‘Since the job server loop is generally responsible for cleaning up the state of the interpreter between jobs, any changes that are made outside the server loop by using exitserver will remain as part of the permanent state of the interpreter for all subsequent jobs. This only applies to changes to VM (like procedure definitions), since the stacks and graphics state are cleared after each job.’ [5]
Operator redefinition
When a PostScript document calls an operator, the first version found on the dictionary stack is used. Operators usually reside in the systemdict dictionary, however by placing a new version into the userdict dictionary, operators can be practically overwritten because the user-defined version is the first one found on the dictionary stack. Using the startjob/exitserver operators, such changes can be made permanent – at least until the printer is restarted. A scheme of the PostScript dictionary stack is given below:
The potential impact of redefining operators is only limited by creativity. When further legitimate documents are printed and call a redefined operator, the attackers version will be executed. This can lead to a various attacks such as denial of service, print job retention and manipulation. Note however that this is not necessarily a security bug, but a 32 years old language feature, available in almost any PostScript printer and RIP.
→ Related aricles: Page Description Languages, Denial of service, Print job manipulation, Print job retention, File system access
- ↑ PostScript Language Reference Manual, Adobe Systems Inc., 1985
- ↑ PostScript Language Reference Manual, 2nd Edition, Adobe Systems Inc., 1992
- ↑ PostScript Language Reference Manual, 3rd Edition, Adobe Systems Inc., 1999
- ↑ PostScript Language Reference Manual, 3rd Edition, Adobe Systems Inc., 1999, p. 68-72
- ↑ PostScript Language Program Design (‘Green Book’),, Adobe Systems Inc., 1988, p. 176