
Printer Exploitation Toolkit - A ferramenta que tornou obsoleto o mergulho em lixeiras.
A sua impressora está segura? Verifique antes que alguém o faça...
O PRET é uma nova ferramenta para testes de segurança de impressoras desenvolvida no âmbito de uma Dissertação de Mestrado na Universidade de Ruhr Bochum. Conecta-se a um dispositivo via rede ou USB e explora as funcionalidades de uma determinada linguagem de impressora. Atualmente PostScript, PJL e PCL são suportados, os quais são falados pela maioria das impressoras laser. Isso permite coisas interessantes como capturar ou manipular trabalhos de impressão, acessar o sistema de arquivos e a memória da impressora ou até mesmo causar danos físicos ao dispositivo. Todos os ataques estão documentados em detalhe no Hacking Printers Wiki.
A ideia principal do PRET é facilitar a comunicação entre o utilizador final e a impressora. Assim, após inserir um comando do tipo UNIX, o PRET traduz para PostScript, PJL ou PCL, envia para a impressora, avalia o resultado e traduz de volta para um formato amigável ao utilizador. O PRET oferece um monte de comandos úteis para ataques e fuzzing em impressoras.

O PRET requer apenas um interpretador Python2. No entanto, para saída colorida e suporte SNMP, módulos de terceiros precisam ser instalados:
# pip install colorama pysnmp
Se estiver a executar numa consola Windows e os caracteres Unicode não forem exibidos corretamente, instale o módulo win_unicode_console:
# pip install win_unicode_console
Para impressão experimental 'sem driver' (veja o comando print), o ImageMagick e o GhostScript precisam ser instalados:
# apt-get install imagemagick ghostscript
usage: pret.py [-h] [-s] [-q] [-d] [-i file] [-o file] target {ps,pjl,pcl}
positional arguments:
target printer device or hostname
{ps,pjl,pcl} printing language to abuse
optional arguments:
-h, --help show this help message and exit
-s, --safe verify if language is supported
-q, --quiet suppress warnings and chit-chat
-d, --debug enter debug mode (show traffic)
-i file, --load file load and run commands from file
-o file, --log file log raw data sent to the target
$ ./pret.py laserjet.lan ps
$ ./pret.py /dev/usb/lp0 pjl
O PRET requer um alvo válido e uma linguagem de impressora como argumentos. O alvo pode ser o endereço IP/nome do host de uma impressora de rede (com a porta 9100/tcp aberta) ou um dispositivo como /dev/usb/lp0 para uma impressora USB local. Para descobrir rapidamente todas as impressoras de rede na sua sub-rede usando broadcast SNMP, execute o PRET sem argumentos:
./pret.py
No target given, discovering local printers
address device uptime status
───────────────────────────────────────────────────────────────────────────────
192.168.1.5 hp LaserJet 4250 10:21:49 Ready
192.168.1.11 HP LaserJet M3027 MFP 13 days Paper jam
192.168.1.27 Lexmark X792 153 days Ready
192.168.1.28 Brother MFC-7860DW 16:31:17 Sleep mode
A linguagem de impressora a ser usada deve ser uma de ps, pjl ou pcl. Nem todas as linguagens são suportadas por todas as impressoras, por isso pode querer trocar de linguagem se não receber nenhum feedback. Cada linguagem de impressora está mapeada para um conjunto diferente de comandos PRET e tem diferentes capacidades de exploração.
--safe tenta verificar via IPP, HTTP e SNMP se a linguagem de impressão selecionada (PS/PJL/PCL) é realmente suportada pelo dispositivo antes de conectar. Em impressoras não ligadas à rede (USB, cabo paralelo) este teste falhará.
--quit suprime a determinação do modelo da impressora, a mensagem de introdução e outras conversas.
--debug mostra o fluxo de dados realmente enviado para o dispositivo e o feedback recebido. Note que os dados de cabeçalho e outras sobrecargas são filtrados. Para ver todo o tráfego, use o wireshark. A depuração também pode ser ativada/desativada dentro de uma sessão PRET usando o comando debug
--load filename lê e executa comandos PRET a partir de um ficheiro de texto. Isto é útil para automação. Os ficheiros de comandos também podem ser invocados posteriormente dentro de uma sessão PRET através do comando load.
--log filename escreve uma cópia do fluxo de dados bruto enviado para a impressora num ficheiro. Isto pode ser útil para construir um ficheiro de trabalho de impressão malicioso que pode ser implantado noutra impressora não diretamente acessível, por exemplo, imprimindo-o a partir de uma unidade USB.
After connecting to a printer device, you will see the PRET shell and can execute various commands:
$ ./pret.py laserjet.lan pjl
________________
_/_______________/|
/___________/___//|| PRET | Printer Exploitation Toolkit v0.25
|=== |----| || by Jens Mueller <[email protected]>
| | ô| ||
|___________| ô| ||
| ||/.´---.|| | || 「 cause your device can be
|-||/_____\||-. | |´ more fun than paper jams 」
|_||=L==H==||_|__|/
(ASCII art by
Jan Foerster)
Connection to laserjet.lan established
Device: hp LaserJet 4250
Welcome to the pret shell. Type help or ? to list commands.
laserjet.lan:/> help
Available commands (type help <topic>):
=======================================
append debug edit free id ls open restart timeout
cat delete env fuzz info mirror printenv selftest touch
cd df exit get load mkdir put set traversal
chvol disable find help lock nvram pwd site unlock
close display format hold loop offline reset status version
laserjet.lan:/> ls ../../
- 834 .profile
d - bin
d - dev
d - etc
d - hp
d - hpmnt
- 1276 init
d - lib
d - pipe
d - tmp
laserjet.lan:/> exit
Uma lista de comandos genéricos do PRET é fornecida abaixo:
help List available commands or get detailed help with 'help cmd'.
debug Enter debug mode. Use 'hex' for hexdump: debug [hex]
load Run commands from file: load cmd.txt
loop Run command for multiple arguments: loop <cmd> <arg1> <arg2> …
open Connect to remote device: open <target>
close Disconnect from device.
timeout Set connection timeout: timeout <seconds>
discover Discover local printer devices via SNMP.
print Print image file or raw text: print <file>|"text"
site Execute custom command on printer: site <command>
exit Exit the interpreter.
Operações genéricas de sistema de ficheiros com uma implementação específica para PS/PJL/PCL são:
┌───────────┬─────┬─────┬─────┬────────────────────────────────────────┐
│ Comando │ PS │ PJL │ PCL │ Descrição │
├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤
│ ls │ ✓ │ ✓ │ ✓ │ Lista o conteúdo do diretório remoto. │
│ get │ ✓ │ ✓ │ ✓ │ Recebe ficheiro: get <file> │
│ put │ ✓ │ ✓ │ ✓ │ Envia ficheiro: put <local file> │
│ append │ ✓ │ ✓ │ │ Acrescenta ao ficheiro: append <file> <str> │
│ delete │ ✓ │ ✓ │ ✓ │ Elimina ficheiro remoto: delete <file> │
│ rename │ ✓ │ │ │ Renomeia ficheiro remoto: rename <old> <new> │
│ find │ ✓ │ ✓ │ │ Lista recursivamente o conteúdo do diretório. │
│ mirror │ ✓ │ ✓ │ │ Espelha o sistema de ficheiros remoto para o diretório local. │
│ cat │ ✓ │ ✓ │ ✓ │ Envia ficheiro remoto para stdout. │
│ edit │ ✓ │ ✓ │ ✓ │ Edita ficheiros remotos com vim. │
│ touch │ ✓ │ ✓ │ │ Atualiza timestamps de ficheiro: touch <file> │
│ mkdir │ ✓ │ ✓ │ │ Cria diretório remoto: mkdir <path> │
├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤
│ cd │ ✓ │ ✓ │ │ Muda o diretório de trabalho remoto. │
│ pwd │ ✓ │ ✓ │ │ Mostra o diretório de trabalho no dispositivo. │
│ chvol │ ✓ │ ✓ │ │ Muda volume remoto: chvol <volume> │
│ traversal │ ✓ │ ✓ │ │ Define path traversal: traversal <path>│
├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤
│ format │ ✓ │ ✓ │ │ Inicializa o sistema de ficheiros da impressora. │
│ fuzz │ ✓ │ ✓ │ │ Fuzzing do sistema de ficheiros: fuzz <category> │
├─ ─ ─ ─ ─ ─┴─ ─ ─┴─ ─ ─┴─ ─ ─┴─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤
│ path - Explora a estrutura do sistema de ficheiros com estratégias de path traversal. │
│ write - Primeiro colocar/anexar ficheiro, depois verificar sua existência. │
│ blind - Testes apenas de leitura para ficheiros existentes como /etc/passwd. │
├───────────┬─────┬─────┬─────┬────────────────────────────────────────┤
│ df │ ✓ │ ✓ │ │ Mostra informações do volume. │
│ free │ ✓ │ ✓ │ ✓ │ Mostra memória disponível. │
└───────────┴─────┴─────┴─────┴────────────────────────────────────────┘
id Show device information.
version Show PostScript interpreter version.
devices Show available I/O devices.
uptime Show system uptime (might be random).
date Show printer's system date and time.
pagecount Show printer's page counter.
lock Set startjob and system parameters password.
unlock Unset startjob and system parameters password.
restart Restart PostScript interpreter.
reset Reset PostScript settings to factory defaults.
disable Disable printing functionality.
destroy Cause physical damage to printer's NVRAM.
hang Execute PostScript infinite loop.
overlay Put overlay eps file on all hardcopies: overlay <file.eps>
cross Put printer graffiti on all hardcopies: cross <font> <text>
replace Replace string in documents to be printed: replace <old> <new>
capture Capture further jobs to be printed on this device.
hold Enable job retention.
set Set key to value in topmost dictionary: set <key=value>
known List supported PostScript operators: known <operator>
search Search all dictionaries by key: search <key>
dicts Return a list of dictionaries and their permissions.
resource List or dump PostScript resource: resource <category> [dump]
dump Dump dictionary: dump <dict>
Dictionaries: - systemdict - statusdict - userdict
- globaldict - serverdict - errordict
- internaldict - currentsystemparams
- currentuserparams - currentpagedevice
config Change printer settings: config <setting>
duplex - Set duplex printing.
copies # - Set number of copies.
economode - Set economic mode.
negative - Set negative print.
mirror - Set mirror inversion.
Nem todos os comandos são suportados por todas as impressoras. Especialmente dispositivos Brother e Kyocera usam os seus próprios clones PostScript – Br-Script e KPDL – em vez de licenciar o ‘Adobe PostScript’ original. Tais variantes da linguagem PostScript podem não ser 100% compatíveis, especialmente no que diz respeito a funcionalidades sensíveis à segurança, como capturar trabalhos de impressão. O acesso ao sistema de ficheiros é suportado pela maioria das impressoras, no entanto, geralmente limitado a um determinado diretório restrito.
id Show device information.
status Enable status messages.
version Show firmware version or serial number (from 'info config').
pagecount Manipulate printer's page counter: pagecount <number>
printenv Show printer environment variable: printenv <VAR>
env Show environment variables (alias for 'info variables').
set Set printer environment variable: set <VAR=VALUE>
display Set printer's display message: display <message>
offline Take printer offline and display message: offline <message>
restart Restart printer.
reset Reset to factory defaults.
selftest Perform various printer self-tests.
disable Disable printing functionality.
destroy Cause physical damage to printer's NVRAM.
flood Flood user input, may reveal buffer overflows.
lock Lock control panel settings and disk write access.
unlock Unlock control panel settings and disk write access.
hold Enable job retention.
nvram NVRAM operations: nvram <operation>
nvram dump [all] - Dump (all) NVRAM to local file.
nvram read addr - Read single byte from address.
nvram write addr value - Write single byte to address.
info Show information: info <category>
info config - Provides configuration information.
info filesys - Returns PJL file system information.
info id - Provides the printer model number.
info memory - Identifies amount of memory available.
info pagecount - Returns the number of pages printed.
info status - Provides the current printer status.
info ustatus - Lists the unsolicited status variables.
info variables - Lists printer's environment variables.
Alguns comandos são suportados exclusivamente por impressoras HP, porque outros fornecedores implementaram apenas um subconjunto do padrão PJL. Isto é especialmente verdade para comandos baseados em PML como restart ou reset. Ativar a retenção de trabalhos a longo prazo através do comando hold parece ser possível apenas para alguns dispositivos Epson. O acesso à NVRAM através do comando nvram é uma funcionalidade proprietária das impressoras Brother. O acesso limitado ao sistema de ficheiros é suportado por várias impressoras HP, OKI, Konica, Xerox, Epson e Ricoh.
selftest Perform printer self-test.
info Show information: info <category>
info fonts - Show installed fonts.
info macros - Show installed macros.
info patterns - Show user-defined patterns.
info symbols - Show symbol sets.
info extended - Show extended fonts.
PCL é uma linguagem de descrição de página muito limitada sem acesso ao sistema de ficheiros. Os comandos get/put/ls usam, portanto, um sistema de ficheiros virtual baseado em macros PCL, implementado principalmente pelo valor 'hack'. Esta prova de conceito mostra que mesmo um dispositivo que suporta apenas linguagens minimalistas como PCL pode ser usado para armazenar ficheiros arbitrários como material infrator de direitos autorais. Embora tal serviço de partilha de ficheiros não seja uma vulnerabilidade de segurança por si só, pode ser considerado 'mau uso do serviço' dependendo da política corporativa.
pret.py - Executable main programcapabilities.py - Routines to check for printer language supportdiscovery.py - Routines to list printers using SNMP broadcastprinter.py - Generic code to describe a printing devicepostscript.py - PS specific code (inherits from class printer)pjl.py - PJL specific code (inherits from class printer)pcl.py - PCL specific code (inherits from class printer)helper.py - Help functions for output, logging, sockets, etc.codebook.py - Static table of PJL status/error codesfuzzer.py - Constants for file system fuzzingmibs/* - Printer specific SNMP MIBsdb/* - database of supported modelsDadas as funcionalidades e várias extensões proprietárias em linguagens de impressão como PostScript e PJL, realizar um pentest em impressoras não é um trabalho trivial. O PRET pode ajudar a auxiliar e verificar problemas conhecidos na linguagem. Depois de brincar com a ferramenta, pode querer realizar uma análise sistemática de segurança de impressoras. Um bom ponto de partida é a Cheat Sheet de Testes de Segurança de Impressoras.
Feliz Hacking!
lpd/* - Scripts for LPD fuzzing