Challenge
We are given a binary to exploit. By running checksec
on it, we see that the binary has the following protections: [show-line-numbers]: false
Canary : No
NX : Yes
PIE : Yes
Fortify : No
RelRO : Partial
Because the binary has NX, we cannot place executable shell code in a buffer and then jump to it. PIE allows the code section of the binary to be located anywhere in memory. This means that we don't know the address of functions within the binary; however, we still know relative offsets.
Reverse Engineering
Dump of assembler code for function main:
0x0000000000001145 <+0>: push rbp # Setup Stack
0x0000000000001146 <+1>: mov rbp,rsp
0x0000000000001149 <+4>: sub rsp,0x110 # Allocate 0x110 bytes on stack
0x0000000000001150 <+11>: mov DWORD PTR [rbp-0x104],edi # Copies edi into stack offset 0x104
0x0000000000001156 <+17>: mov QWORD PTR [rbp-0x110],rsi # Copies rsi into stack offset 0x110
0x000000000000115d <+24>: mov rax,QWORD PTR [rbp-0x110] # Copies value of pointer into rax
0x0000000000001164 <+31>: add rax,0x8 # Adds size_t
0x0000000000001168 <+35>: mov rdx,QWORD PTR [rax] # Copies the value of the pointer [rax + 8] into rdx
0x000000000000116b <+38>: lea rax,[rbp-0x100] # Loads the address of [rbp - 0x100] into rax
0x0000000000001172 <+45>: mov rsi,rdx # rsi = rdx
0x0000000000001175 <+48>: mov rdi,rax # rdi = rax
0x0000000000001178 <+51>: call 0x1030 <strcpy@plt> # Calls strcpy(rsi, rdi) ; strcpy ([rbp - 0x100], argv[1])
0x000000000000117d <+56>: lea rax,[rbp-0x100] # Loads address of [rbp-0x100] into rax
0x0000000000001184 <+63>: mov rdi,rax # rdi = rax
0x0000000000001187 <+66>: call 0x1040 <puts@plt> # puts(rdi)
0x000000000000118c <+71>: mov eax,0x0 # return 0
0x0000000000001191 <+76>: leave
0x0000000000001192 <+77>: ret
End of assembler dump.