Buffer overflow that doesn't overflow

0

I am currently learning exploitation from the book Art of Exploitation. The first code in Exploitation part basically taught me a very basic overflow. This is the code from the book:

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
    int value = 5;
    char buffer_one[8], buffer_two[8];
    strcpy(buffer_one, "one"); /* Put "one" into buffer_one. */
    strcpy(buffer_two, "two"); /* Put "two" into buffer_two. */
    printf("[BEFORE] buffer_two is at %p and contains \'%s\'\n", buffer_two, buffer_two);
    printf("[BEFORE] buffer_one is at %p and contains \'%s\'\n", buffer_one, buffer_one);
    printf("[BEFORE] value is at %p and is %d (0x%08x)\n", &value, value, value);
    printf("\n[STRCPY] copying %d bytes into buffer_two\n\n", strlen(argv[1]));
    strcpy(buffer_two, argv[1]); /* Copy first argument into buffer_two. */
    printf("[AFTER] buffer_two is at %p and contains \'%s\'\n", buffer_two, buffer_two);
    printf("[AFTER] buffer_one is at %p and contains \'%s\'\n", buffer_one, buffer_one);
    printf("[AFTER] value is at %p and is %d (0x%08x)\n", &value, value, value);
}

After executing with argv[1] = 1234567890 I got

[BEFORE] buffer_two is at 0x7ffc97c28ac0 and contains 'two'
[BEFORE] buffer_one is at 0x7ffc97c28ad0 and contains 'one'
[BEFORE] value is at 0x7ffc97c28adc and is 5 (0x00000005)

[STRCPY] copying 9 bytes into buffer_two

[AFTER] buffer_two is at 0x7ffc97c28ac0 and contains '1234567890'
[AFTER] buffer_one is at 0x7ffc97c28ad0 and contains 'one'
[AFTER] value is at 0x7ffc97c28adc and is 5 (0x00000005)

[AFTER] buffer_one is supposed to contains "90" instead of "one". I noticed that my offset is 16 bytes instead of 8 bytes (0x7ffc97c28ac0 and 0x7ffc97c28ad0), that's why if doesn't overflow to buffer_one. Any idea what I should look into and is this a very serious issue?

c
buffer-overflow
asked on Stack Overflow Aug 12, 2017 by ledao • edited Aug 12, 2017 by ledao

2 Answers

1

[AFTER] buffer_one is supposed to contains "90" instead of "one".

No, no, a thousand times no. It is not supposed to hold any particular value. What you are doing is undefined behaviour, the result of which can be anything, including it working perfectly.

In fact, if you examine the two addresses, 0x7ffc97c28ac0 and 0x7ffc97c28ad0, you'll see that they're sixteen bytes apart, not eight (a). The implementation is perfectly allowed to do this since its only responsibility is to give you at least what you asked for. This means that you'll need a few more bytes in your strcpy to overflow the buffer.


(a) One possible reason for this is because it may be more efficient to align items on 16-byte boundaries for 64-bit architectures (the fact that your addresses are 48 bits rather than 32 seems to indicate this is true). Your book may well have been written with a 32-bit system in mind.

But I stress that's only a possible reason. Exploitation requires a very deep understanding of the environment you're working in.

answered on Stack Overflow Aug 12, 2017 by paxdiablo • edited Aug 12, 2017 by paxdiablo
0

It doesn't overflow because buffer_two is placed in a lower place in memory than buffer_one. Because of that, you have to copy argv[1] into buffer_one so it overflow buffer_two.

buffer_one 0x01 --> buffer_two 0x02 - Overflowing buffer_two won't change buffer_one.

strcpy(buffer_one, argv[1]); /* Copy first argument into buffer_one. */

Memories aren't static, what happens in the book is different than in other machines.

answered on Stack Overflow Jan 28, 2021 by Roi • edited Jan 28, 2021 by Roi

User contributions licensed under CC BY-SA 3.0