# An In-Depth Survey of Bypassing Buffer Overflow Mitigation Techniques
## 4 OS-Based Mitigation Techniques
### Protecting the ELF Binaries
#### 4.3.3 Step by Step Procedure of Bypassing PIE and RELRO Mitigations  
The Figure 22 shows the flow of strategy that we have used to bypass PIE and RELRO.  
**Phase 1:** The Figure 23 shows the vulnerable program, having format string (printf) and buffer overflow (getMessage) vulnerability. We need an information leak from binary and to achieve that goal, we will take advantage of format string vulnerability.  
First of all, the vulnerable program is compiled by enabling PIE, and RELRO as shown in the Figure 24. ASLR is also enabled. We can verify the enabled mitigation using checkssee utility. The next step is to leak information by exploiting the format string vulnerability. We can achieve this by loading the program in gdb, and pass a lot of format specifiers as input, which will leak several memory addresses as shown in the Figure 24. Then look at the memory map of program using vmmap command, and confirm those addresses with the leaked addresses. When we look closely at the leaked addresses, we noticed that the 33 rd address is from the executable portion of the vulnerable binary (0x0000555555555000  
Figure 22: Bypassing PIE and RELRO.  
to 0x00000555555556000). We can also verify this by inputting the %338 lx in the program, as shown in the Figure 24. Thus, in our case the leaked address is 0x0000555555555060 and the executable base address is 0x000055555555555000, so after subtracting them the result is 0x60. Now if we subtract this 0x60 from the leaked address (0x0000555555555550a0), we will get a randomized executable base address which can be used to find other functions addresses.  
The first part of exploit is shown in Figure 25, that contains all the steps we have performed above to leak information using format string vulnerability.  
**Phase 2:** The second part of exploit is shown in Figure 26. To accomplish this part, we need to calculate the addresses of _start, pop rdi gadget and pop rsi gadget after randomization. For this purpose, we need to first find the offset of each function and gadget from the executable base address which we have found in the first phase. For example, to calculate the offset of a pop rdi gadget, first we will find its address in the binary using asmsearch utility and then subtract that address with the executable base address. We will do the same with each address, and we will find the offsets of all the functions and gadgets. After finding all the offsets, we will add that offset with the executable base address as  
Figure 24: Leaking Information Using Format String Vulnerability.  
Figure 25: Python Script Part 1.  
highlighted in the figure, and that will give us the actual addresses of functions and gadgets. After executing the exploit, we'll leak the address of printf.  
**Phase 3:** The final step is to get the actual address of system and /bin/sh after randomization. We can accomplish this by utilizing the printf offset leaked previously in phase 2. We can find the offset of printf in libc using readelf command as shown in the Figure 27, and then subtract it with the leaked printf address to know the actual randomization of addresses as highlighted in the Figure 27, which shows the final part of exploit. We can also find the offset of the system and /bin/sh as done in Section 4.2 (Step by Step Procedure of Bypassing ASLR Mitigation), and will add the calculated change with these system and /bin/sh offsets as highlighted in Figure 27 to get addresses after randomization. Script execution will spawn shell.