很好的参考资料:
pwn题堆利用的一些姿势 – malloc_hook
一、malloc hook
使用malloc hook主要是应对保护全开的时候,因为got表无法劫持,所以使用malloc hoook + onegadget来实现
(一)初级利用
malloc_hook是在malloc函数调用前会执行的钩子函数。 在程序中,通常malloc_hook的函数地址对应值为0,也就是不会执行任何东西,我们在利用过程中将其覆盖为onegadget地址,这样再执行一次malloc就会执行onegadget。
关于malloc_hook的地址有两种获取方法,第一种是泄露main_arnea后相差0x10,第二种是通过基址和ELF函数获取
- malloc_hook = main_arnea - 0x10
- malloc_hook = libc基址 + libc.sym["__malloc_hook"]
但从本质上讲,如果程序本身有shellcode,malloc hook的利用就和got表劫持一样简单
(二)程序中有/bin/sh字符串的利用方法
可以将malloc_hook修改为system函数地址,假设/bin/sh在0x400000位置,那么就将申请堆块大小写成0x400000输入,就会执行system("/bin/sh\x00")
(三)更常见的情景,利用realloc函数调整栈结构
首先我们需要知道,为什么需要调整栈位置,那是因为,onegadget的利用往往都是有先行条件的,如图
比如0x4527a,就需要[rsp+0x30] == NULL
而我们在执行malloc_hook存储指令的时候,往往不能控制栈结构,这个时候我们就想到了利用realloc函数。
为什么能够利用realloc?利用realloc有什么作用?
第一,我们需要知道,realloc也是有hook函数的,并且和malloc hook相邻
第二,realloc函数在执行前检查了是否调用realloc hook,之前还push了一堆参数,依托这些push指令我们可以改变栈结构
第三,我们需要根据实际情况选择malloc指向realloc的地址,因为根据实际情况对栈push的需求是不同的
可以选择在任意指令开始realloc函数,只要在realloc hook调用之前即可
实际情况调试,可以在realloc函数下个断点调试即可
最终构造程序流控制链:malloc_hook->realloc->realloc_hook->one_gadget
(四)例题
- Bugku babyheap1
二、free hook
持续补充中…