---

Security problems with lpd

    From: "Kevin K. Sochacki" &ltkksocha@ERENJ.COM>
 Subject: DoS caused by lpd
    Date: Fri, 18 Dec 1998 14:55:28 -0500
      To: BUGTRAQ@netspace.org
Reply-To: Bugtraq List &ltBUGTRAQ@netspace.org>


Hi all,

Denial of Service caused by lpd.

The lpd in question is packaged with RedHat (lpr-0.31-1 or
lpr-0.33-1).   I did not look at lpd on any other plantform, so they may
or may not have the problem.

The problem was reported back on July 28, 1998 by Martin Lacasse
mdlacas@erenj.com to RedHat or more specificlly msf@redhat.com  and
ewt@redhat.com for lpr-0.31-1 and yet lpr-0.33-1 was released with the
same problem.

THE CAUSE
When a remote user prints to a queue that is _not_ restricted (no rs
capability in printcap) on a print server they don't have an account on,
lpd will try to fork the filter as that user.  By this time lpd has
already established a connection to the printer, not being able to fork
because user is not found the connection presist tying up the printer so
that other TCP connection are refused hence the first denial of
service.  Also the job remains at the top of the queue jaming the queue
so other request are accepted but not printed hence the second denial of
service.  Also in looking at the code to hack a fix I noticed that
althought lpd attempts not to run the filters as root if the remote or
local user is root the filters are run as root.  This leaves the filters
open to race condition and the like on poorly writen filters.

THE FIX
Attached is a patch to printjob.c where the problem was found.   The fix
was if user did not exist or is root effectively become lp to fork the
filters other wise fork the filter as the user.

THE PROOF
First let me appologize for the log prompts, but I like to know when,
what, whence, who and where at a glance.
Also the hostnames and IPs have been xxxed out to hide their IDs,
security you know.

#testprint user _does_not_ exist on server
#kksocha user does exist on the server
#both printer job are remote request
#the printcap _does_not_ have a 'rs' for this queue

#as you can see a small 124 byte print request has be made by testprint
user
#and the lpd has a connection hence the sending to reported by lpq

   Mon Dec 14 16:33:05 </dev/ttyp0> /usr/src/redhat/BUILD/lpr-0.33/lpd
   [root@xxprint1]$ lpq -Pxxx01-cc103
   xxprint1.erenj.com: sending to xxx01-cc103
   Rank   Owner      Job  Files                                 Total Size
   1st    testprint  11   .bashrc                               124 bytes
   2nd    kksocha    12   .bashrc                               682 bytes
   0 bytes

   connection to xxx01-cc103 is down

#any attempted to connet to the printer port of the printer is refused
as long as lpd is sending
#however lpd can't fork the filter to actually send the data because the
user _does_not_ exist
#oh port 9100 is also refused but I don't show that here

   Mon Dec 14 16:33:53 </dev/ttyp0> /usr/src/redhat/BUILD/lpr-0.33/lpd
   [root@xxprint1]$ telnet xxx01-cc103 printer
   Trying xxx.xxx.1.167...
   telnet: Unable to connect to remote host: Connection refused

#over 2 minutes later lpd is still trying to  send 124 bytes to printer
which is more then enough
#time as will be proven later with the second larger job in the queue

   Mon Dec 14 16:35:36 </dev/ttyp0> /usr/src/redhat/BUILD/lpr-0.33/lpd
   [root@xxprint1]$ lpq -Pxxx01-cc103
   xxprint1.erenj.com: sending to xxx01-cc103
   Rank   Owner      Job  Files                                 Total
Size
   1st    testprint  11   .bashrc                               124
bytes
   2nd    kksocha    12   .bashrc                               682
bytes
   0 bytes

   connection to xxx01-cc103 is down

#remove the job that is jamming the queue and tying up the connection to
the printer

   Mon Dec 14 16:36:12 </dev/ttyp0> /usr/src/redhat/BUILD/lpr-0.33/lpd
   [root@xxrint1]$ lprm -Pxxx01-cc103 11
   dfA011Aa07949 dequeued
   cfA011dXXXXXXenj.com dequeued
   dfA011Aa14026 dequeued
   cfA011xxnk.erenj.com dequeued

#lpd is now sending the second job to the printer (and their are already
no entries)

   Mon Dec 14 16:36:40 </dev/ttyp0> /usr/src/redhat/BUILD/lpr-0.33/lpd
   [root@xxprint1]$ lpq -Pxxx01-cc103
   xxprint1.erenj.com: sending to xxx01-cc103
   Rank   Owner      Job  Files                                 Total
Size
   1st    kksocha    12   .bashrc                               682
bytes
   0 bytes

   JetDirect lpd: no entries

#only 7 seconds to send 682 bytes to the printer

   Mon Dec 14 16:36:47 </dev/ttyp0> /usr/src/redhat/BUILD/lpr-0.33/lpd
   [root@xxprint1]$ lpq -Pxxx01-cc103
   JetDirect lpd: no entries

#oh look we can now connet to the printer port of the printer

   Mon Dec 14 16:36:56 </dev/ttyp0> /usr/src/redhat/BUILD/lpr-0.33/lpd
   [root@xxprint1]$ telnet xxx01-cc103 printer
   Trying xxx.xxx.1.167...
   Connected to xxx01-cc103.erenj.com.
   Escape character is '^]'.
   ^]
   telnet> close
   Connection closed.

#after my hack every thing worked fine including not fork filters as
root

Thanks for your attention..........

--
(...Later..:)
         _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
        _/                        _/ Exxon Research & Engineering   _/
       _/ _/_/_/ _/_/     _/_/_/ _/ Kevin K. Sochacki              _/
      _/ _/     _/  _/   _/     _/ ICSBS CC124 (908) 730-2911     _/
     _/ _/_/_/ _/_/   & _/_/_/ _/ mailto:kksocha@erenj.com       _/
    _/ _/     _/ _/    _/     _/ PERSONAL                       _/
   _/ _/_/_/ _/  _/   _/_/_/ _/ mailto:kks@superlink.net       _/
  _/                        _/ http://mars.superlink.net/kks  _/
 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends, & analysis