
Printer Exploitation Toolkit - Das Tool, das die Müllcontainer-Durchsuchung überflüssig gemacht hat.
Ist Ihr Drucker sicher? Überprüfen Sie es, bevor es jemand anderes tut...
PRET ist ein neues Werkzeug für Druckersicherheitstests, das im Rahmen einer Masterarbeit an der Ruhr-Universität Bochum entwickelt wurde. Es verbindet sich über Netzwerk oder USB mit einem Gerät und nutzt die Funktionen einer bestimmten Druckersprache aus. Derzeit werden PostScript, PJL und PCL unterstützt, die von den meisten Laserdruckern verwendet werden. Dies ermöglicht coole Dinge wie das Erfassen oder Manipulieren von Druckaufträgen, den Zugriff auf das Dateisystem und den Speicher des Druckers oder sogar die Verursachung physischer Schäden am Gerät. Alle Angriffe sind detailliert im Hacking Printers Wiki dokumentiert.
Die Hauptidee von PRET ist es, die Kommunikation zwischen dem Endbenutzer und dem Drucker zu erleichtern. Nach Eingabe eines UNIX-ähnlichen Befehls übersetzt PRET diesen in PostScript, PJL oder PCL, sendet ihn an den Drucker, wertet das Ergebnis aus und übersetzt es zurück in ein benutzerfreundliches Format. PRET bietet eine ganze Reihe von Befehlen, die für Druckerangriffe und Fuzzing nützlich sind.

PRET benötigt nur einen Python2-Interpreter. Für farbige Ausgabe und SNMP-Unterstützung müssen jedoch Module von Drittanbietern installiert werden:
# pip install colorama pysnmp
Falls in einer Windows-Konsole Unicode-Zeichen nicht korrekt angezeigt werden, installieren Sie das win_unicode_console-Modul:
# pip install win_unicode_console
Für experimentelles, 'treiberloses' Drucken (siehe print-Befehl) müssen ImageMagick und GhostScript installiert werden:
# 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
PRET benötigt ein gültiges Ziel und eine Druckersprache als Argumente. Das Ziel kann entweder die IP-Adresse/der Hostname eines Netzwerkdruckers (mit offenem Port 9100/tcp) oder ein Gerät wie /dev/usb/lp0 für einen lokalen USB-Drucker sein. Um schnell alle Netzwerkdrucker in Ihrem Subnetz mittels SNMP-Broadcast zu entdecken, führen Sie PRET einfach ohne Argumente aus:
./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
Die zu missbrauchende Druckersprache muss eine von ps, pjl oder pcl sein. Nicht alle Sprachen werden von jedem Drucker unterstützt, daher möchten Sie möglicherweise die Sprache wechseln, wenn Sie kein Feedback erhalten. Jede Druckersprache ist einem anderen Satz von PRET-Befehlen zugeordnet und hat unterschiedliche Fähigkeiten zur Ausnutzung.
--safe versucht über IPP, HTTP und SNMP zu prüfen, ob die ausgewählte Druckersprache (PS/PJL/PCL) tatsächlich vom Gerät unterstützt wird, bevor eine Verbindung hergestellt wird. Bei nicht vernetzten Druckern (USB, paralleles Kabel) schlägt dieser Test fehl.
--quit unterdrückt die Bestimmung des Druckermodells, die Einführungsnachricht und einige andere Gespräche.
--debug zeigt den tatsächlich an das Gerät gesendeten Datenstrom und das erhaltene Feedback. Beachten Sie, dass Header-Daten und andere Overheads gefiltert werden. Um den gesamten Verkehr zu sehen, verwenden Sie Wireshark. Das Debuggen kann auch innerhalb einer PRET-Sitzung mit dem debug-Befehl ein- und ausgeschaltet werden.
--load Dateiname liest und führt PRET-Befehle aus einer Textdatei aus. Dies ist nützlich für die Automatisierung. Befehlsdateien können später innerhalb einer PRET-Sitzung über den load-Befehl aufgerufen werden.
--log Dateiname schreibt eine Kopie des rohen Datenstroms, der an den Drucker gesendet wird, in eine Datei. Dies kann nützlich sein, um eine bösartige Druckauftragsdatei zu erstellen, die auf einem anderen, nicht direkt erreichbaren Drucker eingesetzt werden kann, zum Beispiel durch Drucken von einem USB-Laufwerk.
Nach der Verbindung zu einem Druckergerät sehen Sie die PRET-Shell und können verschiedene Befehle ausführen:
$ ./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
Eine Liste generischer PRET-Befehle finden Sie unten:
help Listet verfügbare Befehle auf oder zeigt detaillierte Hilfe mit 'help cmd'.
debug Debug-Modus aktivieren. Verwende 'hex' für Hexdump: debug [hex]
load Führe Befehle aus Datei aus: load cmd.txt
loop Führe Befehl für mehrere Argumente aus: loop <Befehl> <Arg1> <Arg2> …
open Verbinde zu entferntem Gerät: open <Ziel>
close Trenne Verbindung zum Gerät.
timeout Setze Verbindungszeitüberschreitung: timeout <Sekunden>
discover Entdecke lokale Druckergeräte über SNMP.
print Drucke Bilddatei oder Rohtext: print <Datei>|"Text"
site Führe benutzerdefinierten Befehl auf Drucker aus: site <Befehl>
exit Beende den Interpreter.
Generische Dateisystemoperationen mit einer PS-/PJL-/PCL-spezifischen Implementierung sind:
┌───────────┬─────┬─────┬─────┬────────────────────────────────────────┐
│ Befehl │ PS │ PJL │ PCL │ Beschreibung │
├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤
│ ls │ ✓ │ ✓ │ ✓ │ Liste den Inhalt des entfernten Verzeichnisses auf. │
│ get │ ✓ │ ✓ │ ✓ │ Erhalte Datei: get <Datei> │
│ put │ ✓ │ ✓ │ ✓ │ Sende Datei: put <lokale Datei> │
│ append │ ✓ │ ✓ │ │ An Datei anhängen: append <Datei> <Str> │
│ delete │ ✓ │ ✓ │ ✓ │ Lösche entfernte Datei: delete <Datei> │
│ rename │ ✓ │ │ │ Benenne entfernte Datei um: rename <alt> <neu> │
│ find │ ✓ │ ✓ │ │ Liste rekursiv den Verzeichnisinhalt auf. │
│ mirror │ ✓ │ ✓ │ │ Spiegele entferntes Dateisystem in lokales Verzeichnis. │
│ cat │ ✓ │ ✓ │ ✓ │ Gebe entfernte Datei auf stdout aus. │
│ edit │ ✓ │ ✓ │ ✓ │ Bearbeite entfernte Dateien mit vim. │
│ touch │ ✓ │ ✓ │ │ Aktualisiere Dateizeitstempel: touch <Datei> │
│ mkdir │ ✓ │ ✓ │ │ Erstelle entferntes Verzeichnis: mkdir <Pfad> │
├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤
│ cd │ ✓ │ ✓ │ │ Wechsle entferntes Arbeitsverzeichnis. │
│ pwd │ ✓ │ ✓ │ │ Zeige Arbeitsverzeichnis auf Gerät. │
│ chvol │ ✓ │ ✓ │ │ Wechsle entferntes Volume: chvol <Volume> │
│ traversal │ ✓ │ ✓ │ │ Setze Pfad-Traversal: traversal <Pfad> │
├───────────┼─────┼─────┼─────┼────────────────────────────────────────┤
│ format │ ✓ │ ✓ │ │ Initialisiere das Dateisystem des Druckers. │
│ fuzz │ ✓ │ ✓ │ │ Dateisystem-Fuzzing: fuzz <Kategorie> │
├─ ─ ─ ─ ─ ─┴─ ─ ─┴─ ─ ─┴─ ─ ─┴─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤
│ path - Erkunde Dateisystemstruktur mit Pfad-Traversal-Strategien. │
│ write - Zuerst Datei put/append, dann auf Existenz prüfen. │
│ blind - Schreibgeschützte Tests auf vorhandene Dateien wie /etc/passwd. │
├───────────┬─────┬─────┬─────┬────────────────────────────────────────┤
│ df │ ✓ │ ✓ │ │ Zeige Volume-Informationen. │
│ free │ ✓ │ ✓ │ ✓ │ Zeige verfügbaren Speicher. │
└───────────┴─────┴─────┴─────┴────────────────────────────────────────┘
id Zeige Geräteinformationen.
version Zeige PostScript-Interpreter-Version.
devices Zeige verfügbare I/O-Geräte.
uptime Zeige Systembetriebszeit (kann zufällig sein).
date Zeige Systemdatum und -uhrzeit des Druckers.
pagecount Zeige Seitenzähler des Druckers.
lock Setze Startjob- und Systemparameter-Passwort.
unlock Entferne Startjob- und Systemparameter-Passwort.
restart Starte PostScript-Interpreter neu.
reset Setze PostScript-Einstellungen auf Werkseinstellungen zurück.
disable Deaktiviere Druckfunktionalität.
destroy Verursache physischen Schaden am NVRAM des Druckers.
hang Führe PostScript-Endlosschleife aus.
overlay Lege Overlay-EPS-Datei auf alle Hardcopies: overlay <Datei.eps>
cross Füge Drucker-Graffiti auf alle Hardcopies ein: cross <Schriftart> <Text>
replace Ersetze Zeichenfolge in zu druckenden Dokumenten: replace <alt> <neu>
capture Erfasse weitere auf diesem Gerät zu druckende Aufträge.
hold Aktiviere Auftragsrückhaltung.
set Setze Schlüssel auf Wert im obersten Wörterbuch: set <Schlüssel=Wert>
known Liste unterstützte PostScript-Operatoren auf: known <Operator>
search Durchsuche alle Wörterbücher nach Schlüssel: search <Schlüssel>
dicts Gib eine Liste von Wörterbüchern und deren Berechtigungen zurück.
resource Liste oder dump PostScript-Ressource: resource <Kategorie> [dump]
dump Dump Wörterbuch: dump <dict>
Wörterbücher: - systemdict - statusdict - userdict
- globaldict - serverdict - errordict
- internaldict - currentsystemparams
- currentuserparams - currentpagedevice
config Ändere Druckereinstellungen: config <Einstellung>
duplex - Duplexdruck einstellen.
copies # - Anzahl der Kopien einstellen.
economode - Sparmodus einstellen.
negative - Negativdruck einstellen.
mirror - Spiegelung einstellen.
Nicht alle Befehle werden von jedem Drucker unterstützt. Insbesondere Brother- und Kyocera-Geräte verwenden ihre eigenen PostScript-Klone – Br-Script und KPDL – anstatt das originale 'Adobe PostScript' zu lizenzieren. Solche Varianten der PostScript-Sprache sind möglicherweise nicht 100% kompatibel, insbesondere bei sicherheitskritischen Funktionen wie dem Erfassen von Druckaufträgen. Der Zugriff auf das Dateisystem wird von den meisten Druckern unterstützt, ist jedoch normalerweise auf ein bestimmtes, sandboxed Verzeichnis beschränkt.
id Zeige Geräteinformationen.
status Aktiviere Statusmeldungen.
version Zeige Firmware-Version oder Seriennummer (aus 'info config').
pagecount Manipuliere Seitenzähler des Druckers: pagecount <Nummer>
printenv Zeige Drucker-Umgebungsvariable: printenv <VAR>
env Zeige Umgebungsvariablen (Alias für 'info variables').
set Setze Drucker-Umgebungsvariable: set <VAR=WERT>
display Setze Anzeigemeldung des Druckers: display <Meldung>
offline Schalte Drucker offline und zeige Meldung: offline <Meldung>
restart Starte Drucker neu.
reset Setze auf Werkseinstellungen zurück.
selftest Führe verschiedene Drucker-Selbsttests durch.
disable Deaktiviere Druckfunktionalität.
destroy Verursache physischen Schaden am NVRAM des Druckers.
flood Überflute Benutzereingabe, kann Pufferüberläufe aufdecken.
lock Sperre Bedienfeldeinstellungen und Schreibzugriff auf die Festplatte.
unlock Entsperre Bedienfeldeinstellungen und Schreibzugriff auf die Festplatte.
hold Aktiviere Auftragsrückhaltung.
nvram NVRAM-Operationen: nvram <Operation>
nvram dump [all] - Dump (alles) NVRAM in lokale Datei.
nvram read Adresse - Lese einzelnes Byte von Adresse.
nvram write Adresse Wert - Schreibe einzelnes Byte an Adresse.
info Zeige Informationen: info <Kategorie>
info config - Liefert Konfigurationsinformationen.
info filesys - Gibt PJL-Dateisysteminformationen zurück.
info id - Liefert die Druckermodellnummer.
info memory - Identifiziert die verfügbare Speichermenge.
info pagecount - Gibt die Anzahl der gedruckten Seiten zurück.
info status - Liefert den aktuellen Druckerstatus.
info ustatus - Listet die unaufgeforderten Statusvariablen auf.
info variables - Listet die Umgebungsvariablen des Druckers auf.
Einige Befehle werden ausschließlich von HP-Druckern unterstützt, da andere Hersteller nur eine Teilmenge des PJL-Standards implementiert haben. Dies gilt insbesondere für PML-basierte Befehle wie restart oder reset. Die Aktivierung der langfristigen Auftragsrückhaltung über den hold-Befehl scheint nur für einige Epson-Geräte möglich zu sein. Der NVRAM-Zugriff über den nvram-Befehl ist eine proprietäre Funktion von Brother-Druckern. Eingeschränkter Zugriff auf das Dateisystem wird von verschiedenen HP-, OKI-, Konica-, Xerox-, Epson- und Ricoh-Geräten unterstützt.
selftest Führe Drucker-Selbsttest durch.
info Zeige Informationen: info <Kategorie>
info fonts - Zeige installierte Schriftarten.
info macros - Zeige installierte Makros.
info patterns - Zeige benutzerdefinierte Muster.
info symbols - Zeige Symbolgruppen.
info extended - Zeige erweiterte Schriftarten.
PCL ist eine sehr eingeschränkte Seitenbeschreibungssprache ohne Zugriff auf das Dateisystem. Die get/put/ls-Befehle verwenden daher ein virtuelles Dateisystem, das auf PCL-Makros basiert und hauptsächlich aus Hackergründen implementiert wurde. Dieses Proof-of-Concept zeigt, dass selbst ein Gerät, das nur minimalistische Sprachen wie PCL unterstützt, zum Speichern beliebiger Dateien wie urheberrechtsverletzendes Material verwendet werden kann. Obwohl ein solcher Dateifreigabedienst an sich keine Sicherheitsschwachstelle darstellt, könnte er je nach Unternehmensrichtlinie als 'Missbrauch des Dienstes' gelten.
pret.py - Ausführbares Hauptprogrammcapabilities.py - Routinen zur Prüfung der Druckersprachenunterstützungdiscovery.py - Routinen zur Auflistung von Druckern per SNMP-Broadcastprinter.py - Generischer Code zur Beschreibung eines Druckgerätspostscript.py - PS-spezifischer Code (erbt von der Klasse printer)pjl.py - PJL-spezifischer Code (erbt von der Klasse printer)pcl.py - PCL-spezifischer Code (erbt von der Klasse printer)helper.py - Hilfsfunktionen für Ausgabe, Protokollierung, Sockets usw.codebook.py - Statische Tabelle der PJL-Status-/Fehlercodesfuzzer.py - Konstanten für Dateisystem-Fuzzingmibs/* - Druckerspezifische SNMP-MIBsdb/* - Datenbank der unterstützten ModelleAngesichts der Funktionen und verschiedenen proprietären Erweiterungen in Druckersprachen wie PostScript und PJL ist die Durchführung eines Pentests an Druckern keine triviale Aufgabe. PRET kann helfen, bekannte Probleme in der Sprache zu unterstützen und zu verifizieren. Nachdem Sie mit dem Werkzeug herumgespielt haben, möchten Sie vielleicht eine systematische Druckersicherheitsanalyse durchführen. Ein guter Ausgangspunkt ist das Printer Security Testing Cheat Sheet.
Viel Spaß beim Hacken!
lpd/* - Skripte für LPD-Fuzzing