二進(jìn)制課程堆漏洞講解_第1頁
二進(jìn)制課程堆漏洞講解_第2頁
二進(jìn)制課程堆漏洞講解_第3頁
二進(jìn)制課程堆漏洞講解_第4頁
二進(jìn)制課程堆漏洞講解_第5頁
已閱讀5頁,還剩111頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、堆漏洞講解HEAP RELATED VULNERABILITIES目錄0102堆內(nèi)存概述UAF原理與實(shí)踐0304堆相關(guān)數(shù)據(jù)結(jié)構(gòu)堆溢出原理與實(shí)踐05Unlink原理與實(shí)踐第一章堆內(nèi)存概述第一章 堆內(nèi)存概述01:堆概述 堆和棧類似,也是程序執(zhí)行過程中經(jīng)常使用的緩沖區(qū)的一種,它具備以下特性:堆是一種在程序運(yùn)行時(shí)動(dòng)態(tài)分配的內(nèi)存,其所需內(nèi)存大小在程序設(shè)計(jì)時(shí)無法預(yù)先決定。堆在使用時(shí)需要程序員用專用函數(shù)進(jìn)行申請。一般用一個(gè)堆指針來使用申請得到的內(nèi)存。使用完畢之后需要把堆指針傳給堆釋放函數(shù)回收這片內(nèi)存,否則會造成內(nèi)存泄漏。第一章 堆內(nèi)存概述01:堆概述堆內(nèi)存棧內(nèi)存典型用例動(dòng)態(tài)增長的鏈表等數(shù)據(jù)結(jié)構(gòu)函數(shù)局部數(shù)組申

2、請方式需要用函數(shù)申請,通過返回的指針使用。如p=malloc(8);在程序中直接聲明即可釋放方式需要把指針傳給專用的釋放函數(shù)函數(shù)返回時(shí),由系統(tǒng)自動(dòng)回收管理方式需要程序員處理申請與釋放申請后直接使用。申請與釋放由系統(tǒng)自動(dòng)完成,最后達(dá)到棧區(qū)平衡所處位置變化范圍很大0 xbfff*增長方向由內(nèi)存低址向高址排列由內(nèi)存高址向低址增加第一章 堆內(nèi)存概述02:*nix下典型的堆庫dlmalloc General purpose allocatorptmalloc2 glibcjemalloc FreeBSD and Firefoxtcmalloc Googlelibumem Solaris 由于內(nèi)存的需求各

3、不相同等特性,因此目前堆的實(shí)現(xiàn)有多種: 目前 Linux 標(biāo)準(zhǔn)發(fā)行版中使用的堆分配器是 glibc 中的堆分配器:ptmalloc2,其主要是通過 malloc/free 函數(shù)來分配和釋放內(nèi)存塊第一章 堆內(nèi)存概述03:堆內(nèi)存的基本操作 堆塊 (HeapChunk) 的分配是由malloc函數(shù)來完成。 一般的處理流程是先進(jìn)行堆內(nèi)存的分配,在使用完畢后,由程序釋放相應(yīng)的內(nèi)存。第一章 堆內(nèi)存概述03:堆內(nèi)存的基本操作 glibc源碼中對malloc函數(shù)的描述如下。malloc 函數(shù)返回對應(yīng)大小字節(jié)的內(nèi)存塊的指針當(dāng) n=0 時(shí),返回當(dāng)前系統(tǒng)允許的堆的最小內(nèi)存塊當(dāng) n 為負(fù)數(shù)時(shí),由于size_t 是無符

4、號數(shù),所以會導(dǎo)致嘗試分配很大空間,一般會失敗第一章 堆內(nèi)存概述03:堆內(nèi)存的基本操作 glibc源碼中對free函數(shù)的描述如下。 free 函數(shù)會釋放由 p 所指向的內(nèi)存塊。這個(gè)內(nèi)存塊有可能是通過 malloc 函數(shù)得到的,也有可能是通過相關(guān)的函數(shù) realloc 得到的當(dāng) p 已經(jīng)被釋放之后,再次釋放會出現(xiàn)危險(xiǎn)效果(double free)!第一章 堆內(nèi)存概述03:堆內(nèi)存的基本操作還有其它兩個(gè)較為常用的函數(shù)接口:void *calloc(size_t nmemb, size_t size)與malloc動(dòng)態(tài)分配完內(nèi)存后,自動(dòng)初始化該內(nèi)存空間為零void *realloc(void *ptr,

5、 size_t size)用來為ptr重新分配大小為size的一塊內(nèi)存第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用Glibc中malloc/free等函數(shù)是對底層(s)brk 函數(shù)以及 mmap, munmap等函數(shù)封裝。第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用Glibc中malloc/free等函數(shù)是對底層(s)brk 函數(shù)以及 mmap, munmap等函數(shù)封裝。系統(tǒng)調(diào)用描述int brk(void *addr)改變數(shù)據(jù)段大小,將地址設(shè)置為一個(gè)合理的addrvoid *sbrk(intptr_t increment)將程序數(shù)據(jù)段增加一定大小void

6、 *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)映射內(nèi)存文件int munmap(void *addr, size_t length)移除一個(gè)被映射的文件第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用 觀察兩次調(diào)用brk系統(tǒng)調(diào)用之后進(jìn)程虛擬空間堆的變化。第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用第一次調(diào)用brk前:start_brk = brk = end_data = 0 x804b000。此時(shí)觀察進(jìn)程虛擬空間。沒有任何新堆的出現(xiàn)第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用第一次調(diào)用brk后,可

7、以發(fā)現(xiàn)已經(jīng)出現(xiàn)了堆段:start_brk = end_data = 0 x804b000, 而brk = 0 x804c000。此時(shí)觀察進(jìn)程虛擬空間。出現(xiàn)了新的堆區(qū)第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用第二次調(diào)用brk后,可以發(fā)現(xiàn)堆段恢復(fù)為初始狀態(tài):此時(shí)觀察進(jìn)程虛擬空間。堆區(qū)被釋放第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用觀察調(diào)用mmap和munmap系統(tǒng)調(diào)用之后進(jìn)程虛擬空間的變化:第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用調(diào)用mmap前,系統(tǒng)中頁面映射如下,其中映射區(qū)頂部為0 xb7e03000:第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用調(diào)用mmap后,系統(tǒng)映射區(qū)頂部更改為0 xb7de

8、2000:而0 xb7e03000- 0 xb7de2000=132*1024剛好為我們新映射的區(qū)域大小第一章 堆內(nèi)存概述04:堆內(nèi)存底層系統(tǒng)調(diào)用調(diào)用munmap后,系統(tǒng)映射區(qū)頂部重新恢復(fù)為0 xb7e03000 :第二章堆相關(guān)數(shù)據(jù)結(jié)構(gòu)第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk在程序的執(zhí)行過程中,由 malloc 申請的內(nèi)存稱為堆塊chunk 。這塊內(nèi)存在ptmalloc內(nèi)部用malloc_chunk結(jié)構(gòu)體來表示。當(dāng)程序申請的 chunk 被 free 后,會被加入到相應(yīng)的空閑管理列表中。無論一個(gè) chunk 的大小如何,處于分配狀態(tài)還是釋放狀態(tài),它們都使用一個(gè)統(tǒng)一的結(jié)構(gòu)mallo

9、c_chunk。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk已分配堆塊的結(jié)構(gòu):如果該 chunk 的物理相鄰的前一地址chunk是空閑的話,那該字段記錄的是前一個(gè) chunk 的大小(包括 chunk 頭)。否則,該字段可以用來存儲前一個(gè)chunk 的數(shù)據(jù)(chunk中的空間復(fù)用)第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk已分配堆塊的結(jié)構(gòu):該 chunk 的大小,大小必須是 2 * SIZE_SZ 的整數(shù)倍。如果申請的內(nèi)存大小不是 2 * SIZE_SZ 的整數(shù)倍,會被轉(zhuǎn)換滿足大小的最小的 2 * SIZE_SZ 的倍

10、數(shù)。低三個(gè)比特位為標(biāo)志位:A: NON_MAIN_ARENA表征是否屬于主線程M: IS_MAPPED表征是否是由 mmap 分配的P: PREV_INUSE表征前一個(gè)堆塊是否為分配狀態(tài)第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk已分配堆塊的結(jié)構(gòu):P=1表征前一個(gè)堆塊為被分配狀態(tài)第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk已分配堆塊的結(jié)構(gòu):該 chunk 返回給用戶的可用內(nèi)存區(qū)域第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk未分配堆塊的結(jié)構(gòu):該chunk的大小。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk未分配堆塊的結(jié)構(gòu):被釋放的 chunk 被記錄在鏈表

11、中(可能是循環(huán)雙向鏈表,也可能是單向鏈表)。fd 指向下一個(gè)(非物理相鄰)空閑的 chunk;bk 指向上一個(gè)(非物理相鄰)空閑的 chunk。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk未分配堆塊的結(jié)構(gòu):P=0表明前一個(gè)堆塊是處于未分配狀態(tài)。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)01:堆塊 Heap Chunk對于未分配堆塊,有兩處記錄其大?。鹤陨韷K首的size of chunk域下一個(gè)堆塊塊首的size of previous chunk域 一般情況下,物理相鄰的兩個(gè)空閑 chunk 會被合并為一個(gè) chunk 。堆管理器會通過 prev_size 字段以及 size 字段合并兩個(gè)物理相鄰的空閑

12、 chunk 塊。該操作稱之為堆塊合并(chunk consolidate),堆塊合并過程是堆漏洞攻擊的一個(gè)非常重要的目標(biāo)。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Bin 釋放的chunk 不會馬上歸還給系統(tǒng),ptmalloc會統(tǒng)一管理所有空閑的chunk。當(dāng)用戶再一次請求分配內(nèi)存時(shí),分配器會試圖在空閑的chunk中挑選一塊合適的給用戶。這樣可以避免頻繁的系統(tǒng)調(diào)用,降低內(nèi)存分配的開銷。ptmalloc 采用分箱式方法對空閑的chunk進(jìn)行管理。首先,它會根據(jù)空閑的 chunk 的大小以及使用狀態(tài)將 chunk 初步分為4類:fast bins,small bins,large bins,unsorted

13、bin。每類中相似大小的 chunk 會用鏈表(fast bins為單向鏈表,其余為雙向鏈表)鏈接起來。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Bin ptmalloc 使用Arena來記錄空閑堆塊信息,其中主線程信息記錄在main_arena中,子線程信息分別記錄在不同的thread_arena中。Arena的結(jié)構(gòu)如圖。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Bin該變量用于控制程序串行訪問同一個(gè)分配區(qū),當(dāng)一個(gè)線程獲取了分配區(qū)之后,其它線程要想訪問該分配區(qū),就必須等待該線程分配完成候才能夠使用。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Binflags記錄了分配區(qū)的一些標(biāo)志,比如 bit0 記錄了分配區(qū)是否有 fast bin

14、chunk等。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Bin存放每個(gè) fast chunk 鏈表頭部的指針。NFASTBINS在32位和64位上分別不同第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Bin指向分配區(qū)的 top chunk第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Bin在用戶使用 malloc 請求分配內(nèi)存時(shí),ptmalloc2 找到的 chunk 可能并不和申請的內(nèi)存大小一致,這時(shí)候就將分割之后的剩余部分稱之為 last remainder chunk。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)02:Bin用于存儲 unstored bin,small bins 和 large bins 的 chunk 鏈表第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fa

15、st Bins程序經(jīng)常會申請以及釋放一些比較小的內(nèi)存塊。如果將一些較小的 chunk 釋放之后與之相鄰的空閑進(jìn)行合并,那么當(dāng)下一次再次申請相應(yīng)大小的 chunk 時(shí),就需要對 chunk 進(jìn)行分割,這樣就大大降低了堆的利用效率。因此,ptmalloc 中專門設(shè)計(jì)了 fast bin,用于保存size較小的堆塊。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins通過分配釋放4個(gè)小塊,觀察fast bins的變化。第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins內(nèi)存分配完成且數(shù)據(jù)拷貝完成時(shí)堆塊的布局及結(jié)構(gòu)如下:fast bin數(shù)據(jù)中指針均為NULL,表明目前沒有任何空閑堆塊分配的4個(gè)堆塊信息第二章 堆相

16、關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins以前兩個(gè)堆塊為例,查看內(nèi)存數(shù)據(jù):0號堆塊的大小信息1號堆塊的大小信息0號堆塊的數(shù)據(jù)區(qū)0號堆塊的塊指針0號堆塊返回給用戶的數(shù)據(jù)指針,即buf_0第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins釋放0號堆塊,查看堆塊的布局及結(jié)構(gòu)如下:Fastbin的三號鏈表中鏈入了0號堆塊0號堆塊狀態(tài)發(fā)生變化,前向指針發(fā)生變化第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins此時(shí)查看堆內(nèi)存數(shù)據(jù)如下:0號堆塊的數(shù)據(jù)AAAA被更新為前向指針NULL雖然前面堆塊是free狀態(tài),但此時(shí)1號堆塊的P=1,這是因?yàn)閒astbin 容器中的 chunk 的使用標(biāo)記總是被置位,避免被合并。第二章 堆相

17、關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins此時(shí)查看main_arena數(shù)據(jù)如下:第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins繼續(xù)執(zhí)行代碼,釋放1號堆塊,查看堆塊的布局及結(jié)構(gòu)如下:Fastbin的零號鏈表中鏈入了1號堆塊1號堆塊狀態(tài)發(fā)生變化,前向指針發(fā)生變化第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins此時(shí)堆中內(nèi)存數(shù)據(jù)如下:1號堆塊的數(shù)據(jù)BBBB被更新為前向指針NULL第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins繼續(xù)執(zhí)行代碼,釋放2號堆塊,查看堆塊的布局及結(jié)構(gòu)如下:Fastbin的三號鏈表中鏈入了2號堆塊2號堆塊狀態(tài)發(fā)生變化,前向指針發(fā)生變化第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins此時(shí)堆中內(nèi)存

18、數(shù)據(jù)如下:2號堆塊的數(shù)據(jù)CCCC被更新為前向指針0 x601000,即0號堆塊第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)03:Fast Bins此時(shí)查看main_arena數(shù)據(jù)如下:Fast bins的三號鏈表的起始指針更新為2號堆塊第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)04:Unsorted bins & Small Bins通過分配釋放4個(gè)堆塊,觀察small bins的變化。大小大于fast bin第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)內(nèi)存分配完成且數(shù)據(jù)拷貝完成時(shí)堆塊的布局及結(jié)構(gòu)如下:04:Unsorted bins & Small Bins第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)釋放0號堆塊,其首先被放入到unsorted bin中,而unsorted

19、bin可以視為空閑 chunk 回歸其所屬 bin 之前的緩沖區(qū)。釋放的0號堆塊被首先放入unsortbin 中0號堆塊的fd和bk被更新,該值為main_arena.bins004:Unsorted bins & Small Bins第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)此時(shí)查看0號堆塊內(nèi)存數(shù)據(jù)和1號堆塊內(nèi)存數(shù)據(jù)如下。0號堆塊的fd和bk被更新,該值為main_arena.bins01號堆塊的prev_size更新為0號堆塊的大小,且P標(biāo)志位更新為0,表征前一個(gè)chunk為空閑狀態(tài)04:Unsorted bins & Small Bins第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)查看main_arena如下:雙向鏈表指向0號堆

20、塊04:Unsorted bins & Small Bins第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)繼續(xù)釋放2號堆塊,堆塊布局如下:0號和2號堆塊的fd和bk同時(shí)被修改04:Unsorted bins & Small Bins第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)查看main_arena如下:Main_arena的bins數(shù)據(jù)也同時(shí)更新04:Unsorted bins & Small Bins第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)此時(shí)分配一個(gè)不在unsorted bins中的堆塊,原先鏈入在unsorted bins中的堆塊將被更新至small bins對應(yīng)的鏈表中:0號和2號堆塊被移動(dòng)至small bins對應(yīng)大小的鏈表中,且unsorte

21、d bins被清空04:Unsorted bins & Small Bins第二章 堆相關(guān)數(shù)據(jù)結(jié)構(gòu)查看main_arena如下:0號和2號堆塊被移動(dòng)至small bins對應(yīng)大小的鏈表中,且unsorted bins被清空,恢復(fù)為top chunk04:Unsorted bins & Small Bins第三章堆溢出原理與實(shí)踐第三章 堆溢出原理與實(shí)踐01:堆溢出原理堆溢出是指程序向某個(gè)堆塊中寫入的字節(jié)數(shù)超過了堆塊本身可使用的字節(jié)數(shù)(之所以是可使用而不是用戶申請的字節(jié)數(shù),是因?yàn)槎压芾砥鲿τ脩羲暾埖淖止?jié)數(shù)進(jìn)行調(diào)整,這也導(dǎo)致可利用的字節(jié)數(shù)都不小于用戶申請的字節(jié)數(shù)),因而導(dǎo)致了數(shù)據(jù)溢出,并覆蓋到物

22、理相鄰的高地址的下一個(gè)堆塊。第三章 堆溢出原理與實(shí)踐01:堆溢出原理堆溢出漏洞發(fā)生的基本前提是:程序向堆上寫入數(shù)據(jù)寫入的數(shù)據(jù)長度沒有經(jīng)過合法校驗(yàn)堆溢出是一種特定的緩沖區(qū)溢出(還有棧溢出, bss 段溢出等)。但是其與棧溢出所不同的是,堆上并不存在返回地址等可以讓攻擊者直接控制執(zhí)行流程的數(shù)據(jù),因此我們一般無法直接通過堆溢出來控制 EIP。攻擊Unlink過程、攻擊堆塊合并過程、偽造堆塊等第三章 堆溢出原理與實(shí)踐01:堆溢出原理該程序在第12行如果輸入的字符串過長會導(dǎo)致溢出 chunk 的區(qū)域并覆蓋到其后的堆塊。第三章 堆溢出原理與實(shí)踐01:堆溢出原理觀察程序運(yùn)行至第11行時(shí)進(jìn)程堆塊布局如下:1號

23、堆塊被鏈入到fastbin5當(dāng)中,其fd被更新為NULL第三章 堆溢出原理與實(shí)踐01:堆溢出原理假設(shè)惡意輸入A*0 x80個(gè)字符,該長度將溢出0號堆塊數(shù)據(jù)區(qū),寫入至1號堆塊的塊首甚至數(shù)據(jù)區(qū):1號堆塊頭部被溢出,其fd指針被惡意覆蓋為0 x4141414141414141正常的鏈?zhǔn)浇Y(jié)構(gòu)被破壞第三章 堆溢出原理與實(shí)踐01:堆溢出原理如果溢出后程序繼續(xù)嘗試malloc兩個(gè)大小為0 x60的堆塊,則分配器首先將1號堆塊從鏈表脫鏈,然后再次分配時(shí)將會把0 x4141414141414141地址作為一個(gè)堆塊分配給用戶。如果攻擊者將1號堆塊fd指針精心構(gòu)造為一個(gè)包含函數(shù)指針內(nèi)存塊的地址,那么再次分配時(shí)會將該

24、內(nèi)存作為堆塊分配給用戶。此時(shí),攻擊者則可以通過向該內(nèi)存中寫入數(shù)據(jù)從而覆蓋函數(shù)指針,進(jìn)而劫持控制流。第三章 堆溢出原理與實(shí)踐02:堆溢出之Fast Bin Attack為了便于說明,我們將后續(xù)兩次malloc和一次read均編碼在源代碼中(實(shí)際CTFpwn中一般通過菜單選擇進(jìn)行)。兩次malloc觸發(fā)脫鏈第三章 堆溢出原理與實(shí)踐 利用思路: 偽造一個(gè)地址范圍包含malloc_hook函數(shù)指針的堆塊,將其分配給用戶,然后通過內(nèi)存寫將malloc_hook函數(shù)指針覆蓋為bonus函數(shù)地址,從而再次malloc時(shí)觸發(fā)shell。偽造堆塊劫持malloc_hook02:堆溢出之Fast Bin Atta

25、ck第三章 堆溢出原理與實(shí)踐堆塊偽造結(jié)束后,進(jìn)程堆塊布局及對應(yīng)內(nèi)存數(shù)據(jù)如下:偽造長度必須與fastbin對應(yīng)鏈表索引相同覆蓋fd指針為malloc_hook-0 x2302:堆溢出之Fast Bin Attack第三章 堆溢出原理與實(shí)踐為何不能直接將fd覆蓋為malloc_hook-0 x10?偽造長度必須與fastbin對應(yīng)鏈表索引相同此時(shí)不用考慮內(nèi)存對齊02:堆溢出之Fast Bin Attack第三章 堆溢出原理與實(shí)踐兩次malloc之后,我們成功將malloc_hook-0 x23脫鏈,即buf_4= malloc_hook-0 x23+0 x10,此時(shí)buf_4距離malloc_ho

26、ok只需要填充19個(gè)字符,然后就可以覆蓋malloc_hook。02:堆溢出之Fast Bin Attack第三章 堆溢出原理與實(shí)踐成功將malloc_hook覆蓋為bonus函數(shù)地址,再次調(diào)用malloc觸發(fā)shell。成功篡改malloc_hook02:堆溢出之Fast Bin Attack第四章UAF原理與實(shí)踐第四章 UAF原理與實(shí)踐01:UAF原理UAF即Use After Free,是指當(dāng)一個(gè)內(nèi)存塊被釋放之后再次被程序使用,從而引發(fā)非預(yù)期的效應(yīng)。具體可細(xì)分為三種情況:堆塊釋放后,其對應(yīng)的指針被置為 NULL , 此時(shí)再次使用會造成程序崩潰。堆塊釋放后,其對應(yīng)的指針未被置為 NULL,

27、然后在再次被使用之前,沒有代碼對這塊內(nèi)存進(jìn)行修改,那么程序很有可能可以正常運(yùn)轉(zhuǎn)。堆塊釋放后,其對應(yīng)的指針未被置為 NULL,但是在再次被使用之前,存在代碼對這塊內(nèi)存進(jìn)行修改,此時(shí)程序會出現(xiàn)嚴(yán)重問題,甚至造成高危漏洞。第四章 UAF原理與實(shí)踐01:UAF原理一般所指的 UAF漏洞主要是后兩種。此外,我們一般稱被釋放后沒有被設(shè)置為NULL的內(nèi)存指針為懸掛指針 (dangling pointer)。示例:UAF漏洞a為懸掛指針,代碼中羅列了3種不同情況第四章 UAF原理與實(shí)踐01:UAF原理示例:一個(gè)更深入的UAF漏洞指針p1申請內(nèi)存,打印其地址值,然后釋放p1指針;指針p2申請同樣大小的內(nèi)存,打印

28、p2的地址,p1指針指向的內(nèi)存值。p1為懸掛指針第四章 UAF原理與實(shí)踐01:UAF原理運(yùn)行結(jié)果如下:p1與p2地址相同,p1指針釋放后,p2申請相同的大小的內(nèi)存,操作系統(tǒng)會將之前給p1的地址分配給p2,此時(shí)修改p2的值,p1也相應(yīng)被修改了。在free一塊內(nèi)存后,接著申請大小相同的一塊內(nèi)存,分配器會將剛free掉的內(nèi)存再次分配通過p2能夠操作p1,如果之后p1繼續(xù)被使用(use after free),則可以達(dá)到通過p2修改程序功能等目的。第四章 UAF原理與實(shí)踐02:UAF漏洞利用以 HITCON-training 中的 lab 10 hacknote為例演示UAF漏洞利用過程。可以看出在程

29、序的開頭有個(gè)menu函數(shù),其中有add note/delete note/print note。故而程序應(yīng)該主要有3個(gè)功能。之后程序會根據(jù)用戶的輸入執(zhí)行相應(yīng)的功能。第四章 UAF原理與實(shí)踐02:UAF漏洞利用Add note功能:根據(jù)程序,我們可以看出程序最多可以添加5個(gè)note。每個(gè)note有兩個(gè)字段output與content,其中output會被設(shè)置為一個(gè)函數(shù),其函數(shù)會輸出 content 具體的內(nèi)容。struct note void * output; /函數(shù)指針 char * content; /指向contentcontent內(nèi)存位于堆上,其大小由用戶輸入size控制output函

30、數(shù)指針第四章 UAF原理與實(shí)踐02:UAF漏洞利用Delete note功能:delete_note 會根據(jù)給定的索引來釋放對應(yīng)的note。但是值得注意的是,在 刪除的時(shí)候,只是單純進(jìn)行了free,而沒有設(shè)置為NULL,那么顯然,此處存在Use After Free漏洞。內(nèi)存釋放后造成懸掛指針,引發(fā)UAF漏洞第四章 UAF原理與實(shí)踐02:UAF漏洞利用Print note功能:print_note就是簡單的根據(jù)給定的note的索引來輸出對應(yīng)索引的note的內(nèi)容。注意,不是輸出content內(nèi)容,輸出的是note內(nèi)容!第四章 UAF原理與實(shí)踐02:UAF漏洞利用利用思路:首先創(chuàng)建兩個(gè)note (

31、較大content size),然后再釋放這兩個(gè)note形成懸掛指針。此時(shí)內(nèi)存中將存在著兩個(gè)較小的被free的note結(jié)構(gòu)體。然后創(chuàng)建一個(gè)較小content size的note,將占用之前被free的兩個(gè)note結(jié)構(gòu)體。最后,通過覆蓋并調(diào)用其中一個(gè)note的output函數(shù)指針來獲得shell。第四章 UAF原理與實(shí)踐02:UAF漏洞利用兩次創(chuàng)建note之后的內(nèi)存數(shù)據(jù)如下:Note_0的output函數(shù)指針與content指針Note_0的content所在堆塊Note_1的output函數(shù)指針與content指針Note_1的content所在堆塊第四章 UAF原理與實(shí)踐02:UAF漏洞利用

32、釋放note_0和note_1之后的堆塊布局如下:Note_0和note_1均處于free狀態(tài),且被加入到fastbins當(dāng)中第四章 UAF原理與實(shí)踐02:UAF漏洞利用觀察釋放note_0和note_1之后的內(nèi)存數(shù)據(jù)如下:Note_0和note_1均的output函數(shù)指針被更新為相應(yīng)的值第四章 UAF原理與實(shí)踐02:UAF漏洞利用此時(shí)創(chuàng)建一個(gè)新的note (note_2),其content大小和note結(jié)構(gòu)體大小保持一致,則根據(jù)fast bin的脫鏈規(guī)則,note_1的結(jié)構(gòu)體內(nèi)存將被分配給note_2的結(jié)構(gòu)體,note_0的結(jié)構(gòu)體內(nèi)存將被分配給note_2的content:note_1結(jié)構(gòu)體

33、被note_2結(jié)構(gòu)體占用note_0結(jié)構(gòu)體被note_2.content占用第四章 UAF原理與實(shí)踐02:UAF漏洞利用此時(shí)創(chuàng)建一個(gè)新的note (note_2),其content大小和note結(jié)構(gòu)體大小保持一致,則根據(jù)fast bin的脫鏈規(guī)則,note_1的結(jié)構(gòu)體內(nèi)存將被分配給note_2的結(jié)構(gòu)體,note_0的結(jié)構(gòu)體內(nèi)存將被分配給note_2的content:note_0結(jié)構(gòu)體被note_2.content占用覆蓋note_0的output函數(shù)指針為system的地址第四章 UAF原理與實(shí)踐02:UAF漏洞利用在將note_0的output函數(shù)指針的覆蓋為system函數(shù)地址時(shí),同時(shí)覆蓋

34、note_0的content指針為”|sh”,這是為了避免system的截?cái)鄦栴}(該題目中最終將執(zhí)行system(*0 x0804b008))。最后,調(diào)用print note功能,成功觸發(fā)shell。第五章Unlink原理與實(shí)踐第五章 Unlink原理與實(shí)踐01:遠(yuǎn)古時(shí)期Unlink原理Unlink用來將一個(gè)雙向鏈表(只存儲空閑的 chunk)中的一個(gè)元素取出來,可能在以下地方使用:malloc 從恰好大小合適的 large bin 中獲取 chunk。 這里需要注意的是 fastbin 與 small bin沒有使用unlink,依次遍歷處理 unsorted bin 時(shí)也沒有使用unlin

35、k。Free后向合并,合并物理相鄰低地址空閑 chunk。前向合并,合并物理相鄰高地址空閑 chunk(除了 top chunk)。malloc_consolidate 后向合并,合并物理相鄰低地址空閑 chunk。 前向合并,合并物理相鄰高地址空閑 chunk(除了 top chunk)。realloc 前向擴(kuò)展,合并物理相鄰高地址空閑 chunk(除了top chunk)第五章 Unlink原理與實(shí)踐01:遠(yuǎn)古時(shí)期Unlink原理設(shè)置 P-fd-bk = P-bk.設(shè)置 P-bk-fd = P-fd.第五章 Unlink原理與實(shí)踐01:遠(yuǎn)古時(shí)期Unlink原理以 32 位為例,假設(shè)我們將中

36、間堆塊的fd/bk篡改為target_addr 12 和expect_value第五章 Unlink原理與實(shí)踐01:遠(yuǎn)古時(shí)期Unlink原理那么在釋放該堆塊時(shí), glibc 判斷這個(gè)塊是 small chunk。 判斷前向合并,發(fā)現(xiàn)前一個(gè) chunk 處于使用狀態(tài),不需要前向合并。 判斷后向合并,發(fā)現(xiàn)后一個(gè) chunk 處于空閑狀態(tài),需要合并。 繼而對 nextchunk 采取 unlink 操作。根據(jù)unlink的機(jī)制: 設(shè)置 P-fd-bk = P-bk.設(shè)置 P-bk-fd = P-fd. FD=P-fd = target addr -12 BK=P-bk = expect value

37、FD-bk = BK,即 *(target addr-12+12)=BK=expect value BK-fd = FD,即*(expect value +8) = FD = target addr-12可以實(shí)現(xiàn)任意地址寫任意數(shù)據(jù)第五章 Unlink原理與實(shí)踐02:現(xiàn)代時(shí)期Unlink原理現(xiàn)代glibc堆分配器對unlink進(jìn)行了安全增強(qiáng),阻止了上述直接形式上的任意地址寫任意數(shù)據(jù)攻擊。對chunk大小進(jìn)行檢查對fd和bk合法性進(jìn)行檢查第五章 Unlink原理與實(shí)踐03:攻擊現(xiàn)代Unlink如果我們能夠找到一個(gè)指向該堆塊的內(nèi)存地址記為Ptr,則假設(shè)我們按照下述方法進(jìn)行覆蓋,則可以繞過對fd和bk

38、的合法性檢查。Ptr-12Ptr-8chunk addr第五章 Unlink原理與實(shí)踐03:攻擊現(xiàn)代Unlink此時(shí)Unlink發(fā)生后ptr指向內(nèi)存數(shù)據(jù)被更新為ptr-12,如圖。Ptr-12Ptr-8ptr-12第五章 Unlink原理與實(shí)踐03:攻擊現(xiàn)代Unlink*ptr最初指向分配的堆塊,因此通常情況下都可以作為緩沖區(qū)進(jìn)行編輯,那么假設(shè)我們向*ptr寫入AAAABBBBCCCCDDDD,如下。ptr-12DDDDCCCCBBBBAAAA此時(shí)繼續(xù)向*ptr寫入則獲得一次任意地址寫任意數(shù)據(jù)的機(jī)會第五章 Unlink原理與實(shí)踐04:Unlink攻擊實(shí)踐以2015第一屆強(qiáng)網(wǎng)杯shellman演示unlink攻擊過程,該binary中存在堆溢出??梢钥闯鲈诔绦虻拈_頭有個(gè)menu函數(shù),其中有一些常用的操作如查看、增加、編輯、刪除等操作。故而程序應(yīng)該主要有4個(gè)功能。之后程序會根據(jù)用戶的輸入執(zhí)行相應(yīng)的功能。第五章 Unlink原理與實(shí)踐04:Unlink攻擊實(shí)踐Create shellcode函數(shù)反編譯結(jié)果:根據(jù)代碼可以推理出正常情況下堆的布局如下:存放在.bss段,指向堆內(nèi)存第五章 Unlink原理與實(shí)踐04:Unlin

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論