Re: Library address randomization

On Jan 22, 2009, at 5:03 PM, Ricardo Rolim wrote:
Currently I'm using Fedora 10 and apparently I'm not getting any library address randomization for programs compiled as PIE. Whereas the binary itself, stack and heap are randomly getting their addresses changed from one execution to the next, the library stands still at a predictable location. Strangely enough I've got the expected result out of Ubuntu 8.10. This is how I'm checking:

[ricardo@localhost ~]$ ./dummy
printf: 0x17c900
main : 0xb7f8851c
[ricardo@localhost ~]$ ./dummy
printf: 0x17c900
main : 0xb7f5051c

Ricardo -

While the libc addresses are not being randomized (try 'ldd ./dummy' to see the actual library base addresses), on Fedora they are ASCII shielded (aka ASCII armor). You will notice that the first and last bytes of your printf() call are null bytes (0x00 17 c9 00). Fedora maps shared libraries into this region (the first 16MB of addressable memory, always beginning with 0x00) as a protective measure to prevent ret2libc type exploits and null pointer dereferencing. Although it's possible to write a null byte, especially if you arrange for the data you overflow a buffer with to end at the right length, in this case you will find it quite difficult to write both null bytes needed to address printf() in libc.

Google for 'fedora ascii shield' and you'll find a wealth of information on the subject. You will also find that such protection really isn't terribly protective. In this specific case, the printf() address has a null byte on both sides - so if you're writing a string, you won't be able to write two null bytes. But on x86 and other little endian machines, writing an address like 0x00badbad is still feasible via string operations... printf("\xad\xdb\xba\x00") will get you there, for example. And of course, any operations that work on raw byte values and not string operations, will still work just fine.