Difference between revisions of "PostScript"
(Created page with "Clones: Br-Script, KPDL") |
|||
(12 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | + | The PostScript (PS) language was invented by Adobe Systems between 1982 and 1984. It has been standardized as PostScript Level 1 <ref>''PostScript Language Reference Manual'', Adobe Systems Inc., 1985</ref>, PostScript Level 2 <ref>''[https://www-cdf.fnal.gov/offline/PostScript/PLRM2.pdf PostScript Language Reference Manual, 2nd Edition]'', Adobe Systems Inc., 1992</ref>, PostScript 3 <ref>''[https://www.adobe.com/products/postscript/pdfs/PLRM.pdf PostScript Language Reference Manual, 3rd Edition]'', Adobe Systems Inc., 1999</ref> 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 [https://en.wikipedia.org/wiki/LaTeX 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: | |
+ | |||
+ | <syntaxhighlight lang=postscript> | ||
+ | %! | ||
+ | (Hello world) print | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | 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 [[Print job manipulation|manipulation]] and [[Print job retention|retention]] as well as gaining access to the printer's [[File system access|file system]]. | ||
+ | |||
+ | == Security features == | ||
+ | |||
+ | === Exiting the server loop === | ||
+ | |||
+ | Normally, each print job is encapsulated in its own, separate environment. One interesting feature of PostScript is that a program can circumvent print job encapsulation and alter the initial VM for subsequent jobs <ref>''[https://www.adobe.com/products/postscript/pdfs/PLRM.pdf PostScript Language Reference Manual, 3rd Edition]'', Adobe Systems Inc., 1999, p. 68-72</ref>. To do so, it can use either ''startjob'', a Level 2 feature: | ||
+ | |||
+ | <syntaxhighlight lang=postscript> | ||
+ | true 0 startjob | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | or ''exitserver'' (available in all implementations that include a job server): | ||
+ | |||
+ | <syntaxhighlight lang=postscript> | ||
+ | serverdict begin 0 exitserver | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | This capability is controlled by the ''StartJobPassword'' which defaults to <code>0</code> (compare [[Credential disclosure#PostScript|credential disclosure]]). 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 will remain as part of the permanent state of the interpreter for all subsequent jobs <ref>''[https://www-cdf.fnal.gov/offline/PostScript/GREENBK.PDF PostScript Language Program Design (Green Book),]'', Adobe Systems Inc., 1988, p. 176</ref>. In other words, a print job can access and alter further jobs. Bingo! | ||
+ | |||
+ | === 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: | ||
+ | |||
+ | |||
+ | [[File:Dictstack.png|300px|The PostScript dictionary stack]] | ||
+ | |||
+ | |||
+ | 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 [[Document processing#Showpage redefinition|denial of service]], print job [[Print job retention|retention]] and [[Print job manipulation|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 [https://en.wikipedia.org/wiki/Raster_image_processor RIP]. | ||
+ | |||
+ | → ''Related articles:'' [[Fundamentals#Printer Control Languages|Page Description Languages]], [[Denial of service]], [[Print job manipulation]], [[Print job retention]], [[File system access]] | ||
+ | |||
+ | <!-- what about Configurable PostScript Interpreter (CPSI) technology? --> | ||
+ | |||
+ | ----- |
Latest revision as of 16:49, 31 January 2017
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
Normally, each print job is encapsulated in its own, separate environment. One interesting feature of PostScript is that a program can circumvent print job encapsulation and alter the initial VM for subsequent jobs [4]. To do so, it can use either startjob, a Level 2 feature:
true 0 startjob
or exitserver (available in all implementations that include a job server):
serverdict begin 0 exitserver
This capability is controlled by the StartJobPassword which defaults to 0
(compare credential disclosure). 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 will remain as part of the permanent state of the interpreter for all subsequent jobs [5]. In other words, a print job can access and alter further jobs. Bingo!
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 articles: 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