220 likes | 526 Views
ASLR smack and laugh reference. What ASLR means. ASLR stands for address space layout randomization It’s a security technology to prevent exploitation of buffer overflows It’s implemented and enabled by default into important operating systems
E N D
What ASLR means • ASLR stands for address space layout randomization • It’s a security technology to prevent exploitation of buffer overflows • It’s implemented and enabled by default into important operating systems • It introduces randomness into the address space of a process
ASLR contd.. With ASLR the predictability of memory addresses is reduced by randomizing the address space layout for each instantiation of a program. So the job of ASLR is to prevent exploits by moving process entry points to random locations, because this decreases the probability that an individual exploit will succeed. Common exploits fail by crashing the process with a high probability instead of executing malicious code.
Testing ASLR 24 bits out of 32 are randomized Fig 1: Without ASLR Fig 2: With ASLR ASLR can be disabled at boot-time passing the norandmaps parameter Or at runtime via echo 0 >/proc/sys/kernel/randomize_va_space
Techniques to bypass ASLR • Stack juggling methods • Ret2ret • Ret2esp • Ret2eax • Ret2 pop • GOT hijacking • Overwriting DTORS
ret2ret • Relies on a pointer previously stored on the stack as a potential return address to the shellcode. • A potential return address is a base address of a pointer in the upper stack frame, above the saved return address • The gap between the location of the potential return address on the stack and the shellcode, padded with addresses that contain a RET instruction. • Each RET performs a POP action and increments ESP by 4 bytes, and afterward jumps to the next one. • The last RET will jump to the potential return address and will lead to the shellcode
Ret2ret contd… Vulnerable code Ret2ret procedure strcpy(buf,argv[1]); • Calculate the buffer start and end addresses ( the target range for exploitation) • Search for a potential return address in the upper stack frame by examining the EBP • If an address is found, subjecting it to byte-alignment conversion might produce an address that falls between the buffer start and end address. For example, if buf starts at 0xbffff6d0 and ends at 0xbffff6d8 and the address found by EBP examination is 0xbffff6f0 , then 0xbffff6f0 & 0xFFFFFF00 = 0xbffff600 is an address that falls within buffer start and end addresses. • We find a RET address from dump and fill up the locations all the way to that pointer with that RET address.
Ret2pop • resembles the previous method, except it's focused on a buffer overflow within a program function scope • When the buffer is used as the 2nd argument in the function, the combination of POP followed by a RET would skip the 1st argument jump directly to the 2nd argument • The pop command causes the stack to skip 4 bytes • The next instruction is ret which leads to the pointer to the shell code
ret2pop contd… vulnerable code ret2pop technique • Vulnerable code • This code contains a strcpy vulnerability in function and a perfect pointer to argv because an argv argument is directly passed to function. Note that Argv is the 2nd parameter • Find a pop-ret sequence • The address of the pop ret sequence is 0x08048467 which will be the last entry of ret2pop chain
ret2esp ret2esp procedure vulnerable code • The principle of this method is interpret hardcoded data as instruction • ret2esp takes advantage of the instruction sequence jmp *esp • The hardcoded value 58623 is ffe4 which is translated to ‘jmp *esp
ret2esp contd.. • From the dump of the assembler code we can find something like: 0x08048397 <main+19>: movl $0xe4ff,0xfffffff4(%ebp) If we analyze the memory location of 0x08048397 (gdb) x/7b 0x08048397 0x8048397 <main+19>: 0xc7 0x45 0xf4 0xff 0xe4 ... (gdb) x/1i 0x804839a 0x804839a <main+22>: jmp *%esp • We need to overwrite the instruction pointer with 0x804839a and have ESP point to the shellcode
ret2eax • The idea of this approach is to use the information that is stored in the accumulator, the EAX register • A function that returns a value, stores this value by using EAX • a function that returns a string, writes a pointer to this string into EAX right before the execution is continued by the calling function • The exploit requires overwriting of the return address with address of a call *eax instruction Fig : ret2eax
ret2eax contd… • Strcpy returns a pointer to buf, the pointer is written into EAX • Next step is to find the address of a call *esp: objdump –D ret2eax|grep –B 2 call|grepeax 8048493: call *%eax • The return address will be overwritten with 0x08048493
GOT hijacking • GOT stands for global offset table • PLT stands for procedure linkage table • These tables are involved when a library function is called. • PLT contains instructions(namely jmp instructions) and GOT contains pointers.
GOT & PLT • When a library function(e.g. printf) is called jump to its relevant entry of the PLT which points to an entry in GOT • Jump to the address that this entry of the GOT contains • If the function is called for the first time this address points to the next instruction in the PLT, which calls the dynamic linker to resolve the function’s address. If the function’s address has been found somehow it is written to the GOT and the function is executed. • Otherwise the GOT already contains the address that points to printf. The function is executed immediately. The part of the PLT that calls the dynamic linker is no longer used. • The execution of the function is finished. Go on with the execution of the calling function PLT Printf() call Dynamic linker libc GOT
Ret2got vulnerable code Approach • The GOT entry of a function “A” will be patched, so that it points to another function ”B”. Every time function A is called, function B will be executed with the parameters function A has been called with • The objective is to have the 2ndprintf function printf(“Array …”) be intrerprted as system(“Array …”). System will try to execute the Array script. An attacker could create a script called Array that contains /bin/sh for instance • The first printf simply triggers the dynamic linker to resolve its address
ret2got contd… code analysis exploitation technique • So 0x08048332 has to be written to the location 0x080496ac • 1ststrcpy accepts argv[1] . argv[1] can be used to overflow buffer array and overwrite ptr with the GOT reference of printf0x080496ac • 2ndstrcpy accepts argv[2]. Argv[2] will be 0x08048332
DTORS vulnerabilities #include <stdio.h> #include <stdlib.h> static void cleanup(void) __attribute__ ((destructor)); main() { printf("Some actions happen in the main() function..\n"); printf("and then when main() exits, the destructor is called..\n"); exit(0); } void cleanup(void) { printf("In the cleanup function now..\n"); } • In binary programs compiled with the GNU C compiler, special table sections called .dtors is made for destructors. The destructor functions are executed just before main exits with an exit system call • E.g. The cleanup function is defined with the dest Attribute • The .dtors table section of the binary is an array of 32 bit addresses terminated by a null address • The array always begins with 0xffffffff and ends with the NULL address of 0x00000000 • Between these two are the addresses of all the functions that have been declared with the destructor attribute
DTORS contd… If we examine with ‘nm’ command: 080495b4 d __DTOR_END__ 080495ac d __DTOR_LIST__ …… 080483e8 t cleanup • .dtors section starts at _DTOR_LIST_ and ends at _DTOR_END_ • 080495ac will contain 0xffffffff • 080495b4 will contain 0x00000000 • 080495b0 will contain e8830408, the address of cleanup function If we examine with ‘objdump -s -j .dtors ./dtors_sample’, we can see the actual contents of the .dtors section: 80495acffffffff e8830408 00000000 ............
DTORS contd… • .dtors section is included in all binaries compiled with the GNU C compiler, regardless of whether any functions were declared with the destructor attribute. • Since the .dtors section is writable, if the address after the 0xffffffff is overwritten with a memory address, the program's execution flow will be directed to that address when the program exits. • A code with a format string vulnerability e.g. printf(string)can be exploited to execute a shell script by overwriting the .dtors section