Debugging a program that is opened by pwntools

krise picture krise · Apr 25, 2020 · Viewed 14.5k times · Source

I am trying to do a stackoverflow for a course at university. The binary I am to exploit has a canary, however, there is a way to leak that canary to stdout. The canary of course consists of some random bytes so I can't just read them from the string that the program outputs to stdout.

For this reason I am using the python and pwntools like p.recv(timeout = 0.01).encode("hex"). (I'm using pwntools only because I don't know another way to read the output in hex format, if there is an easier way I can of course use something else)

This works more or less works as expected, I manage to write the memory area that is past the canary. However, I get a segfault, so I obviously have some problem with the stackoverflow I am causing. I need a way of debugging this, like seeing the stack after I provide the input that causes the stackoverflow.

And now without any further ado the actual question: Can I debug a process that I started with pwntools (like process("./myprog")) in GDB or some other program that can show me the content of the stack?

I already tried getting the pid in python and using gdb attach to attach to that pid, but that didn't work.

Note: The binary I am trying to exploit has the guid set. Don't know if that matters tho.

Answer

deuteriumoxide picture deuteriumoxide · May 26, 2020

You can use the pwnlib.gdb to interface with gdb.

You can use the gdb.attach() function: From the docs:

bash = process('bash')

# Attach the debugger
gdb.attach(bash, '''
set follow-fork-mode child
break execve
continue
''')

# Interact with the process
bash.sendline('whoami')

or you can use gdb.debug():

# Create a new process, and stop it at 'main'
io = gdb.debug('bash', '''
# Wait until we hit the main executable's entry point
break _start
continue

# Now set breakpoint on shared library routines
break malloc
break free
continue
''')

# Send a command to Bash
io.sendline("echo hello")

# Interact with the process
io.interactive()

The pwntools template contains code to get you started with debugging with gdb. You can create the pwntools template by running pwn template ./binary_name > template.py. Then you have to add the GDB arg when you run template.py to debug: ./template.py GDB.

If you get [ERROR] Could not find a terminal binary to use., you might need to set context.terminal before you use gdb.

If you're using tmux, the following will automatically open up a gdb debugging session in a new horizontally split window:
context.terminal = ["tmux", "splitw", "-h"]

And to split the screen with the new gdb session window vertically:
context.terminal = ["tmux", "splitw", "-v"]

(Note: I never got this part working, so idk if it'll work. Tell me if you get the gdb thing working).
(To use tmux, install tmux on your machine, and then just type tmux to start it. Then type python template.py GDB.

If none of the above works, then you can always just start your script, use ps aux, find the PID, and then use gdb -p PID to attach to the running process.