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 use. As the linux manual points out its pretty vulnerable function. We will check if we can overflow the buffer in the exploitation part.
Although this program has suid bit set, it doesn’t call setuid function. Which means we will need to call it in the exploitation if we are going to build a priviledge escalation attack.
- NX is enabled
- Which means we can’t just directly overflow the buffer and drop to shellcode.
Cool, what can we do about it then ? We can do Ret2Libc attack of course.
As we are going to create a Ret2Libc attack, we need to find our binaries’ libc.so file.
This step is important because ‘.so’ files of binaries are like identity cards. If we don’t adjust our exploit code with them, it may not work.
After finding this, i will download it on my local in order to work on it.
Crashed the program with longer input than it supposed to take.
Analyzing the base pointer.
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 could just say that our buffer should be 128 + 8 = 136 byte long and I also showed it with RSP and stack state.
ROP Payload Logic
RBP = 128
RET = RSP + RBP + 8
JUNK BUFFER = 136 byte long
RET = JUNK BUFFER + 8
payload = (JUNK BUFFER) + (malicious return) + ….
Congratulations !! We succesfully built our ROP logic.
In the 64bit binary exploitation, the most simple logic to calculate the offset in order to call functions from libc(aka Ret2Libc) with giving global offset table + procedure linkage table and calling main after 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 put.
I will use “pop rdi; ret” gadget.
from pwn import *
voila! , we succesfully called the main one more time with overwriting the RET and leaked the puts!
This is the part i like most.
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 from outside, we need to expose it. In here you can use netcat and someother tools aswell but i will be using socat.
socat TCP4-LISTEN:7001,reuseaddr,fork EXEC:/usr/bin/vuln,stderr
This time we will take offsets from the
libc.so.6 that we downloaded. Because the binary mainly uses it, ours and its will be different.
In this step i will introduce you with another concept.
The best tool for finding one gadget RCE in libc.so.6
With this tool we won’t need to calculate otherstuff.
Thanks to Layle for teaching me this great trick.
one_gadget = p64(offset + 0x4f2c5)
Boom! but wait what?? , why are we not root?
As i mentioned before, although this binary has SUID bit set it doesn’t call setuid function.
We will do callback 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.
libc_setuid = 0xe5970
p64(0x0),0x00000000000, is pretty important. It is the argument of setuid(). We will set it to 0 as root is 0.
rop_chain = buf + 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.