3

ASLR randomizes the addresses of the process executable code, stack, heap and libraries. This is to make the life of an attacker difficult as they cannot hardcode addresses in the code across multiple instantiations.

But how does this help with system libraries? They are never unloaded. Every process uses libc, for example, and so the address of prinf never changes. How is this helping if I am hardcoding the address of printf? This does not change unless the machine reboots.

I do have ASLR enabled --

# cat /proc/sys/kernel/randomize_va_space 2 

Here is some sample code --

unsigned long getEBP ( void ) { asm("movl %ebp, %eax"); } int main(void) { int (*p)(const char*, ...) = &printf; printf("printf address = %p \n", p); (*p)("printf address = %p\n", &printf); printf ("EBP:%x\n" ,getEBP ()); } 

And the output across multiple runs --

# ./a.out printf address = 0x4003c0 printf address = 0x4003c0 EBP:6a71d300 # ./a.out printf address = 0x4003c0 printf address = 0x4003c0 EBP:93e5c100 

See the EBP is changing as it should but not the address of printf.

What am I missing?

EDIT: Compiling with -fPIC did not help on my RHEL VM.

# ./a.out printf address = 0x3047a4f0f0 printf address = 0x3047a4f0f0 EBP:7aaac900 # ./a.out printf address = 0x3047a4f0f0 printf address = 0x3047a4f0f0 EBP:632eca20 

If the libc calls are in fact randomized as the reply says below, how is it implemented? libc itself is not reloaded, so the actual address of printf is not changing, how can it be randomized?

2 Answers 2

2

Update:

see https://stackoverflow.com/questions/24984955/why-arent-glibcs-function-addresses-randomized-when-aslr-is-enabled

Compile the binary using -fPIE or -fPIC -pie -fPIE:

https://stackoverflow.com/questions/2463150/fpie-position-independent-executable-option-gcc-ld

Binary compiled with default flags:

user01@user01 ~/test $ ./test_ASLR printf address = 0x400420 printf address = 0x400420 EBP:9af703c0 user01@user01 ~/test $ ./test_ASLR printf address = 0x400420 printf address = 0x400420 EBP:8411e900 user01@user01 ~/test $ ./test_ASLR printf address = 0x400420 printf address = 0x400420 EBP:28f8e50 

Binary compiled with -pie -fPIE flags:

user01@user01 ~/test $ ./test_ASLR printf address = 0x7f8227963340 printf address = 0x7f8227963340 EBP:19e01ad0 user01@user01 ~/test $ ./test_ASLR printf address = 0x7fecb2baa340 printf address = 0x7fecb2baa340 EBP:9c8148e0 user01@user01 ~/test $ ./test_ASLR printf address = 0x7f5d00edb340 printf address = 0x7f5d00edb340 EBP:32b3c6d0 
7
  • That did not work on my VM. I get the same value every time. Also, why would the EBP change in case the -fPIC is not used? Commented Jan 2, 2018 at 20:32
  • Compile with -fPIE Commented Jan 2, 2018 at 20:35
  • No difference. I see the same value as the one compiled with -fPIC Commented Jan 2, 2018 at 20:37
  • If the libc calls are in fact randomized, how is it implemented? libc itself is not reloaded, so the actual address of printf is not changing, how can it be randomized? Commented Jan 2, 2018 at 20:38
  • 1
    @stflow: each process has its own memory mapping. This means different processes can have the same memory page mapped at different addresses. In other words: the library can still be shared between the processes but each process knows the memory pages of the library at different addresses. Commented Jan 2, 2018 at 21:26
0

When you compile with default flags, most of the time .text segment stays at a constant addresses and GOT is filled up with a list of pointers for functions used in the program which are resolved as they are encountered. Now since in this case GOT was at a constant place it is directly put in call by the compiler. An example :

0x8048446 <main+35> call printf@plt <0x80482f0> 

This does not mean that actual location of printf was not randomized. If this was the first call to printf in the program _dl_runtime_resolve will fill in the appropriate values. Otherwise it should look something like this

pwndbg> x/xi 0x80482f0 0x80482f0 <printf@plt>: jmp DWORD PTR ds:0x804a00c pwndbg> telescope 0x804a00c 00:0000│ 0x804a00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0xf7e38670 (printf) ◂— call 0xf7f0eb09 

This is the actual location of printf in libc. In normal cases &printf points actually to the printf@plt which is just a jumptable for actual printf in libc.

Now for -pie -fPIE the &printf points to the actual printf in libc. This flag only adds ASLR to the sections that were constant earlier. Libraries were loaded at random offsets in both the cases.

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.