{"id":13469370,"url":"https://github.com/RUB-NDS/PRET","last_synced_at":"2025-03-26T06:32:09.784Z","repository":{"id":39633257,"uuid":"61873736","full_name":"RUB-NDS/PRET","owner":"RUB-NDS","description":"Printer Exploitation Toolkit - The tool that made dumpster diving obsolete.","archived":false,"fork":false,"pushed_at":"2024-08-02T01:18:28.000Z","size":1914,"stargazers_count":4025,"open_issues_count":67,"forks_count":620,"subscribers_count":198,"default_branch":"master","last_synced_at":"2025-03-19T09:15:36.529Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://hacking-printers.net","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RUB-NDS.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-24T09:33:21.000Z","updated_at":"2025-03-19T05:32:41.000Z","dependencies_parsed_at":"2023-02-15T15:31:42.530Z","dependency_job_id":"43ffa0eb-a45d-4a82-93dc-bdb166f6f6b9","html_url":"https://github.com/RUB-NDS/PRET","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RUB-NDS%2FPRET","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RUB-NDS%2FPRET/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RUB-NDS%2FPRET/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RUB-NDS%2FPRET/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RUB-NDS","download_url":"https://codeload.github.com/RUB-NDS/PRET/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245604137,"owners_count":20642944,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T15:01:36.258Z","updated_at":"2025-03-26T06:32:08.608Z","avatar_url":"https://github.com/RUB-NDS.png","language":"Python","readme":"## PRET - Printer Exploitation Toolkit\n\n**Is your printer secure? Check before someone else does...**\n\nPRET is a new tool for printer security testing developed in the scope of a [Master's Thesis](http://nds.rub.de/media/ei/arbeiten/2017/01/13/exploiting-printers.pdf) at Ruhr University Bochum. It connects to a device via network or USB and exploits the features of a given printer language. Currently [PostScript](https://www.adobe.com/products/postscript/pdfs/PLRM.pdf), [PJL](http://h10032.www1.hp.com/ctg/Manual/bpl13208.pdf) and [PCL](http://www.hp.com/ctg/Manual/bpl13210.pdf) are supported which are spoken by most laser printers. This allows cool stuff like capturing or manipulating print jobs, accessing the printer's file system and memory or even causing physical damage to the device. All attacks are documented in detail in the [Hacking Printers Wiki](http://hacking-printers.net/wiki/).\n\nThe main idea of PRET is to facilitate the communication between the end-user and the printer. Thus, after entering a UNIX-like command, PRET translates it to PostScript, PJL or PCL, sends it to the printer, evaluates the result and translates it back to a user-friendly format. PRET offers a whole bunch of commands useful for printer attacks and fuzzing.\n\n![PRET design](img/architecture.png)\n\n### Installation\n\nPRET only requires a Python2 interpreter. For colored output and SNMP support however, third party modules need to be installed:\n\n    # pip install colorama pysnmp\n\nIf running on a Windows console and Unicode characters are not displayed correctly, install the *win_unicode_console* module:\n\n    # pip install win_unicode_console\n\nFor experimental, ‘driverless’ printing (see print command), ImageMagick and GhostScript need to be installed:\n\n    # apt-get install imagemagick ghostscript\n\n### Usage\n\n```\nusage: pret.py [-h] [-s] [-q] [-d] [-i file] [-o file] target {ps,pjl,pcl}\n\npositional arguments:\n  target                printer device or hostname\n  {ps,pjl,pcl}          printing language to abuse\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -s, --safe            verify if language is supported\n  -q, --quiet           suppress warnings and chit-chat\n  -d, --debug           enter debug mode (show traffic)\n  -i file, --load file  load and run commands from file\n  -o file, --log file   log raw data sent to the target\n```\n\n###### Example usage:\n\n    $ ./pret.py laserjet.lan ps\n    $ ./pret.py /dev/usb/lp0 pjl\n\n###### Positional Arguments:\n\nPRET requires a valid target and a printer language as arguments. The target can either be the IP address/hostname of a network printer (with port 9100/tcp open) or a device like `/dev/usb/lp0` for a local USB printer. To quickly discover all network printers in your subnet using SNMP broadcast, simply run PRET without arguments:\n\n```\n./pret.py\nNo target given, discovering local printers\n\naddress          device                       uptime    status                 \n───────────────────────────────────────────────────────────────────────────────\n192.168.1.5      hp LaserJet 4250             10:21:49   Ready                 \n192.168.1.11     HP LaserJet M3027 MFP        13 days    Paper jam             \n192.168.1.27     Lexmark X792                 153 days   Ready                 \n192.168.1.28     Brother MFC-7860DW           16:31:17   Sleep mode            \n```\n\nThe printer language to be abused must be one of `ps`, `pjl` or `pcl`. Not all languages are supported by every printer, so you may want to switch languages if you don't receive any feedback. Each printer language is mapped to a different set of PRET commands and has different capabilities to exploit.\n\n###### Optional Arguments:\n\n`--safe` tries to check via IPP, HTTP and SNMP if the selected printing language (PS/PJL/PCL) is actually supported by the device before connecting. On non-networked printers (USB, parallel cable) this test will fail.\n\n`--quit` suppresses printer model determination, intro message and some other chit-chat.\n\n`--debug` shows the datastream actually sent to the device and the feedback received. Note that header data and other overhead is filtered. The see the whole traffic, use wireshark. Debugging can also be switched on/off within a PRET session using the `debug` command \n\n`--load filename` reads and executes PRET commands from a text file. This is useful for automation. Command files can also be invoked later within a PRET session via the `load` command.\n\n`--log filename` writes a copy of the raw datastream sent to the printer into a file. This can be useful to build a malicious print job file which can be deployed on another printer not directly reachable, for example by printing it from USB drive.\n\n### Generic Commands\n\nAfter connecting to a printer device, you will see the PRET shell and can execute various commands:\n\n```\n$ ./pret.py laserjet.lan pjl\n      ________________\n    _/_______________/|\n   /___________/___//||   PRET | Printer Exploitation Toolkit v0.25\n  |===        |----| ||    by Jens Mueller \u003cjens.a.mueller@rub.de\u003e\n  |           |   ô| ||\n  |___________|   ô| ||\n  | ||/.´---.||    | ||        「 cause your device can be\n  |-||/_____\\||-.  | |´           more fun than paper jams 」\n  |_||=L==H==||_|__|/\n\n     (ASCII art by\n     Jan Foerster)\n\nConnection to laserjet.lan established\nDevice:   hp LaserJet 4250\n\nWelcome to the pret shell. Type help or ? to list commands.\nlaserjet.lan:/\u003e help\n\nAvailable commands (type help \u003ctopic\u003e):\n=======================================\nappend  debug    edit    free  id    ls       open      restart   timeout  \ncat     delete   env     fuzz  info  mirror   printenv  selftest  touch    \ncd      df       exit    get   load  mkdir    put       set       traversal\nchvol   disable  find    help  lock  nvram    pwd       site      unlock   \nclose   display  format  hold  loop  offline  reset     status    version  \n\nlaserjet.lan:/\u003e ls ../../\n-      834   .profile\nd        -   bin\nd        -   dev\nd        -   etc\nd        -   hp\nd        -   hpmnt\n-     1276   init\nd        -   lib\nd        -   pipe\nd        -   tmp\nlaserjet.lan:/\u003e exit\n```\n\nA list of generic PRET commands is given below:\n\n```\nhelp      List available commands or get detailed help with 'help cmd'.\ndebug     Enter debug mode. Use 'hex' for hexdump:  debug [hex]\nload      Run commands from file:  load cmd.txt\nloop      Run command for multiple arguments:  loop \u003ccmd\u003e \u003carg1\u003e \u003carg2\u003e …\nopen      Connect to remote device:  open \u003ctarget\u003e\nclose     Disconnect from device.\ntimeout   Set connection timeout:  timeout \u003cseconds\u003e\ndiscover  Discover local printer devices via SNMP.\nprint     Print image file or raw text:  print \u003cfile\u003e|\"text\"\nsite      Execute custom command on printer:  site \u003ccommand\u003e\nexit      Exit the interpreter.\n```\n\nGeneric file system operations with a PS/PJL/PCL specific implementation are:\n\n```\n┌───────────┬─────┬─────┬─────┬────────────────────────────────────────┐\n│ Command   │ PS  │ PJL │ PCL │ Description                            │\n├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤\n│ ls        │  ✓  │  ✓  │  ✓  │ List contents of remote directory.     │\n│ get       │  ✓  │  ✓  │  ✓  │ Receive file: get \u003cfile\u003e               │\n│ put       │  ✓  │  ✓  │  ✓  │ Send file: put \u003clocal file\u003e            │\n│ append    │  ✓  │  ✓  │     │ Append to file: append \u003cfile\u003e \u003cstr\u003e    │\n│ delete    │  ✓  │  ✓  │  ✓  │ Delete remote file: delete \u003cfile\u003e      │\n│ rename    │  ✓  │     │     │ Rename remote file: rename \u003cold\u003e \u003cnew\u003e │\n│ find      │  ✓  │  ✓  │     │ Recursively list directory contents.   │\n│ mirror    │  ✓  │  ✓  │     │ Mirror remote filesystem to local dir. │\n│ cat       │  ✓  │  ✓  │  ✓  │ Output remote file to stdout.          │\n│ edit      │  ✓  │  ✓  │  ✓  │ Edit remote files with vim.            │\n│ touch     │  ✓  │  ✓  │     │ Update file timestamps: touch \u003cfile\u003e   │\n│ mkdir     │  ✓  │  ✓  │     │ Create remote directory: mkdir \u003cpath\u003e  │\n├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤\n│ cd        │  ✓  │  ✓  │     │ Change remote working directory.       │\n│ pwd       │  ✓  │  ✓  │     │ Show working directory on device.      │\n│ chvol     │  ✓  │  ✓  │     │ Change remote volume: chvol \u003cvolume\u003e   │\n│ traversal │  ✓  │  ✓  │     │ Set path traversal: traversal \u003cpath\u003e   │\n├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤\n│ format    │  ✓  │  ✓  │     │ Initialize printer's file system.      │\n│ fuzz      │  ✓  │  ✓  │     │ File system fuzzing: fuzz \u003ccategory\u003e   │\n├─ ─ ─ ─ ─ ─┴─ ─ ─┴─ ─ ─┴─ ─ ─┴─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤\n│   path   - Explore fs structure with path traversal strategies.      │\n│   write  - First put/append file, then check for its existence.      │\n│   blind  - Read-only tests for existing files like /etc/passwd.      │\n├───────────┬─────┬─────┬─────┬────────────────────────────────────────┤\n│ df        │  ✓  │  ✓  │     │ Show volume information.               │\n│ free      │  ✓  │  ✓  │  ✓  │ Show available memory.                 │\n└───────────┴─────┴─────┴─────┴────────────────────────────────────────┘\n```\n\n### Commands in PS mode\n\n```\nid         Show device information.\nversion    Show PostScript interpreter version.\ndevices    Show available I/O devices.\nuptime     Show system uptime (might be random).\ndate       Show printer's system date and time.\npagecount  Show printer's page counter.\n\nlock       Set startjob and system parameters password.\nunlock     Unset startjob and system parameters password.\nrestart    Restart PostScript interpreter.\nreset      Reset PostScript settings to factory defaults.\ndisable    Disable printing functionality.\ndestroy    Cause physical damage to printer's NVRAM.\nhang       Execute PostScript infinite loop.\n\noverlay    Put overlay eps file on all hardcopies:  overlay \u003cfile.eps\u003e\ncross      Put printer graffiti on all hardcopies:  cross \u003cfont\u003e \u003ctext\u003e\nreplace    Replace string in documents to be printed:  replace \u003cold\u003e \u003cnew\u003e\ncapture    Capture further jobs to be printed on this device.\nhold       Enable job retention.\n\nset        Set key to value in topmost dictionary:  set \u003ckey=value\u003e\nknown      List supported PostScript operators:  known \u003coperator\u003e\nsearch     Search all dictionaries by key:  search \u003ckey\u003e\ndicts      Return a list of dictionaries and their permissions.\nresource   List or dump PostScript resource:  resource \u003ccategory\u003e [dump]\n\ndump       Dump dictionary:  dump \u003cdict\u003e\n  Dictionaries: - systemdict - statusdict - userdict \n                - globaldict - serverdict - errordict\n                - internaldict - currentsystemparams\n                - currentuserparams - currentpagedevice\n\nconfig     Change printer settings:  config \u003csetting\u003e\n  duplex        - Set duplex printing.\n  copies #      - Set number of copies.\n  economode     - Set economic mode.\n  negative      - Set negative print.\n  mirror        - Set mirror inversion.\n```\n\nNot all commands are supported by every printer. Especially Brother and Kyocera devices use their own PostScript clones – Br-Script and KPDL – instead of licensing original ‘Adobe PostScript’. Such flavours of the PostScript language may not be 100% compatible, especially concerning security sensitive features like capturing print jobs. Access to the file system is supported by most printers, however usually limited to a certain, sandboxed directory.\n\n### Commands in PJL mode\n\n```\nid         Show device information.\nstatus     Enable status messages.\nversion    Show firmware version or serial number (from 'info config').\npagecount  Manipulate printer's page counter:  pagecount \u003cnumber\u003e\nprintenv   Show printer environment variable:  printenv \u003cVAR\u003e\nenv        Show environment variables (alias for 'info variables').\nset        Set printer environment variable:  set \u003cVAR=VALUE\u003e\n\ndisplay    Set printer's display message:  display \u003cmessage\u003e\noffline    Take printer offline and display message:  offline \u003cmessage\u003e\nrestart    Restart printer.\nreset      Reset to factory defaults.\nselftest   Perform various printer self-tests.\ndisable    Disable printing functionality.\ndestroy    Cause physical damage to printer's NVRAM.\nflood      Flood user input, may reveal buffer overflows.\n\nlock       Lock control panel settings and disk write access.\nunlock     Unlock control panel settings and disk write access.\nhold       Enable job retention.\n\nnvram      NVRAM operations:  nvram \u003coperation\u003e\n  nvram dump [all]           - Dump (all) NVRAM to local file.\n  nvram read addr            - Read single byte from address.\n  nvram write addr value     - Write single byte to address.\n\ninfo       Show information:  info \u003ccategory\u003e\n  info config      - Provides configuration information.\n  info filesys     - Returns PJL file system information.\n  info id          - Provides the printer model number.\n  info memory      - Identifies amount of memory available.\n  info pagecount   - Returns the number of pages printed.\n  info status      - Provides the current printer status.\n  info ustatus     - Lists the unsolicited status variables.\n  info variables   - Lists printer's environment variables.\n```\n\nSome commands are supported exclusively by HP printers, because other vendors have only implemented a subset of the PJL standard. This is especially true for PML based commands like `restart`or `reset`. Enabling long-term job retention via the `hold` command seems to be possible for some Epson devices only. NVRAM access via the `nvram` command is a proprietary feature of Brother printers. Limited access to the file system is supported by various HP, OKI, Konica, Xerox, Epson and Ricoh devices.\n\n### Commands in PCL mode\n\n```\nselftest   Perform printer self-test.\ninfo       Show information:  info \u003ccategory\u003e\n  info fonts      - Show installed fonts.\n  info macros     - Show installed macros.\n  info patterns   - Show user-defined patterns.\n  info symbols    - Show symbol sets.\n  info extended   - Show extended fonts.\n```\n\nPCL is a very limited page description language without access to the file system. The `get`/`put`/`ls` commands therefore use a virtual file system based on PCL macros, implemented mostly for the hack value. This proof-of-concept shows that even a device which supports only minimalist languages like PCL can be used to store arbitrary files like copyright infringing material. Although such a file sharing service is not a security vulnerability per se, it might apply as ‘misuse of service’ depending on the corporate policy\n\n### File Listing\n\n- `pret.py` - Executable main program\n- `capabilities.py` - Routines to check for printer language support\n- `discovery.py` - Routines to list printers using SNMP broadcast\n- `printer.py` - Generic code to describe a printing device\n- `postscript.py` - PS specific code (inherits from class printer)\n- `pjl.py` - PJL specific code (inherits from class printer)\n- `pcl.py` - PCL specific code (inherits from class printer)\n- `helper.py` - Help functions for output, logging, sockets, etc.\n- `codebook.py` - Static table of PJL status/error codes\n- `fuzzer.py` - Constants for file system fuzzing\n- `mibs/*` - Printer specific SNMP MIBs\n- `db/*` - database of supported models\n- `lpd/*` - Scripts for LPD fuzzing\n\n### Getting Started\n\nGiven the features and various proprietary extensions in printing languages like PostScript and PJL, conducting a pentest on printers is not a trivial job. PRET can help to assist and verify known issues in the language. Once you have played around with the tool, you may want to perform a systematic printer security analysis. A good starting point is the [Printer Security Testing Cheat Sheet](http://hacking-printers.net/wiki/index.php?title=Printer_Security_Testing_Cheat_Sheet).\n\n**Happy Hacking!**\n","funding_links":[],"categories":["Tools","Python","Network Tools","Python (1887)","Network","Software Tools"],"sub_categories":["IoT","Intentionally Vulnerable Systems as Docker Containers","Network Tools","Hardware Tools","Forensics","Docker Containers of Penetration Testing Distributions and Tools","Analysis Frameworks"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRUB-NDS%2FPRET","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRUB-NDS%2FPRET","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRUB-NDS%2FPRET/lists"}