2

I am currently looking into security measures adapted by OSX and noticed something really weird. Though they claim to support ASLR for all binaries by default, it seems that all of the dylib are located at fixed address across runs.

Here is my script to test this, the output is also shown below

test.c

#include<stdio.h>

int main(){
    printf("main address : %p\n",&main);
    printf("printf address : %p\n",&printf);
    return 0;
}

output for five consecutive runs

main address : 0x10bbd5f00
printf address : 0x7fff9a053154

main address : 0x109c82f00
printf address : 0x7fff9a053154

main address : 0x1044a7f00
printf address : 0x7fff9a053154

main address : 0x103d7cf00
printf address : 0x7fff9a053154

main address : 0x10c90ef00
printf address : 0x7fff9a053154

The result clearly shows that while PIE is enabled, ASLR is certainly not.

To further check whether ASLR is specifically disabled for libsystem_c.dylib, I also ran the test code with DYLD_PRINT_SEGMENTS=1, and confirmed all dylib are located in fixed locations.

So my question is, is ASLR really available/supported on mac?
If yes, how should I enable it?
If no, what are possible reasons that apple fail/refuse to implement this feature?

Notes :
The code is ran on OSX El Captain(10.11.6) and Mojave(10.14.6)

James
  • 31
  • 7
  • I'm not sure printing the address of `printf()` is a good test as I believe that's provided by the kernel (looks like it given the high virtual memory address). I think you need to get the address of a loaded `dylib` for example (get a list of dylibs your exe uses with `otool -L exefile`). Some [sample code here](https://stackoverflow.com/questions/40785473/im-trying-to-get-the-base-address-of-loaded-dylibs-in-osx). – trojanfoe Sep 26 '19 at 13:27
  • I fail to see why printf would return a wrong virtual address of any function residing in memory space. But just to make this clear, attaching and checking the process at runtime with gdb/lldb also agrees that dylib stay at a fixed address across runs. – James Sep 26 '19 at 14:49

1 Answers1

1

After doing some more experiment and research, I realised that OSX implemented ASLR to behave quite differently from linux ASLR. The most fundamental difference is that in OSX, PIE and ASLR are tied together and decided during compile time.

Below is a summarised comparison between with/without PIE:

No PIE
Executable - fixed
Libraries - randomised per device boot
Heap - fixed
Mmap - fixed
Stack - fixed

PIE
Executable - 16bits randomised per execution
Libraries - randomised per device boot
Heap - 20bits randomised per execution
Mmap - 16bits randomised per execution(always come right after Activity Tracing region, fixed offset from Executable)
Stack - 16bits randomised per execution

Compared to Linux ASLR, where there are at least 20bits randomisation for each region, OSX ASLR is relatively weak, and may be brute-forced in an acceptable amount of time. Making it highly susceptible to ROP and other attacks.

James
  • 31
  • 7