malloc源码分析(4)--free后mallocdouble free
文章目錄
- 測(cè)試代碼
- __libc_malloc
- __libc_malloc調(diào)用_int_malloc
- _int_malloc回到__libc_malloc
- 如何利用double free
- 測(cè)試代碼
- 測(cè)試代碼2
之前我們從源碼的角度分析了如何初始化heap并且從top chunk分配出了第一個(gè)塊fast bin,那么這次我們結(jié)合free fastchunk來分配相同size的fastbin
測(cè)試代碼
#include<malloc.h> int main(){void *p=malloc(0x18);*(int *)(p+8)=0xdeadbaaf;free(p);p=NULL;void *p1=malloc(0x18);return 0; }其實(shí)代碼很簡(jiǎn)單,我們主要就是跟蹤一下從freechunk里面malloc出來究竟有哪些check
大概運(yùn)行到這里吧,然后我們跟進(jìn)
__libc_malloc
我們首先看看現(xiàn)在的main_arena
可以看到對(duì)應(yīng)大小有一個(gè)空閑塊,并且flags是0代表有fastchunks
同時(shí)__malloc_hook為NULL,只要我們不設(shè)置,初始化后他就一直是NULL.所以我們這里不會(huì)去調(diào)用
獲取ar_ptr并且進(jìn)入_int_malloc
__libc_malloc調(diào)用_int_malloc
這個(gè)函數(shù)兩個(gè)作用
- 如果需要的size太大,就返回0
- 正常請(qǐng)求就轉(zhuǎn)化成具體需要的size(需要考慮header)
那么多大算太大呢
internal_size_t也就是8,minsize也就是0x20,所以就是(unsigned)-0x200
具體為什么這個(gè)值我也不清楚,但一般情況下肯定都是滿足的
大部分都類似于之前提到的malloc
這里因?yàn)槲覀兇笮〈_實(shí)滿足,所以會(huì)進(jìn)來,之前由于沒有初始化所以進(jìn)不來
非常熟悉的操作,尋找到對(duì)應(yīng)的fastbiny的地址
這里我們肯定會(huì)執(zhí)行一次因?yàn)閐o while,如果victim==NULL代表里面確實(shí)沒有就跳出,然后while的成立的條件其實(shí)是寫入失敗,因?yàn)閷懭氤晒ψ詈髸?huì)返回victim,那么就相當(dāng)于是false,所以一般我們也會(huì)成功,這里寫while可能會(huì)涉及多線程,但單線程的時(shí)候如果有free chunk就相當(dāng)于我把victim->fd寫到fastbiny里面,就相當(dāng)于拿出來一個(gè)
這里其實(shí)是檢查fastbiny的大小是否和我們需要的size匹配,一般來說是匹配的,如果失敗說明這個(gè)fastbin鏈表被修改了
額這個(gè)是源碼里面的
結(jié)果我直接跳到這里來了
感覺是這個(gè)優(yōu)化的有點(diǎn)奇怪,我單步執(zhí)行一下,好像執(zhí)行了void *p=chunk2mem(victim);
然后這個(gè)allo_perturb和free_perturb都是一樣的,都不會(huì)執(zhí)行
那么就回到了__libc_malloc
_int_malloc回到__libc_malloc
這里我們已經(jīng)獲取到了要分配的區(qū)域,所以不會(huì)進(jìn)去
解鎖
簡(jiǎn)單檢查一下
就回來了
可以看到我們這里malloc的就是剛剛釋放的,并且里面還有數(shù)據(jù)
所以一般提倡malloc后立馬memset清空
如何利用double free
測(cè)試代碼
#include<malloc.h> int main(){void *p=malloc(0x18);void *p1=malloc(0x18);free(p);free(p1);free(p);void *p2=malloc(0x18);*(size_t*)p2=0xdeadbaff;return 0; }回到我們上次提到的double free,為了避免free check double free的情況,我們中間需要隨便free掉一個(gè)heap,然后就形成了這樣環(huán)形的情況
我們首先malloc一個(gè)
大家知道由于malloc不會(huì)清空heap內(nèi)容,所以我們現(xiàn)在fastbiny保存的就應(yīng)該是0x405020,然后這個(gè)時(shí)候我們修改一下fd的指針
可以看到變成這個(gè)樣子了
所以我們?nèi)绻賛alloc三次的話,第三次就應(yīng)該可以malloc到我們需要任意寫的地方
為什么可以這樣呢?
其實(shí)我們通過剛才簡(jiǎn)單的free malloc可以看出,我們fastbiny他是以0作為結(jié)束標(biāo)準(zhǔn)的,他不會(huì)去記錄你到底進(jìn)去了幾個(gè)出來了幾個(gè),只要里面不是0,我認(rèn)為就還有,還可以分配,所以當(dāng)我們修改了鏈之后,他就會(huì)乖乖去跟著fd去遍歷
而一般來說fd都是可以控制的,它屬于我們的data區(qū)域
那么我們接著攻擊,看可以可以malloc三次
測(cè)試代碼2
因?yàn)橹虚g兩次的malloc其實(shí)是沒什么用的,所以我就沒保留指針
#include<malloc.h> int main(){void *p=malloc(0x18);void *p1=malloc(0x18);free(p);free(p1);free(p);void *p2=malloc(0x18);*(size_t*)p2=0xdeadbaff;malloc(0x18);malloc(0x18);void *p3=malloc(0x18);return 0; }如愿以償?shù)男薷某闪薲eadbaff,我們執(zhí)行一下
報(bào)錯(cuò),奧段錯(cuò)誤,確實(shí),這個(gè)地方不一定有內(nèi)容,我們指向別的吧
這里其實(shí)我們要獲取__malloc_hook就要知道libc加載地址,但這里我遇到了點(diǎn)問題
dlopen是可以用來獲取so加載地址,類似于windows下的GetProcAddr,但這里如果我用的不是系統(tǒng)自身版本的libc就會(huì)報(bào)錯(cuò),暫時(shí)還不知道為什么
這里我們先寫死吧
這里可以看到我具體的加載地址
那么對(duì)于我就是這樣的
我們執(zhí)行到這里可以看到,bins已經(jīng)被修改到malloc_hook,也就是說我們malloc的第三個(gè)就在malloc_hook附近
臥槽,報(bào)錯(cuò)了??,我們跟蹤一下
一直到_int_malloc都沒什么問題
問題還是出現(xiàn)在了這里
由于victim就是我們當(dāng)前將要分配的區(qū)域,他會(huì)檢查這個(gè)大小是否匹配,如果不匹配就不分配
所以我們先要繞過這個(gè)大小檢查
這個(gè)也是fastbin attack里面需要特別構(gòu)造的一點(diǎn),就是大小匹配
注意到malloc上面這一塊,有一個(gè)比較特殊的偏移
可以看到有個(gè)7f的區(qū)域
那么我們?cè)偃タ纯碿hunksize的實(shí)現(xiàn)
size_bits其實(shí)就是4+2+1=7
所以相當(dāng)于就是
fastbin_index的實(shí)現(xiàn)呢
左移4位減去2,剛好就是5,而5對(duì)應(yīng)的大小就是0x70,所以我們要保證最后分配的塊實(shí)際大小是0x70
為什么這里0x78也可以呢,還記得我說idx是/16嘛,所以你多一點(diǎn)沒關(guān)系,畢竟我是整除,其實(shí)我個(gè)人覺得如果畢竟chunksize(victim)==size最好
因?yàn)檫@種不嚴(yán)格的判斷才導(dǎo)致我們可以利用0x7f來繞過,而且在實(shí)際中,一般塊的大小也只會(huì)收到1,2,4標(biāo)記位的影響,我們chunksize已經(jīng)去掉了,不知道這里為什么還要多此一舉反而可以讓我們繞過
接下來就是修改一下payload,因?yàn)橐WC獲取0x70
#include<malloc.h> int main(){void *p=malloc(0x68);void *p1=malloc(0x68);free(p);free(p1);free(p);void *p2=malloc(0x68);*(size_t*)p2=0x7ffff7fcbb10;-0x23malloc(0x68);malloc(0x68);void *p3=malloc(0x68);return 0; }首先運(yùn)行一下,可以看到成功分配
我們?cè)僬{(diào)試一下
這個(gè)就是__malloc_hook上面的那個(gè)地址
bytes是我們需要的,nb是實(shí)際的,idx就是實(shí)際需要的fastbin對(duì)應(yīng)的索引
當(dāng)前的fastbiny地址和空閑塊地址
victim就是我們這里的pp
這里因?yàn)閯偤梅衔覀兊纳婕熬蜏?zhǔn)備返回
回到主函數(shù),確實(shí)也被修改了
這才是完整的malloc_hook對(duì)應(yīng)的heap
我們找找malloc_hook的偏移0x23-0x10=0x13
這里我們測(cè)試就寫個(gè)deadbaaf,實(shí)際上需要寫一個(gè)one_gadget
所以總的大概double free就這樣啦
總結(jié)
以上是生活随笔為你收集整理的malloc源码分析(4)--free后mallocdouble free的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 远程计算机未配置身份验证出现问题怎么办,
- 下一篇: IDEA配置JDK、Maven 常见错误