0

i am honing my assembly for buffer overflow exploitation.

Machine specs : kali linux 32 bit running in virtual box.

i am running this code

#include <stdio.h>

getinput(){

  char buffer[8]; //allocating 8 bytes
  gets(buffer); //read input
  puts(buffer); // print;

}

main() {

  getInput();
  return 0 ;
}

My understaning is that when the function getInput() is invoked the following happens :

1 - the address of the next instruction in main is pushed on the stack. 2 - ebp register is pushed on the stack. 3 - 8 bytes are allocated on the stack for the buffer.

That a total of 16 bytes.. but

As you can see in the image , just before reading the input in the getInput() function it shows a total of 24 bytes of the stack. specifically, i don't know why there is an extra 0x0000000 on the top of the stack

moreover, when i try to over-write the return address by inputing something like (ABCDABCDABCDABCD[desired address for target program]) it justs over-writes everything.

And if i try to input something like \xab\xab\xab\xab it gives a segementation fault , although this is only 4 bytes and should fit perfectly into the 8 bytes buffer.

Thank you in advance.

  • 3
    You disassembled `main` not `getinput`. Anyway, the extra space is due to alignment and/or unoptimized code. – Jester Jun 04 '20 at 18:58
  • Unrelated to the stack question, when you input \xab\xab\xab\xab, are you actually inputting the byte `0xAB` four times, or writing the string of those characters, which would have a length of 16? – Thomas Jager Jun 04 '20 at 19:04
  • And the obligatory [never use `gets`!!](https://stackoverflow.com/q/1694036/10077) – Fred Larson Jun 04 '20 at 19:05
  • @FredLarson: This code is vulnerable *on purpose*, as an exercise in buffer overflows. That's *why* it uses the no-longer-standard `gets` (removed in C11). Its advantage here is that it only takes one arg, so the asm stack frame is as simple as possible. – Peter Cordes Jun 04 '20 at 19:14
  • @PeterCordes: That's fine, but I'll leave the comment as a warning to anyone who reads this in the future. – Fred Larson Jun 04 '20 at 19:17
  • 1
    this code will not link – 0___________ Jun 04 '20 at 19:45
  • @ThomasJager, i am really not sure about this , it is supposed to input the 4 bytes into the buffer, but it causes an immediate segmentation fault. although it should fit in the buffer. But it appears to be writing the string of the characters which have a size of 16. do you have a suggestion of how to mitigate this? – Mostafa Saeed Jun 05 '20 at 06:27
  • @MostafaSaidYassin You need to find a different way to pass in your values. The simplest way is to use a hex editor to create a short file with the contents you want, and forward that to `stdin`. The `stdin` doesn't automatically parse `\`-based codes. It's the same for newlines. You can't write `\n` and have a new line happen. – Thomas Jager Jun 05 '20 at 12:08

2 Answers2

2

In real life buffer overflow attacks, you never know the size of the stack frame. If you discover a buffer overflow bug, it's up to you to determine the offset from the buffer start to the return address. Treat your toy example exactly like that.

That said, the structure of the stack frame can be driven by numerous considerations. The calling convention might call for specific stack alignment. The compiler might create invisible variables for its own internal bookkeeping, which may vary depending on compiler flags, such as the level of optimization. There might be some space for saved caller registers, the number of which is driven by the register usage of the function itself. There might even be a guard variable specifically to detect buffer overflows. In general, you can't deduce the stack frame structure from the source alone. Unless you wrote the compiler, that is.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • thakn you for the detailed answer. I figured out that the extra 4 bytes came from pushing ebx ,as you suggested, by the compiler. However, it is still not clear to me why inputing 4 bytes "\xab\xab\xab\xab" causesa segmentation fault – Mostafa Saeed Jun 05 '20 at 06:23
  • I am aware now that /xab/xab/xab/xab is inputing the string length not 4 bytes. – Mostafa Saeed Jun 05 '20 at 06:28
  • unrelated question: when i overwrite the value of the return address with whatever address ( lets say x ) i want. should x be the runtime address or the address at compiling because they are different. – Mostafa Saeed Jun 05 '20 at 06:29
  • Runtime, naturally. That's exactly why [ASLR](https://en.wikipedia.org/wiki/Address_space_layout_randomization) was invented, to make buffer overrun exploits harder. – Seva Alekseyev Jun 05 '20 at 12:32
0

After diassembling the getInput routin , it turned out that the extra 4 bytes came from the compiler pushing $ebx on the stack for some reason.

After testing with various payloads , it appeared that i was not considering the deceptive null byte that is added at the end of the string. so i only need to add one extra byte to mitigate the effect of the null byte.

The proper payload was : printf "AAAAAAAAAAAAA\xc9\x61\x55\x56" | ./test