Event | Challenge | Category | Points | Solves |
---|---|---|---|---|
inshack-2019 | gimme-your-shell | pwn | 50 | 67 |
TL;DR
This is a remote buffer overflow challenge, there is no protection on the binary but ASLR is enable on the remote server. I redirected the execution flow to write my shellcode to a controled area, then jump to it and execute it.
Getting informations
First I looked at the protections on the binary :
No protections is enabled but it’s a remote challenge and we can assume that the ASLR is enabled on the remote server. Let keep that in mind and try to run the binary.
The program crash when the input is to big. The binary is not stripped which means that we can find symbol inside the binary by opening it with ghidra we can easily spot the vuln function which use a vulnerable function to get input from the user. Here gets will read the user input from STDIN and the result will be stored in local_18 but there is no check on the size of the user input, we have our buffer overflow.
Road to the exploit
Since ASLR is randomizing the stack addresses we can’t find the address of our payload and jump to it. We could try to leak an address of libc and perform a ret2libc but I didn’t use this technique because it’s an 64 bits binary and there is no easy way to control the register rdi which is used to pass the first arguments. So without a gadget to properly set rdi we can’t make a call to puts with the address of gets as parameter to leak it’s address. But remember the NX bit is not set, here is a definition from wikipedia :
An operating system with support for the NX bit may mark certain areas of memory as non-executable. The processor will then refuse to execute any code residing in these areas of memory. The general technique, known as executable space protection, is used to prevent certain types of malicious software from taking over computers by inserting their code into another program's data storage area and running their own code from within this section; one class of such attacks is known as the buffer overflow attack.
So if it’s disable we can write data and then execute what we write if it’s a valid set of instructions. Now there are 2 problems to solve, where to write the shellcode and how to jump there.
We can see from the code in ghidra that the parameter of the gets function depend of rbp
1 |
|
By chance there is a gadget which allow us to set a crafted value in rbp :
1 |
|
You can use the readelf command to list sections of the binary and their differents rights, we can see that the .bss section has write (W) right, it’s a perfect candidate to host our shellcode.
1
2
3
4
5
readelf -S weak
[...]
[25] .bss NOBITS 0000000000600a18 00000a18
0000000000000010 0000000000000000 WA 0 0 8
[...]
We also have to see where the program crash, I use gdb with the peda extention which allow me to create patterns and search for them :
1 |
|
Perfect we can control rip which is the instuction pointer at offset 24.
Building the exploit
So here is the plan :
- overflow the program until rip
- use the previous gadget to set rbp with a controlled value in bss
- ret to the code in vuln to make a second call to get
- send our shellcode which will be in bss
- jump to our controlled area in bss
1 |
|
1 |
|