I am trying to understand ASLR and how it is implemented. I understand it does not actually "prevent" buffer overflow etc from happening, it will only make it more difficult. But i am not able to figure out how it prevent a return to libc attack. For example, lets say i have a program which has a buffer overflow. I give as input a np-op sled followed by shell code. The shell code overwrites the return address in the stack frame. So when the function returns it will execute the shell code. Similar if i write the address of a libc function that function will get invoked. now with ASLR, on every program run the program will start at some random address right ? but the libc functions are still at the same address and if I'm correct that won't change till i reboot a machine. So, if i basically try to brute force a vulnerable program with all possible addresses, can i still get a return to libc ? also, does aslr prevent ( and how ?) from ROP attacks ? if not what are the defenses ?
brute force a vulnerable program with all possible addresses
Trying to brute-force the address space (there are 2^64 possible addresses in a modern 64-bit system) is supposed to be impossible in practice due to constraints on time (and resources). Also see: What is the largest performed/possible bruteforce attack to date?
On a more practical note, if you guess the address wrong there is a big chance of the program crashing due to for instance a segmentation fault. Since brute-forcing a 64 bit address can take long, these crashes can be detected.
Therefore, finding the addresses of the shellcode on the stack, the library functions (in the case of return-to-libc) or the gadgets (in the case of ROP) is too hard for the attacker.
Of course, there are other ways to bypass ASLR. Look into Pointer Leaks and memory layout attacks such as heapspray if you are interested.