1

Practicing and learning buffer overflows by example. I have a question of why a particular buffer overflow is not working with strcpy(). I can trigger the buffer overflow segfault with gets() in stuffing 8 or more characters. My question is for 7 character input. The gets fault condition is not triggered, but copying 7 characters into a buffer of 4 should trigger a segfault in the strcpy() line. What am I missing? Why isn't it triggering?

#include <stdio.h>
#include <string.h>
void pass_function()
{
    int length;
    char bufferA[8];
    char bufferB[4];
    printf("Enter password: ");
    gets(bufferA);

    strcpy(bufferB, bufferA);
    printf("Returning\n");
    return;
}

int main(int argc, char *argv[ ])
{
    pass_function();
    return 0;

}
  • 1
    Please, always provide the compilation flags, so we can debug the issue – Mr. E Jan 28 at 17:32
  • 1
    What is your target achitecture? – r3mus n0x Jan 28 at 17:42
  • x64 architecture. Compiled with: gcc example.c -o example – Robert Jan 28 at 18:27
2

First we must consider that built-in machine architecture decisions impact the way you exploit these issues. For example, in the classical writing Smashing the stack for fun and profit by Aleph One, we can see that an x86 stack typically grows downward (i.e. the base for the stack is the highest address, and as we push onto it, the stack pointer decreases in value)...

Depending on the implementation the stack will either grow down (towards lower memory addresses), or up. In our examples we'll use a stack that grows down. This is the way the stack grows on many computers including the Intel, Motorola, SPARC and MIPS processors.

So for example, assuming your compiler doesn't rearrange the order in which bufferA and bufferB are pushed onto the stack, Aleph One describes an architecture where-by bufferB actually has an address which is lower than that of bufferA. I'm pretty sure this explains your observations correctly; when you overflow bufferB, you're not actually overwriting the return address, but a part of bufferA (or some padding before bufferA). You could verify this by codifying your assertion, such that your runtime will validate it (by either succeeding or generating an error message), like this:

assert(bufferB < bufferA); // I'm asserting that in your case overflowing `bufferB` will result in modifications to `bufferA`.
assert(bufferA < bufferB); // You probably expect that overflowing `bufferB` into `bufferA` is impossible because of this condition... let's see which test passes?

You might need to #include <assert.h> to use assert.

Now having said all of this, there are many, many other issues standing in the way of successfully demonstrating a stack-based buffer overflow. Various protections have been created, such that the only reliable reproduction is typically referred to as a ret2libc attack, and that requires quite intimate knowledge of the specific hardware and OS configuration. As such, I recommend that after reading the paper by Aleph One (linked to above) and before attempting to reproduce that experiment, I highly recommend watching this DEFCON video entitled "(un)Smashing the Stack: Overflows, Countermeasures, and the Real World".

Once you've reviewed these two resources, I'm sure you'll have a much better chance of reproducing a stack-based buffer overflow.

0

Why isn't it triggering?

Because your compiler's handling of Undefined Behaviour is sufficiently relaxed to sidestep a segfault.

(Related questions)

If you compile with a suitably pedantic compiler (Note: such a compiler may not exist) that uses fat pointers and/or other methods to trap on any access outside allocated memory bounds, you'll get your error notifications.

Valgrind and Electric Fence for example get you part-way to that ideal.

-1

I just compile and run your program it's working properly the behaviour of your program totally depends on compiler.Because your compiler compiles it and generate code that runs on your CPU.There is a clear difference between MinGW compiler and GNU C compiler.They are different in behaving ,there is no big difference but little differences are available, try your code in an online c compiler like Try your code in this I've tried your code in this website and the out put you can see at the bottom of image.enter image description here

  • don't you worry sometimes compiler shocks us , sometime it behaves very good beyond our expectations but sometimes it makes us ruthless.If you find problem try to use other resources like other compiler to know more – J.Doe Jan 28 at 17:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.