HP-UX rlpdaemon CVE-2001-1198 explained


I was once reading a lot of data gathered from the Unix estate; some of it HP-UX.

Among the things I read were config files (such as inetd.conf) and lists of setuid programs and it came to my attention that HP-UX's /usr/sbin/rlpdaemon appeared in both of these.

The program was setuid root and was run by root when traffic arrived on port 515/tcp (lpd). The setuid wouldn't be required for the inetd use case so I thought it might also be usable outside of inetd and consulted the man page [1] to find out more.


I noticed the option "-L" to allow the user to choose which file to log to and with this being a setuid root program realised the potential for this to be done unsafely. [2] So I tried using the "-l" and "-L" options together (from my non-root account) but without success. I tried a bit more with "-i -l -L" and got a file created as root. It contained a line of text ("Connection Lost" or similar) and the program quit immediately.


If a program gives the user the ability to write files as root that can usually lead to a root shell - at least if the user gets some control over what's written to the file.

To get some control over the output I would need to get past the state that had the program quit with an error message. I realised that the error with the "Connection Lost" message was misleading. When the program is started with "-i" it expects the arrangement that comes from being started by inetd where the standard streams are network socket descriptors. When calling from a terminal with "-i" that's not the case and when rlpdaemon tries to treat them as network sockets it fails.

To get past the error that causes program termination obviously one or other of these incompatible states must be changed:

  1. drop the "-i" from the command line
  2. provide a network socket for the standard streams
and since the first was already tried that left only the second.

As a non-root user you need to create a network socket on a high-numbered port for use with rlpdaemon and apply it to all three standard streams. Once you have this the program does not quit but remains running and doing nothing.

At this stage it is waiting for input (over the network socket). You want to provide some input that will cause something to be written to the logfile. Maybe submiting a print job would be suitable. After searching online for the details of the lpd network protocol [3] I did this and got text written that started with the name of the program and went on to include other data.

The easiest part to take control of is the name of the program - which is provided by the caller and known to C programmers as argv[0]. Almost any value may be supplied here including text with newlines. That's easily enough to give some ways of getting root access.


I reported this to HP (August 2001) including an exploit that used netcat for the networking and afterward made a more polished version in Perl. [4] After HP released patches (November 2001) and I'd tested them I made a public announcement. [5]

I suspect that this bug report from X-Force [6] which came out after the HP patch and before my own report was based on reverse-engineering the patch. That's why I stated the patch fixed multiple faults (although I'm now doubtful of that).


Once the vendor had the update deploying it was in the hands of other people.


  1. rlpdaemon man page

  2. Norm Hardy on the confused deputy

  3. lpd network protocol rfc1179

  4. exploit rlpdaemon exploit

  5. December 2001 bug report

  6. November 2001 X-Force report
version 3
Written by Peter M Allan. 2015
back to articles