3

I have this structure:

struct Books {
 char  title[50];
 char  author[50];
};

Let's say that I know that if I pass arg1 to the program, in some part of the code, it adds some chars in the direction $title+52, so the author value is overwritten (buffer overflow).

Now I add ASLR to my binary. By this way, some directions are random, so I think the buffer overflow that I described before could not be possible.

Is this true? Or even if I add ASLR the directions of struct members are together and buffer overflow could be possible?

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
Miguel.G
  • 377
  • 1
  • 6
  • 20
  • ASLR randomizes the starting position of contiguous blocks of virtual memory. Your variable is still going to be inside one of those blocks. Buffer overflow problems are not going to magically go away with ASLR. – Marco Bonelli Oct 17 '18 at 15:43
  • You may find this post helpful: https://stackoverflow.com/questions/3605222/what-is-address-space-layout-randomization – Jeff Learman Oct 17 '18 at 16:03
  • Note that there's a difference between "buffer overflow" as a problem, and "buffer overflow attacks." ALSR does not address the problem of buffer overflows as bugs. It just makes it harder to effectively use such a bug in an attack. More specifically, it makes it harder to use such a bug to do things like steal information or gain access. It doesn't make it much harder for an attack to crash the program. – Jeff Learman Oct 17 '18 at 18:03
  • Hi! Thanks both, I will check it:) – Miguel.G Oct 18 '18 at 13:57

3 Answers3

5

The specific overflow you mentioned is still possible.

With the exception of bitfields, the fields of a structure follow one another in order in memory (with some possible padding in between). This is detailed in section 6.7.2.1p15 of the C standard:

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

So in this case the author field will always follow the title field, regardless of what specific address an object of type struct Books is located at. The only possible difference could be the amount of padding, but unless you add or remove fields in the struct this probably won't change.

dbush
  • 205,898
  • 23
  • 218
  • 273
2

ASLR does not affect stuff that is compile-time. The compiler chooses the layout of the structure at the time of compilation and this is hardcoded in the resulting object code.

Furthermore, the C standard requires that successive struct members are laid out in memory in the order they appear in the struct definition (with unspecified padding in between members, but this too is fixed at the compilation time)

2

I think you are misunderstanding the effects of ASLR (Address Space Layout Randomization): ASLR randomly arranges the positions of different virtual memory areas of a process (executable, stack, heap, data, libraries, etc) to be different in every execution. It does not change the relative position of elements in the same virtual memory area.


Take for example the following simple program:

int main(void) {
    struct {
        char a[10];
        char b[10];
    } myvar;

    printf("a: %p\n", &myvar.a);
    printf("b: %p\n", &myvar.b);

    return 0;
}

Here's the program's virtual memory with ASLR disabled:

0x555555554000     0x555555555000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x555555754000     0x555555755000 r--p     1000 0      /home/marco/test/test [read only data]
0x555555755000     0x555555756000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffffffde000     0x7ffffffff000 rw-p    21000 0      [stack] <-- myvar is here

Output (ASLR disabled):

$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a

And here's the same program with ASLR enabled:

0x559fefcbe000     0x559fefcbf000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x559fefebe000     0x559fefebf000 r--p     1000 0      /home/marco/test/test [read only data]
0x559fefebf000     0x559fefec0000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffe3bb5e000     0x7ffe3bb7f000 rw-p    21000 0      [stack] <-- myvar is here

Output (ASLR enabled):

$ ./test
a: 0x7ffe3bb5e080
b: 0x7ffe3bb5e08a
$ ./test 
a: 0x7ff4abdeea80
b: 0x7ff4abdeea8a
$ ./test 
a: 0x7efa6b8fa080
b: 0x7efa6b8fa08a

Your variable is still going to be inside a certain contiguous block of virtual memory, and the relative position of the fields will not change at all. Contiguous arrays will still be contiguous using ASLR: they will just start at a different position in memory.

Since struct fields are by standard contiguous in memory (and follow their declaration order), this means that buffer overflow will still be a potential problem, even when using ASLR.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128