User Tools

Site Tools


session:10

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
session:10 [2020/07/12 23:18]
Silvia Pripoae [Tutorial: Chaining Information Leaks with GOT Overwrite]
session:10 [2020/07/19 12:49] (current)
Line 1: Line 1:
-= 0x09. Defense Mechanisms+====== 0x09. Defense Mechanisms ======
  
-== Resources+===== Resources =====
  
-[[http://security.cs.pub.ro/summer-school/res/slides/09-defense-mechanisms.pdf|Slides]]+[[http://security.cs.pub.ro/summer-school/res/slides/10-defense-mechanisms.pdf|Slides]]
  
-[[https://security.cs.pub.ro/summer-school/res/arc/09-defense-mechanisms-skel.zip|Activities archive]]+Get the tasks by cloning [[https://github.com/hexcellents/sss-exploit|Public GitHub Repository]].
  
-== Tutorials+ 
 +===== Tutorials =====
  
 The previous sessions ([[:session:07]] and [[:session:08]]) presented an exploitation scenario that is based on the assumption that machine instructions can be executed from **any** memory segment belonging to the process. As you can recall from [[session:03]], different sections of an ELF binary are grouped into segments which are loaded into memory when the binary is being executed. This mechanism (and some hardware support) enables 2 important protection mechanisms that will be presented in this session: executable space protection, and address space layout randomization.  The previous sessions ([[:session:07]] and [[:session:08]]) presented an exploitation scenario that is based on the assumption that machine instructions can be executed from **any** memory segment belonging to the process. As you can recall from [[session:03]], different sections of an ELF binary are grouped into segments which are loaded into memory when the binary is being executed. This mechanism (and some hardware support) enables 2 important protection mechanisms that will be presented in this session: executable space protection, and address space layout randomization. 
Line 24: Line 25:
 </note> </note>
  
-== Tools+===== Tools =====
  
 The **checksec** command-line tool is a wrapper over the functionality implemented in pwntools' ''pwnlib.elf.elf'' module. The **checksec** command-line tool is a wrapper over the functionality implemented in pwntools' ''pwnlib.elf.elf'' module.
Line 47: Line 48:
  
  
-=== Executable Space Protection+==== Executable Space Protection ====
  
 The **executable space protection** is an instance of the **principle of least privilege**, which is applied in many security sensitive domains. In this case, the executable space protection is used to limit the types of memory access that a process is allowed to make during execution. A memory region (i.e., page) can have the following protection levels: READ, WRITE, and EXECUTE. The executable space protection mandates that writable regions should not be executable at the same time. The **executable space protection** is an instance of the **principle of least privilege**, which is applied in many security sensitive domains. In this case, the executable space protection is used to limit the types of memory access that a process is allowed to make during execution. A memory region (i.e., page) can have the following protection levels: READ, WRITE, and EXECUTE. The executable space protection mandates that writable regions should not be executable at the same time.
Line 69: Line 70:
 There are of course other implementations in different hardening-oriented projects such as: OpenBSD [[http://marc.info/?l=openbsd-misc&m=105056000801065|W^X]], Red Hat [[http://www.redhat.com/magazine/009jul05/features/execshield/|Exec Shield]], PaX (which is now part of [[https://grsecurity.net/|grsecurity]]), Windows Data Execution Prevention ([[http://support.microsoft.com/kb/875352|DEP]]). There are of course other implementations in different hardening-oriented projects such as: OpenBSD [[http://marc.info/?l=openbsd-misc&m=105056000801065|W^X]], Red Hat [[http://www.redhat.com/magazine/009jul05/features/execshield/|Exec Shield]], PaX (which is now part of [[https://grsecurity.net/|grsecurity]]), Windows Data Execution Prevention ([[http://support.microsoft.com/kb/875352|DEP]]).
  
-==== Walk-through+=== Walk-through ===
  
 The Linux kernel provides support for managing memory protections in the ''%%mmap()%%'' and ''%%mprotect()%%'' syscalls. These syscalls are used by the loader to set protection levels for each segment it loads when running a binary. Of course, the same functions can also be used during execution. The Linux kernel provides support for managing memory protections in the ''%%mmap()%%'' and ''%%mprotect()%%'' syscalls. These syscalls are used by the loader to set protection levels for each segment it loads when running a binary. Of course, the same functions can also be used during execution.
Line 196: Line 197:
 </code> </code>
  
-==== Bypassing NX+=== Bypassing NX ===
  
 **ret-to-plt/libc.** You can return to the ''.plt'' section and call library function already linked. You can also call other library functions based on their known offsets. The latter approach assumes no ASLR (see next section), or the possibility of an information leak. **ret-to-plt/libc.** You can return to the ''.plt'' section and call library function already linked. You can also call other library functions based on their known offsets. The latter approach assumes no ASLR (see next section), or the possibility of an information leak.
Line 204: Line 205:
 **Return Oriented Programming (ROP).** This is a generalization of the ret-to-* approach that makes use of existing code to execute almost anything. As this is probably one of the most common types of attacks, it will be discussed in depth in a future section. **Return Oriented Programming (ROP).** This is a generalization of the ret-to-* approach that makes use of existing code to execute almost anything. As this is probably one of the most common types of attacks, it will be discussed in depth in a future section.
  
-=== Address Space Layout Randomization+==== Address Space Layout Randomization ====
  
 Address Space Layout Randomization (ASLR) is a security feature that maps different memory regions of an executable at random addresses. This prevents buffer overflow-based attacks that rely on known addresses such as the stack (for calling into shellcode), or dynamically linked libraries (for calling functions that were not already linked with the target binary). Usually, the sections that are randomly mapped are: the stack, the heap, the VDSO page, and the dynamic libraries. The code section can also be randomly mapped for [[http://en.wikipedia.org/wiki/Position-independent_executable|PIE]] binaries. Address Space Layout Randomization (ASLR) is a security feature that maps different memory regions of an executable at random addresses. This prevents buffer overflow-based attacks that rely on known addresses such as the stack (for calling into shellcode), or dynamically linked libraries (for calling functions that were not already linked with the target binary). Usually, the sections that are randomly mapped are: the stack, the heap, the VDSO page, and the dynamic libraries. The code section can also be randomly mapped for [[http://en.wikipedia.org/wiki/Position-independent_executable|PIE]] binaries.
Line 234: Line 235:
 </code> </code>
  
-=== Bypassing ASLR+==== Bypassing ASLR ====
  
 **Bruteforce.** If you are able to inject payloads multiple times without crashing the application, you can bruteforce the address you are interested in (e.g., a target in libc). Otherwise, you can just run the exploit multiple times. **Bruteforce.** If you are able to inject payloads multiple times without crashing the application, you can bruteforce the address you are interested in (e.g., a target in libc). Otherwise, you can just run the exploit multiple times.
Line 247: Line 248:
 **Restrict entropy.** There are various ways of reducing the entropy of the randomized address. For example, you can decrease the initial stack size by setting a huge amount of dummy environment variables. **Restrict entropy.** There are various ways of reducing the entropy of the randomized address. For example, you can decrease the initial stack size by setting a huge amount of dummy environment variables.
  
-**Partial overwrite.** This technique is useful when we are able to overwrite only the least significant byte(s) of an address (e.g. a GOT entry). We must take into account the offsets of the original and final addresses from the beginning of the mapping. If these offsets only differ in the last 12 bits, the exploit is deterministic, as the base of the mapping is aligned to 0x1000. For example, the offsets of ''read'' and ''write'' in ''libc6_2.27-3ubuntu1.2_i386'' are suitable for a partial overwrite:+**Partial overwrite.** This technique is useful when we are able to overwrite only the least significant byte(s) of an address (e.g. a GOT entry). We must take into account the offsets of the original and final addresses from the beginning of the mapping. If these offsets only differ in the last bits, the exploit is deterministic, as the base of the mapping is aligned to 0x1000. The offsets of ''read'' and ''write'' in ''libc6_2.27-3ubuntu1.2_i386'' are suitable for a partial overwrite:
 <code bash> <code bash>
 gdb-peda$ p read gdb-peda$ p read
Line 254: Line 255:
 $2 = {<text variable, no debug info>} 0xe6ea0 <__GI___libc_write> $2 = {<text variable, no debug info>} 0xe6ea0 <__GI___libc_write>
 </code> </code>
-Otherwisewe can still try to overwrite a larger part of the address in combination with bruteforce.+Howeversince bits 12-16 of the offsets differ, the corresponding bits in the full addresses would have to be bruteforced (probability 1/4).
  
 **Information leak.** The most effective way of bypassing ASLR is by using an information leak vulnerability that exposes randomized address, or at least parts of them. You can also dump parts of libraries (e.g., ''libc'') if you are able to create an exploit that reads them. This is useful in remote attacks to infer the version of the library, downloading it from the web, and thus knowing the right offsets for other functions (not originally linked with the binary). **Information leak.** The most effective way of bypassing ASLR is by using an information leak vulnerability that exposes randomized address, or at least parts of them. You can also dump parts of libraries (e.g., ''libc'') if you are able to create an exploit that reads them. This is useful in remote attacks to infer the version of the library, downloading it from the web, and thus knowing the right offsets for other functions (not originally linked with the binary).
  
-=== Tutorial: Chaining Information Leaks with GOT Overwrite+==== Tutorial: Chaining Information Leaks with GOT Overwrite ====
  
 In this tutorial we will exploit a program that is similar to ''02-challenge-no-ret-control'' from the previous session: In this tutorial we will exploit a program that is similar to ''02-challenge-no-ret-control'' from the previous session:
Line 366: Line 367:
 </code> </code>
  
-=== RELRO+==== RELRO ====
  
 **RELRO** (**Rel**ocation **R**ead-**O**nly) defends against attacks which overwrite data in relocation sections, such as the GOT-overwrite we showed earlier. **RELRO** (**Rel**ocation **R**ead-**O**nly) defends against attacks which overwrite data in relocation sections, such as the GOT-overwrite we showed earlier.
Line 377: Line 378:
 This is not a game-over in terms of exploitation, as other overwriteable code pointers often exist. These can be specific to the application we want to exploit or reside in shared libraries (for example: the GOT of shared libraries that are not compiled with RELRO). The return addresses on the stack are still viable targets. This is not a game-over in terms of exploitation, as other overwriteable code pointers often exist. These can be specific to the application we want to exploit or reside in shared libraries (for example: the GOT of shared libraries that are not compiled with RELRO). The return addresses on the stack are still viable targets.
  
-== seccomp+==== seccomp ====
  
 **seccomp** is a mechanism though which an application may transition into a state where the system calls it performs are restricted. The policy, which may act on a whitelist or blacklist model, is described using [[https://lwn.net/Articles/593476/|eBPF]]. **seccomp** is a mechanism though which an application may transition into a state where the system calls it performs are restricted. The policy, which may act on a whitelist or blacklist model, is described using [[https://lwn.net/Articles/593476/|eBPF]].
Line 413: Line 414:
 </note> </note>
  
-== Challenges+===== Challenges =====
  
-=== 01. Challenge ret-to-libc+==== 01-04. Challenges rwslotmachine[1-4] ====
  
-Looks good! Let's get serious and do something useful with this.+All of the challenges in this section are intended to be solved with **ASLR enabled**. However, you are free to disable it while developing your exploit for debugging purposes. You are provided with the needed shared libraries from the remote system.
  
-Continue working in the ''01-tutorial-ret-to-libc/'' folder in the [[https://security.cs.pub.ro/summer-school/res/arc/09-defense-mechanisms-skel.zip|activities archive]].+The challenges are based on the same //"application"//: the binaries expose very similar functionality with minimal implementation differencesYour job is to identify the defense mechanisms in use for each of them and bypass them in order to read a flag from the remote system.
  
-The final goal of this task is to bypass the NX stack protection and call ''system("/bin/sh")''We will start with a simple **ret-to-plt**:+They are numbered in the suggested solving order.
  
-  - Display all ''libc'' functions linked with the ''auth'' binary. 
-  - Return to ''puts()''. Use ''ltrace'' to show that the call is actually being made. 
-  - Find the offset of the ''“malloc failed”'' static string in the binary. 
-  - Make the binary print ''"failed"'' the second time ''puts'' is called. 
-  - **(bonus)** The process should ''SEGFAULT'' after printing ''"Enter password:"'' again. Make it exit cleanly (the exit code does not matter, just no ''SIGSEGV''). You can move on to the next task without solving this problem. 
-  - Remember how we had ASLR disabled? The other ''libc'' functions are in the memory, you just need to find their addresses. Find the offset of ''system()'' in ''libc''. Find the offset of the ''"/bin/sh"'' string in ''libc''. 
-  - Where is ''libc'' linked in the ''auth'' binary? Compute the final addresses and call ''system("/bin/sh")'' just like you did with ''puts''. 
 <note important> <note important>
-//Hint//: Use ''LD_TRACE_LOADED_OBJECTS=1 ./auth'' instead of ''ldd''. The latter is not always reliable because the order in which it loads the libraries might be different than when you actually run the binary.+In the case of ''rwslotmachine4'', you will need the shared library ''libint.so''
 </note> </note>
  
 <note important> <note important>
-//Hint//: When you will finally attack this''stdin'' will get closed and the new shell will have nothing to read. Use cat to concatenate your attack string with ''stdin'' like this: ''cat <(python -c 'print "L33T_ATTACK"') - | ./vulnbinary''+To set LD_LIBRARY_PATH from a pwntools scriptuse this method: 
-</note+<code python> 
- +process('./rwslotmachineX', env={'LD_LIBRARY_PATH' : '.'})
-=== 02. Challenge - no-ret-control +
- +
-Go to the ''02-challenge-no-ret-control/'' folder in the [[https://security.cs.pub.ro/summer-school/res/arc/09-defense-mechanisms-skel.zip|activities archive]]. +
- +
-Imagine this scenario: we have an executable where we can change at least 4B of random memory, but ASLR is turned on. We cannot reliably change the value of the return address because of this. Sometimes ret is not even called at the end of a function. +
- +
-Alter the execution of ''force_exit'', in order to call the secret function. +
- +
-=== 03. Challenge - ret-to-plt +
- +
-Go to the ''03-challenge-ret-to-plt/'' folder in the [[https://security.cs.pub.ro/summer-school/res/arc/09-defense-mechanisms-skel.zip|activities archive]]. +
- +
-''random'' is a small application that generates a random number. +
- +
-Your task is to build an exploit that makes the application always print the **same second random number**. That is the first printed random number is whatever, but the second printed random number will always be the same, for all runs. In the sample output below the second printed random number is always ''1023098942'' for all runs. +
- +
-<code text> +
-hari@solyaris-home:~$ python -c 'print <payload here>' | ./random +
-Hi! Options: +
- 1. Get random number +
- 2. Go outside +
-Here's a random number: 2070249950. Have fun with it! +
-Hi! Options: +
- 1. Get random number +
- 2. Go outside +
-Here's a random number: 1023098942. Have fun with it! +
-Segmentation fault (core dumped) +
-hari@solyaris-home:~$ python -c 'print <payload here>' | ./random +
-Hi! Options: +
- 1. Get random number +
- 2. Go outside +
-Here's a random number: 1152946153. Have fun with it! +
-Hi! Options: +
- 1. Get random number +
- 2. Go outside +
-Here's a random number: 1023098942. Have fun with it! +
 </code> </code>
-   
-You can use this Python skeleton for buffer overflow input: 
- 
-<file python skel.py> 
-#!/usr/bin/python 
-import struct, sys 
- 
-def dw(i): 
- return struct.pack("<I", i) 
- 
-#TODO update count for your prog 
-pad_count_to_ret = 100 
-payload = "X" * pad_count_to_ret 
- 
-#TODO figure out where to return 
-ret_addr = 0xdeadbeef 
-payload += dw(ret_addr) 
- 
- 
-#TODO add stuff after the payload if you need to 
-payload += "" 
- 
-sys.stdout.write(payload) 
-</file> 
- 
-**Bonus**: The process should SEGFAULT after printing the second (constant) number. Make it exit cleanly (the exit code does not matter, just no SIGSEGV). 
- 
-=== 04. Challenge - colors 
- 
-Go to the ''04-challenge-colors/'' folder in the [[https://security.cs.pub.ro/summer-school/res/arc/09-defense-mechanisms-skel.zip|activities archive]]. 
- 
-<note important> 
-//Hint//: If you are going to use an inline python command, stdin will get closed and the new shell will have nothing to read. Use cat to concatenate your attack string with stdin like this: ''%%cat <(python -c 'print "L33T_ATTACK"') - | ./vulnbinary%%'' 
 </note> </note>
  
-===== 04.a. +<note tip> 
- +//Hint//: Do not waste time on reverse engineering ''rwslotmachine3''! It is very similar to ''rwslotmachine2'', but operates on the client/server model.
-Exploit the ''colors'' binary and call ''system()''. Disregard the string parameter of ''system()'' for now. +
- +
-===== 04.b. +
- +
-ASLR still disabled. Call ''%%system("blue")%%''. Get a shell with this. //Hint//: Where will it search for the "blue" command? +
- +
-===== 04.c. +
- +
-Again, ASLR disabled. Call ''%%system("/bin/sh")%%'' without using the previous trick. +
- +
- +
-=== 05. Challenge - bruteforce +
- +
-Continue working in the ''04-challenge-colors/'' folder in the [[https://security.cs.pub.ro/summer-school/res/arc/09-defense-mechanisms-skel.zip|activities archive]]. +
- +
-Try the previous exploit with ASLR enabled. You can rerun the binary multiple times. +
- +
-<note important> +
-Figure out how addresses look like using ''LD_TRACE_LOADED_OBJECTS=whatever ./colors'' multiple times. How many bits do change? Run the program multiple times with some fixed addresses for ''system'' and ''/bin/bash'' in the payload+
 </note> </note>
  
-<note> 
-The ASLR entropy on 32-bit systems if pretty low, which makes this bruteforce attack feasible. On 64-bit platforms you will need an information leak, and a 2-stage exploit. We are going to discuss this in a future session. 
-</note> 
  
-=== 06Challenge mprotect+==== 05Bonus rwslotmachine5 ====
  
-Go to either the ''03-challenge-ret-to-plt/'' or ''04-challenge-colors/'' folder in the [[https://security.cs.pub.ro/summer-school/res/arc/09-defense-mechanisms-skel.zip|activities archive]].+This challenge is similar to ''rwslotmachine1''. However, your exploit for the first challenge will (most likely) not workInvestigate why and develop a bypass.
  
-Using any of the 2 binaries, try to call ''mprotect()'' in order to change the protection flags of the stack, then inject a shellcode similar to the ones in the [[session:10|previous session]]. +<note tip
- +You can find a table describing x86 syscalls [[http://security.cs.pub.ro/hexcellents/wiki/kb/exploiting/linux_abi_x32|here]].
-<note important+
-To make your life easier, you can disable ASLRThe purpose of this task is to bypass NX, and not ASLR. +
-</note> +
- +
-<note important> +
-//Hint//: The ''ulimit -s'' unlimited trick will make the stack get mapped at a fixed address.+
 </note> </note>
session/10.1594585106.txt.gz · Last modified: 2020/07/12 23:18 by Silvia Pripoae