2

I have the following code to simulate buffer overflow.

Edit: I missed an important step in the code below. As the discussion progressed that the variable c is getting modified.

void function (int fd, int e)
{
        int i = 0;
        int n;
        char c;
        char s[44];
        .
        .
        c = getchar(fd);
        .
        //Some check on c
        s[i++] = c;
        .
        //Some more local variables and some operations on them.
}

I am trying to overflow the buffer by sending more input > 4 bytes in order to see how the local variables and EBP and RET and arguments get modified.

However when I debug in GDB to see the stack frame, this buffer gets overflowed and the overflowed data doesn't seem to be allocated contiguous memory locations.

Buffer base address: 0xbfff fdb3 Address of C : 0xbfff fddf Address of i: 0xbfff fde0

As you can see, my input string contains plenty of NOP's (\x90) then plenty of A's (\x41). In the GDB stack frame you can see that the 1st 4 byte of the buffer gets filled contiguously as expected then some part of the excess data also gets filled contiguously. from (address: 0xbffffddc onwards till 0xbffffdfc)

But this is not the complete data. Then there is some other data in between and again my input string can be seen from address 0xbffffe1c to 0xbffffe2c.

SO the buffer although gets overflowed, the overflowed data is not stored in contiguous locations. How can I make the overflow data get stored at continuous locations ?

PS: On my Ubuntu machine, 32 bit system,

RootPhoenix
  • 1,626
  • 1
  • 22
  • 40
  • What platform are you using? I vaguely recall reading about various countermeasures some OSes use to make such attacks harder, randomizing memory locations and such. I know OpenBSD does a lot of that sort of thing. – Tom Zych Nov 14 '15 at 12:52
  • I think this effect is because of canaries, used to present buffer overflow attack. But I am yet to come up with a proper explanation. – Haris Nov 14 '15 at 12:56
  • Compile your code without stack protection, e.g. in GCC `-fno-stack-protector`. In Visual Studio turn the protection off by adding `/GS-` – 0x90 Nov 14 '15 at 13:08
  • @0x90 I already have compiled using gcc -g -fno-stack-protector -z execstack – RootPhoenix Nov 14 '15 at 13:18
  • Please try to use this line: `gcc file.c -o output -fno-stack-protector`. https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Optimize-Options.html – 0x90 Nov 14 '15 at 13:19
  • Yours should be good too, you added `-z execstack` which is fine. I guess that `-g` added debug information to your executable and that's why you are seeing what you have described. Please try to show the assembly and add some information of the exact steps you are following and what commands you put into the the `gdb`, try to be as explicit as possible. – 0x90 Nov 14 '15 at 16:28
  • @0x90 But if I do not compile using -g I will not be able to debug using gdb. I really don't understand why is there break in the stored data. It should ideally be in contiguous space. Edited my question. – RootPhoenix Nov 15 '15 at 13:46
  • It's not exactly true [see this](http://stackoverflow.com/questions/6909047/is-it-possible-to-debug-core-file-generated-by-a-executable-compiled-without-gdb), moreover please upload all the steps you are following. – 0x90 Nov 15 '15 at 13:56

1 Answers1

2

When you declared your variables

    int i = 0;
    int n;
    char c;
    char s[4];

assuming the stack overflows "up" past c, you are relying upon an assumption which may not be true, i.e., that the variables are immediately adjacent on the stack. This may not be true because there may be a "stack guard" or "stack canary" between variables.

To read more about this, look for "stack guard" and "stack canaries":

Community
  • 1
  • 1
Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • I knew this. But according to the first link, and what i know *...Stack Guard writes a Canary word between the local variables and the return address on the stack, before a function is called, and checks it just before the function returns...*. This would mean there is a canary inbetween the return address and the variables, and when buffer overflow is done, that canary would get overwritten(thats how buffer overflow attacks are detected). But here the canary is not getting overwritten. – Haris Nov 14 '15 at 13:01
  • You might get more insight by writing a different byte in each location, i.e., a counter so that you can compare it with the location addresses. – Thomas Dickey Nov 14 '15 at 13:03
  • I don't think this answers the OP's question. – Haris Nov 14 '15 at 13:06
  • OP did not appear to know about stack canaries. Perhaps someone can do a better analysis. – Thomas Dickey Nov 14 '15 at 13:16
  • Yes, But the answer should justify why the buffer is getting overwritten. It might be because of the canaries, but I can't get my head around your explanation. – Haris Nov 14 '15 at 13:19
  • Hi, The local variables e, fd, i, n and c are all allocated adjacent to each other. Infact the base address of array s[] is exactly 4 bytes away from c...I have checked this by printing the address of s and (&s+1). – RootPhoenix Nov 14 '15 at 13:19
  • But what is located at `0xbffffdff` ? I do not see that answered in the discussion so far. It appears to be outside your variables, and in the realm where the system manages the stack. That's (as noted before) implementation-specific, so you can only get generic advice on how to investigate it. – Thomas Dickey Nov 14 '15 at 13:37
  • @ThomasDickey I missed an important step, sorry, Please see the edited code in the question. The c variable is getting modified by getchar and then put into s[] – RootPhoenix Nov 14 '15 at 13:52
  • Also I have added the GDB output before the buffer is started filing – RootPhoenix Nov 14 '15 at 13:56
  • Then the data seem to be account for: the data with "0xbXXXX" are addresses on the stack used by the runtime for managing the parameter lists. You might consider modifying your program so that you can see the stack *before* and *after* any of the variables are set using local variables, e.g., use `memset` for clearing the array, and assign zeros to everything. – Thomas Dickey Nov 14 '15 at 13:57
  • @ThomasDickey Also I think the `0xbffffdff` address contains `0x00000051`. this is the variable `i` which is incremented as `s[i++]` – RootPhoenix Nov 14 '15 at 14:06
  • I was not talking about that, but for example "0xbffffe08: 0xbffffe48". It would be easier to see patterns if the local variables were pre-set to zeros. – Thomas Dickey Nov 14 '15 at 14:10