* It is a 64 bit dynamically linked binary, nx and aslr is enabled *
There are many things to be done in binary analyzation but I will just mainly focus on Ret2Libc attack.
You can use many other tools but I will use those mainly.
- pwntools (python library)
- A reverse engineering tool (gHidra , IDA etc.)
- First thing first,
- We need to analyze our binary in order to determine what kind of attack vector we need to use
The program uses gets() to check password from user. As linux manual shows its a pretty vulnerable function. If we can control this and overflow it, that would be perfect
Although this program has suid bit set, it doesn’t call setuid function. Which means we will need to call it manually, if we are planning to perform a privilege escalation attack
We can’t just directly overflow the buffer and drop to a shellcode.
Cool, what can we do about it then ? We can do Ret2Libc ofc
We first need to find our binaries’ libc.so file because we will be jumping to it
Matching libc files with remote is important because our exploit might not work remote as libcs can be different
After finding this, I will work on it locally
Crashed the program with longer input than it supposed to take (overflowed the buffer)
Analyzing the base pointer ( * the arrow for stack is in wrong direction, * )
As you can see, peda told us that RBP was in the offset 128. As i explained in my previous post,
RET comes after RBP. Therefore, we can just say that our buffer should be 128 + 8 = 136 byte long and I also showed it with RSP and stack state.
We need to leak some functions from the binary in order to find where libc is located at
By simply giving got of puts as argument to puts we can leak it
rop_chain = buf + pop_rdi + got_put + plt_put + plt_main
Now if we recieve the next main call we will recieve the leaked offset of the function puts.
Offsets can be found manually, but I will use pwn tools for it when developing the exploit
We need to use “pop rdi; ret” in order to execute next instruction
from pwn import *
We succesfully called the main one more time with overwriting the RET, leaked the puts and calculated libc address!
As I said before you can find those offsets manually but I will use pwn tools for it
Second stage will be like this.
rop_chain = buf + pop_rdi + sh + sys
from pwn import *
Boom, we dropped to a shell locally.
In order to access the binary externally, we need to expose it. You can use netcat and some other tools as well but I will be using socat.
socat TCP4-LISTEN:7001,reuseaddr,fork EXEC:/usr/bin/vuln,stderr
We will need to change offsets now as remote is different, you can simply modify libc in the script
I won’t use classic system + /bin/sh now, I will switch to one_gadget
It basically finds you a gadget that gives you a shell in libc
Thanks to Layle for teaching me this great trick.
one_gadget = p64(libc.address + 0x4f2c5)
Boom! but wait what??, why aren’t we root?
As I mentioned before, although this binary has SUID bit set it doesn’t call setuid function
We will return to main one more time. I don’t know why it is exactly happening but you can’t just directly call setuid in one chain. You need to do one more chain.
payload = JUNK
p64(0x0),0x00000000000, is pretty important. It is the argument of setuid(). We will set it to 0 as root is 0.
rop_chain = JUNK + one_gadget
We succesfully created our exploit, enjoy your root shell !!
from pwn import *
Thank you for making out here. If you have any questions, please let me know.