0

I'm currently trying to do some tests with the buffer overflow vulnerability. Here is the vulnerable code

void win()
  {
      printf("code flow successfully changed\n");
  }

int main(int argc, char **argv)
  {
      volatile int (*fp)();
      char buffer[64];

      fp = 0;

      gets(buffer);

      if(fp) {
           printf("calling function pointer, jumping to 0x%08x\n", fp);
           fp();
             }
   }

The exploit is quite sample and very basic: all what I need here is to overflow the buffer and override the fp value to make it hold the address of win() function. While trying to debug the program, I figured out that fb is placed below the buffer (i.e with a lower address in memory), and thus I am not able to modify its value. I thought that once we declare a local variable x before y, x will be higher in memory (i.e at the bottom of the stack) so x can override y if it exceeds its boundaries which is not the case here. I'm compiling the program with gcc gcc version 5.2.1, no special flags (only tested -O0)

Any clue?

Ahmed202
  • 737
  • 3
  • 7
  • 12
  • [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/q/1694036/995714) – phuclv Sep 14 '21 at 04:06

2 Answers2

3

The order of local variable on the stack is unspecified.

It may change between different compilers, different versions or different optimization options. It may even depend on the names of the variables or other seemingly unrelated things.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
RalfFriedl
  • 1,134
  • 3
  • 11
  • 12
0

The order of local variables on the stack is not defined until compile/link (build) time. I'm no expert certainly, but I think you'd have to do some sort of a "hex dump", or perhaps run the code in a debugger environment to find out where it's allocated. And I'd also guess that this would be a relative address, not an absolute one.

And as @RalfFriedl has indicated in his answer, the location could change under any number of compiler options invoked for different platforms, etc.

But we do know it's possible to do buffer overflows. Although you do hear less about them now due to defensive measures such as address space layout randomization (ASLR), they're still around and paying the bills for someone I'd guess. There are of course many many online articles on the subject; here's one that seems fairly current(https://www.synopsys.com/blogs/software-security/detect-prevent-and-mitigate-buffer-overflow-attacks/).

Good luck (should you even say that to someone practicing buffer overflow attacks?). At any rate, I hope you learn some things, and use it for good :)

  • Hi @Seamus, the ASLR is used to change the addresses of functions in libc in a random way each time you run the program, more precisely, ASRL is used to shift by a random value all the components of the memory like the stack, heap, text... As a defense mechanism it prevents the return-into-libc and ROP attacks. It does not prevent the stack smashing (this is the role of stack canaries). Preventing an overflown buffer from changing the value of another local variable on the stack is not possible in my opinion. – Ahmed202 Aug 16 '18 at 08:29
  • @Ahmed202: Thank you for the clarification. I'm really out of my depth here, but you you seem to be quite knowledgeable - perhaps you should answer? I'd be very interested to learn more about how this works. I'm only here as this question was asked in another forum, then got moved... so I feel a bit like [Dorothy in the Wizard of Oz](https://www.youtube.com/watch?v=cMhrpapLTZM) :) –  Aug 16 '18 at 12:37
  • I guess that the compiler is performing a kind of optimization by reordering local variables on the stack. If my hypothesis is true, forcing the "non-optimization" mode by adding -O0 flag to the gcc will keep the order as intended in the program i.e fp above the buffer... – Ahmed202 Aug 17 '18 at 14:48