分析方法:
全局變量位置布局: 哪些在.bss,哪些在.data,變量之間的關(guān)系
哪些變量, 緩沖區(qū), 數(shù)組,存儲(chǔ)了哪些值(別的變量,別的地址,申請(qǐng)的堆地址)
使用的數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù)結(jié)構(gòu)中成員之間的關(guān)系,地址位置關(guān)系,各個(gè)成員大小及其含義.
程序處理數(shù)據(jù)結(jié)構(gòu)的方法:存儲(chǔ)方式,遍歷方式,查找方式.操作方法(創(chuàng)建,修改,打印,刪除.增刪改查各種操作)
是否有數(shù)組越界, 整數(shù)溢出(處理不好負(fù)數(shù),處理不好0,-1后又變成全f), 長(zhǎng)度判斷錯(cuò)誤,沒有進(jìn)行長(zhǎng)度判斷,將用戶提供的長(zhǎng)度直接去申請(qǐng)內(nèi)存,
是否有uaf,是否有double free,是否有懸掛指針
分析使用了什么bin:fastbin, smallbin, unsorted bin, top chunk 能否利用
錯(cuò)誤的unlink對(duì)棧, bss,.data等進(jìn)行操作
一般大結(jié)構(gòu)體對(duì)應(yīng)的申請(qǐng)的堆地址會(huì)存儲(chǔ)在bss上的全局變量. 可用于unlink將其中一個(gè)地址指向改全局變量前面,操作該堆內(nèi)容時(shí)就會(huì)操作到該全局變量.(unlink的套路)
1.off by one
http://www.lxweimin.com/p/046a6b0578fc
2.unlink
3.uaf
http://www.lxweimin.com/p/1b0b773a8c7f
4.fastbin attack
fastbin double free 也是一種修改fd指向來在任意地址分配內(nèi)存,可以在某個(gè)可以被編輯的全局指針處,malloc_hook處亦可以
偽造fastbin chunk,強(qiáng)制釋放后再次申請(qǐng)到這片內(nèi)存(需要繞過很多檢查)
修改fastbin中chunk的fd指向stack或者其他地方中偽造的fast chunk,多次申請(qǐng)內(nèi)存后得到目標(biāo)地址內(nèi)存(只需要繞過size檢查),
可通過前一個(gè)chunk的堆溢出修改下一個(gè)chunk的fd和其他chunk的size域. 這種方式可以結(jié)合unsorted bin泄漏libc和修改fd申請(qǐng)到
malloc_hook進(jìn)行g(shù)etshell.
實(shí)例1:
實(shí)例2: http://www.lxweimin.com/p/5b0a1b168fed
5.Chunk Extend and Overlapping
1).篡改前一個(gè)塊大小,釋放后把后一個(gè)塊合起來free到fastbin中:
0x602000: 0x0000000000000000 0x0000000000000041 <=== 篡改大小
0x602010: 0x0000000000000000 0x0000000000000000
0x602020: 0x0000000000000000 0x0000000000000021 這個(gè)chunk屬于bin中的某個(gè)chunk
0x602030: 0x0000000000000000 0x0000000000000000
0x602040: 0x0000000000000000 0x0000000000020fc1
2).small bin:篡改的時(shí)機(jī)在釋放前后都是可以的,因?yàn)閡nsorted bin大小不同的chunk可共存.
而fastbin不能在free后篡改,因?yàn)閎in的鏈表大小是相同的,就算改了也不會(huì)找到這個(gè)塊進(jìn)行分配.
0x602000: 0x0000000000000000 0x00000000000000b1 <=== 被放入unsorted bin, 篡改為0xb0大小
0x602010: 0x00007ffff7dd1b78 0x00007ffff7dd1b78
0x602020: 0x0000000000000000 0x0000000000000000
0x602030: 0x0000000000000000 0x0000000000000000
0x602040: 0x0000000000000000 0x0000000000000000
0x602050: 0x0000000000000000 0x0000000000000000
0x602060: 0x0000000000000000 0x0000000000000000
0x602070: 0x0000000000000000 0x0000000000000000
0x602080: 0x0000000000000000 0x0000000000000000
0x602090: 0x0000000000000000 0x0000000000000021
0x6020a0: 0x0000000000000000 0x0000000000000000 一直extend到這里
0x6020b0: 0x00000000000000b0 0x0000000000000020 <=== 注意此處標(biāo)記為空,這個(gè)塊防止與top chunk合并
0x6020c0: 0x0000000000000000 0x0000000000000000
0x6020d0: 0x0000000000000000 0x0000000000020f31 <=== top chunk
3)fastbin 的后向extend多個(gè)塊:
ptr=malloc(0x10);//分配第1個(gè) 0x80 的chunk1
malloc(0x10); //分配第2個(gè) 0x10 的chunk2
malloc(0x10); //分配第3個(gè) 0x10 的chunk3
malloc(0x10); //分配第4個(gè) 0x10 的chunk4
*(int *)((int)ptr-0x8)=0x61;
free(ptr);
ptr1=malloc(0x50);這個(gè)包含了后3個(gè)堆,可完全控制它們
4)各種塊的前向extend:
ptr1=malloc(128);//smallbin1
ptr2=malloc(0x10);//fastbin1
ptr3=malloc(0x10);//fastbin2
ptr4=malloc(128);//smallbin2
malloc(0x10);//防止與top合并
free(ptr1);
*(int *)((long long)ptr4-0x8)=0x90;//修改pre_inuse域
*(int *)((long long)ptr4-0x10)=0xd0;//修改pre_size域
free(ptr4);//unlink進(jìn)行前向extend
malloc(0x150);//占位塊,可以控制前面4個(gè)塊
6.House Of xxx:
1)House Of Einherjar:通過溢出(一般是堆溢出)修改in_use,主動(dòng)觸發(fā)free后進(jìn)行合并,且此時(shí)prev_size可是可控的,達(dá)到再次申請(qǐng)到任意地址內(nèi)存的效果
實(shí)例:http://www.lxweimin.com/p/dbf0d8adc736
2)House of Lore
類似于修改fastbin的fd指針一樣修改small bin的bk,從而在指定位置申請(qǐng)內(nèi)存.
3)House Of Force
這個(gè)是針對(duì)top chunk size 的纂改,可以使得 top chunk 指向我們期望的任何位置,這就相當(dāng)于一次任意地址寫,一般通過堆溢出寫入size為-1
首先,需要存在漏洞使得用戶能夠控制 top chunk 的 size 域。
其次,需要用戶能自由控制 malloc 的分配大小
第三,分配的次數(shù)不能受限制
size計(jì)算:
目標(biāo)地址t, top chunk 地址s
按理說的大小是 w=t-s
但是輸入i要滿足((i) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK=w
而MALLOC_ALIGN_MASK = 2 * SIZE_SZ -1
實(shí)例1:HITCON training lab 11
s=0xa4e060
t=0xa4e000
w=t-s=-0x60 由于這個(gè)值已經(jīng)是對(duì)~MALLOC_ALIGN_MASK對(duì)齊(就是看低16bit位全為0就已經(jīng)對(duì)齊了,
此時(shí)w&~MALLOC_ALIGN_MASK還是=w)
i=w- SIZE_SZ - MALLOC_ALIGN_MASK
實(shí)例二:
4)House of Rabbit
一般運(yùn)用在 fastbin attack 中,利用了在 malloc consolidate 的時(shí)候 fastbin 中的堆塊進(jìn)行合并時(shí) size 沒有進(jìn)行檢查從而偽造一個(gè)假的堆塊.
可以通過修改size字段(堆溢出),再分配大內(nèi)存觸發(fā)合并
也可以通過uaf修改fd觸發(fā)
5)House of Roman
7.Unsorted Bin Attack
Unsorted Bin Attack 被利用的前提是控制 Unsorted Bin Chunk 的 bk 指針。重要!!(一般通過堆溢出覆蓋已被釋放到unsortedbin中的chunk)
Unsorted Bin Attack 可以達(dá)到的效果是實(shí)現(xiàn)修改任意地址值為一個(gè)較大的數(shù)值。
當(dāng)一個(gè)較大的 chunk 被分割成兩半后,如果剩下的部分大于 MINSIZE,就會(huì)被放到 unsorted bin 中。
釋放一個(gè)不屬于 fast bin 的 chunk,并且該 chunk 不和 top chunk 緊鄰時(shí),該 chunk 會(huì)被首先放到 unsorted bin 中。
插入的時(shí)候插入到 unsorted bin 的頭部,取出的時(shí)候從鏈表尾獲取。
當(dāng)進(jìn)行 malloc_consolidate 時(shí),可能會(huì)把合并后的 chunk 放到 unsorted bin 中,如果不是和 top chunk 近鄰的話。
可用于泄漏地址和任意地址寫固定大數(shù)據(jù).
- .tcache
tcache poisoning :類似于fastbin中的chunk的fd被修改,但是修改tcache的fd不需要size驗(yàn)證
tcache dup:類似于double free或者修改fd形成的循環(huán)鏈表.且沒有檢測(cè)可以t->a->t...
tcache house of spirit;強(qiáng)制對(duì)某塊進(jìn)行釋放,沒有對(duì)齊檢測(cè)
tcache unlink: 在 smallbin 中包含有空閑塊的時(shí)候,會(huì)同時(shí)將同大小的其他空閑塊,放入 tcache 中,此時(shí)也會(huì)出現(xiàn)解鏈操作,但相比于 unlink 宏,缺少了鏈完整性校驗(yàn)。因此,原本 unlink 操作在該條件下也可以使用。例子:
利用unsorted bin泄漏libc需要將tcache填滿才行.就這個(gè)導(dǎo)致了一些麻煩而已
內(nèi)存釋放:
在 free 函數(shù)的最先處理部分,首先是檢查釋放塊是否頁對(duì)齊及前后堆塊的釋放情況,便優(yōu)先放入 tcache 結(jié)構(gòu)中。
內(nèi)存申請(qǐng):
(1)首先,申請(qǐng)的內(nèi)存塊符合 fastbin 大小時(shí)并且找到在 fastbin 內(nèi)找到可用的空閑塊時(shí),會(huì)把該 fastbin 鏈上的其他內(nèi)存塊放入 tcache 中。
(2)其次,申請(qǐng)的內(nèi)存塊符合 smallbin 大小時(shí)并且找到在 smallbin 內(nèi)找到可用的空閑塊時(shí),會(huì)把該 smallbin 鏈上的其他內(nèi)存塊放入 tcache 中。
(3)當(dāng)在 unsorted bin 鏈上循環(huán)處理時(shí),當(dāng)找到大小合適的鏈時(shí),并不直接返回,而是先放到 tcache 中,繼續(xù)處理。
9.IO_FILE
1)偽造vtable指針指向別處,再該處寫入要劫持的對(duì)象和內(nèi)容. 實(shí)例:
http://www.lxweimin.com/writer#/notebooks/32246030/notes/40290385
2)FSOP 文件流導(dǎo)向編程.
劫持_IO_list_all 的值來偽造鏈表和其中的_IO_FILE 項(xiàng)
觸發(fā):FSOP 選擇的觸發(fā)方法是調(diào)用_IO_flush_all_lockp,這個(gè)函數(shù)會(huì)刷新_IO_list_all 鏈表中所有項(xiàng)的文件流,相當(dāng)于對(duì)每個(gè) FILE 調(diào)用 fflush,也對(duì)應(yīng)著會(huì)調(diào)用_IO_FILE_plus.vtable 中的_IO_overflow。
如何觸發(fā)?:
當(dāng) libc 執(zhí)行 abort 流程時(shí)
當(dāng)執(zhí)行 exit 函數(shù)時(shí)
當(dāng)執(zhí)行流從 main 函數(shù)返回時(shí)
條件:泄漏libc基址, 任意地址寫修改_IO_list_all
繞過: fp->_mode <= 0; fp->_IO_write_ptr > fp->_IO_write_base
3)2.24版本及以上多了檢測(cè).很難劫持vtable了
scanf讀入數(shù)據(jù)時(shí)會(huì)先將數(shù)據(jù)寫入到IO_FILE中的char* _IO_buf_base; /* Start of reserve area. /
char _IO_buf_end; /* End of reserve area. */ 地址中,這些地址是通過heap分配的.
如果修改了這些地址,就可以往別處寫入數(shù)據(jù)了.