💧上次介绍了堆里面的off_by_one,那么这个off_by_null和它有神马区别呢,哎,别看名字挺像,它俩无论是在栈里面还是堆里面都有很大区别的。

📌off_by_one,这个我们知道可以通过溢出控制到下一个字节,体现在堆里面就是,可以控制到下一个chunk的size位,我们知道根据堆的排布,当申请0x18,0x28,0x38,等这样末尾是8时(32位的是4),那么下一个chunk的prev_size就是我们的输入数据的空间,那么off_by_one就可以修改下一个chunk的size位实现一些堆漏洞的利用,比如堆块重叠(overlap-chunk),unlink等操作,还有一些针对于fastbin相关的操作。

📐然而off_by_null,是把溢出的下一个字节改成null,那么一般是伪造空闲的堆块实现overlap-chunk,来进行后续的操作的。

📏下面看一道题目来具体体会一下。

题目连接:攻防世界里面的babyheap

也可以通过网盘下载:题目连接

保护情况

常回家看看之off_by_null(堆篇)-LMLPHP

64位ida载入看看

main函数,一些功能函数,有选项

常回家看看之off_by_null(堆篇)-LMLPHP

create函数

常回家看看之off_by_null(堆篇)-LMLPHP

有申请堆块的限制,大小没有限制,在看看read_input函数,是存在漏洞的

常回家看看之off_by_null(堆篇)-LMLPHP

delete函数,正常free堆块,没有uaf漏洞

常回家看看之off_by_null(堆篇)-LMLPHP

show函数,通过索引逐个打印堆块内容

常回家看看之off_by_null(堆篇)-LMLPHP

分析:就一个off_by_null漏洞可以用,题目没有edit编辑功能,只能不停的add,free。

思路:通过off_by_null,伪造堆块,再次free这个堆块的时候会进行合并,将上面的堆块也视为free,比如申请两个0x100堆块,两个0x68堆块,那么再次申请一个0x100的堆块时候,通过off_by_null将这个堆块的size位变成0x300 ,因为前面0x100的堆块的size位是0x111,0x68的size位是0x71去掉size的标志位加起来刚刚好是0x300,那么在free最后一个0x100的堆块的时候会进行合并,此时第一个堆块久变成大堆块的首地址了,这个时候再次进行申请会从大堆块分割,此时就可以泄露出libc地址,同样申请大堆块,修改0x68小堆块的fd位,进行fastbin attack ,修改__malloc_hook,___realloc_hook进而获取shell。

EXP:

常回家看看之off_by_null(堆篇)-LMLPHP

常回家看看之off_by_null(堆篇)-LMLPHP

07-06 16:02