+ All Categories
Home > Internet > Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Date post: 22-Jan-2018
Category:
Upload: pacsecjp
View: 382 times
Download: 1 times
Share this document with a friend
83
From Out of Memory to Remote Code Execu3on Yuki Chen (@guhe120) Qihoo 360Vulcan Team
Transcript
Page 1: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

FromOutofMemorytoRemoteCodeExecu3on �YukiChen(@guhe120)Qihoo360VulcanTeam

Page 2: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

CVE-2014-0290,CVE-2014-0321,CVE-2014-1753,CVE-2014-1769,CVE-2014-1782,CVE-2014-1804,CVE-2014-2768,CVE-2014-2802,CVE-2014-2803,CVE-2014-2824,CVE-2014-4057,CVE-2014-4092,CVE-2014-4091,CVE-2014-4095,CVE-2014-4096,CVE-2014-4097,CVE-2014-4082,CVE-2014-4105,CVE-2014-4129,CVE-2014-6369,CVE-2015-0029,CVE-2015-1745,CVE-2015-1743,CVE-2015-3134,CVE-2015-3135,CVE-2015-4431,CVE-2015-5552,CVE-2015-5553,CVE-2015-5559,CVE-2015-6682,CVE-2015-7635,CVE-2015-7636,CVE-2015-7637,CVE-2015-7638,CVE-2015-7639,CVE-2015-7640,CVE-2015-7641,CVE-2015-7642,CVE-2015-7643,CVE-2015-8454,CVE-2015-8059,CVE-2015-8058,CVE-2015-8055,CVE-2015-8057,CVE-2015-8056,CVE-2015-8061,CVE-2015-8067,CVE-2015-8066,CVE-2015-8062,CVE-2015-8068,CVE-2015-8064,CVE-2015-8065,CVE-2015-8063,CVE-2015-8405,CVE-2015-8404,CVE-2015-8402,CVE-2015-8403,CVE-2015-8071,CVE-2015-8401,CVE-2015-8406,CVE-2015-8069,CVE-2015-8070,CVE-2015-8440,CVE-2015-8409,CVE-2015-8047,CVE-2015-8455,CVE-2015-8045,CVE-2015-8441,CVE-2016-0980,CVE-2016-1015,CVE-2016-1016,CVE-2016-1017,CVE-2016-4120,CVE-2016-4160,CVE-2016-4161,CVE-2016-4162,CVE-2016-4163,CVE-2016-4185CVE-2016-4249,CVE-2016-4180,CVE-2016-4181,CVE-2016-4183,CVE-2016-4184,CVE-2016-4185,CVE-2016-4186,CVE-2016-4187,CVE-2016-4233,CVE-2016-4234,CVE-2016-4235,CVE-2016-4236,CVE-2016-4237,CVE-2016-4238,CVE-2016-4239,CVE-2016-4240,CVE-2016-4241,CVE-2016-4242,CVE-2016-4243,CVE-2016-4244,CVE-2016-4245,CVE-2016-4246,CVE-2016-4182,CVE-2016-3375,CVE-2017-3001,CVE-2017-3002,CVE-2017-3003,CVE-2017-0238,CVE-2017-0236,CVE-2017-8549,CVE-2017-8619�

WhoamI �BugHunter@360VulcanTeam�

Page 3: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

WhoamI �HardcoreACGOtaku

Page 4: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

About360VulcanTeam�

ü  SecurityResearchesfromQihu360

ü  Pwn2OwnWinners:ü  Pwn2Own2015IE11ü  Pwn2Own2016Google

Chrome,AdobeFlashü  Pwn2Own2017Edge,Safari,

AdobeFlash,Win10,MacOSXü  “MasterofPwn”Pwn2Own

2017

Page 5: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Agenda�

•  Out-of-MemoryExcep3oninBrowser•  FromOut-of-MemorytoRCE•  FromOut-of-MemorytoASLRbypass•  Conclusion

Page 6: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

OutofMemoryExcep3oninWebBrower

Page 7: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

OutofMemoryExcep3on �“Run%meexcep%onwhenthereisnosufficientmemory.” �

Page 8: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

BrowserOOMExample1�•  IE8CA_rArrayUseAaerFree(cve-2014-1753)•  Foundbyfuzzing

function f() { var size = 0x8000000; var s = "AAAA"; while (s.length < (size - 2)/2) s += s;

var x = document.createElement("frame"); x.setAttribute("prop2", s.substring(0, (size - 2)/2)); var node = document.body.appendChild(x);

for ( var y = 0; y < 20; ++ y ) { var z = node.cloneNode(); document.body.appendChild(z); }

}

Page 9: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

CloneNode �

Clonea_ributesOnebyone �

CreateanewA_ributesArray�

CopyA9ributeFail?�

FreeA_ributesArray�

AccessA_ributesArray(UAF) �

Ifthea9ributetocopyisaverylargestring,itcancauseanOut-of-MemorywhencloneThea9ribute.FinallytrigtheuseaHerfree.�

Page 10: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

BrowserOOMExample2�•  IEJscirptJSON.parseOOMMemoryCorrup3on �

var chunksize = 0x2000000; var json = '[' for ( var i = 0; i < chunksize/0x10; ++ i ) json += '1,' json += '1]'; var arr = new Array(); try {

for ( var i = 0; i < 0x1000; ++ i ) arr.push(json.substr(0, (chunksize-2)/2));

} catch (e) {} // Force IE into low-memory state by allocating large amount of memory

while (true) { JSON.parse(json); } �

Page 11: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

jscript!JSONParser::ParseObject+0x3fb: 65b4e9da mov eax,dword ptr [esi+14h] // length of the json array 65b4e9dd mov dword ptr [esp+14h],eax 65b4e9e1 shl eax,4 // alloc size = arr_length * 0x10   65b4e9e4 push eax 65b4e9e5 mov dword ptr [esp+20h],eax 65b4e9e9 call dword ptr [jscript!_imp__malloc (65b740fc)] // malloc can fail if there is no sufficient memory // malloc fail is not checked and will directly copy content to address [NULL + arr_size] 65b4ea2fa5movsdwordptres:[edi],dwordptr[esi]es:002b:00777fc0=????????ds:002b:03eb8398=00000003 � �

Page 12: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

OOMBugs–DifferentTypes �

•  Handled/NotHandled•  Controllable/Uncontrollable•  32-bits/64-bits•  Con3nuable/NotCon3nuable

Page 13: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Handled/NotHandled �•  HandledOOM– Developerisawareofpoten3alOOMinthecode–  Butfailedtohandleitcorrectly(e.g.theIECA_rArrayUAFcase)

•  NothandledOOM– Developerhasnoideaaboutthepoten3alOOMinthecode(e.g.theJSONcase)

–  Cancauseunexpectedexecu3onpathchange(earlyreturn,excep3on),whichcancauseexploitablecondi3on

Page 14: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Controllable/Uncontrollable

•  Controllable– WecantrigtheOOMexcep3onreliably,atany3mewewant•  Controllablelargealloca3on•  Controllablelow-memorystate

•  Uncontrollable– Occursrandomly,notcontrolledbyus

•  Smallalloca3ons•  Uncontrollablelow-memorystate

Page 15: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

32-bits/64-bits �

•  Usually,it’seasiertofindreliableOOMin32-bitstargetsthan64-bits

•  Becauseit’seasiertoforcetheprocessintoalow-memorystatein32-bitstarget– Bybruteforcealloca3ons

Page 16: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Con3nuable/NotCon3nuable�•  Con3nuable–  Programcancon3nuetoexecuteaaertheOOM–  Exploitpossible

•  NotCon3nuable–  Programcannotcon3nuetoexecuteaaerOOM

•  Crashimmediatelyduetonon-exploitablememorycorrup3on(e.g.nullpointerdeference)

•  Crashac3velyforalloca3onsthatcannotfail•  Browserhasamemorylimita3on,andwillcrashifmemoryexceedsthelimita3on

–  Notexploitable,onlyDDOSL �

Page 17: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Find/Focusoncontrollableandcon,nuableOOMexcep3onsonly�

Forbughunters:�

Page 18: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

FindOOMBugs �

•  NormalFuzz– Fuzzwithrandomvaluessome3mestrigsOOM

•  Fuzzinlowmemorystate– ToolssuchasApplica3onVerifier– Hookalloca3onAPIs– Somebrowsershastestinterfaceforout-of-mmemorysimula3on(e.g.FireFox)

•  Codeaudi3ng�

Page 19: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

FromOut-of-MemorytoRemoteCodeExecu3on

Page 20: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

AJourneyWithOOMBugsinMicrosoaEdge�

•  FindcontrollableOOMinEdge•  Breakthetransac3onopera3onstomakeinconsistentarraystate

•  Achievememorycorrup3on•  Win �

Page 21: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

FindcontrollableOOMinEdge�

•  WeneedtofindOOMexcep3onswhichcouldbetriggedreliably

•  JavaScriptarraysegmentalloca3onisanicevector

Page 22: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ArraySegment�•  JavaScriptarrayinIE/Edge– Alinklistofarraysegments�

length �

head �

Array�HeadSegment�

lea�

length �

size�

next�

element[0]�

element[N]�

… �

Segment1�

lea�

length �

size�

next�

element[0]�

element[N]�

… �

SegmentN�… �

Page 23: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

vararr=newArray();arr[0]=1;arr[1]=2;arr[2000]=3;arr[5000]=4;

�Headsegment �arr�

le.=0length=2element[0]=1element[1]=2��

Segment1�

Segment2�

le.=2000length=1element[0]=3�

le.=5000length=1element[0]=4�

Page 24: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ArraySegment(.cont) �

•  JavaScriptarrayelementsarestoredinsegments– Whenalloca3nganarraysegment,italsoallocatesthememoryspaceforelementsinit

•  Whenaddanewelementintoarray,ifthereisnoexis3ngspaceforit,iteitherallocatesnewsegmentorenlargesexis3ngsegment�

Page 25: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ArraySegmentAlloca3onOOMin32-bitsEdge�

•  Whenalloca3ngarraysegment,ifthere’snosufficientmemory,anOOMexcep3onwillbethrown

Page 26: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

try{for(vari=0x10000000;i<0x18000000;++i)

a[i]=0x0d0d0d0d;}catch(e){}try{

while(true){arr_ab.push(newArrayBuffer(0x02c9dbec*4));//Step1:Make

browserintoalow-memorystatebyalloca,nglargememoy}

}catch(e){}try{

a.reverse();//Step2:Trigarraysegmentalloca,on tothrowOOMexcep,on

}catch(e){alert(e);} �

TrigOOMin32-bitsEdge-Example�

Page 27: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

TrigOOMin32-bitsEdge–Example(.cont) �

Page 28: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ArraySegmentAlloca3onOOMin64-bitsEdge�

•  Wearenotabletoforce64-bitsEdgeintoinsufficientmemorystate– Because64-bitsprocess’smemoryspaceislarge

•  Thereiss,llachancetotrigOOMexcep3onin64-bitsEdge–  Ifthereisanoverflowinalloca,onsize

Page 29: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

OOMWhenAllocateSizeOverflow�

Page 30: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

varaaa=newArray();for(vari=0;i<arrSize.length;++i){

aaa.unshia.apply(aaa,args);//Step1:Growarraysegmentsizeun,lnearlyoverflow

aaa[arrSize[i]-1]=1;} try{

aaa.unshia.apply(aaa,args);//Step2:Triganothersegmentsizegrowwherethesizewilloverflow}catch(e){//Error:OutofMemory}

TrigOOMin64-bitsEdge-Example�

Page 31: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

TrigOOMin64-bitsEdge–Example(.cont) �

Page 32: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

NowwehavecontrollableOOMinboth32/64-bitsEdge,what’sNext? �

Page 33: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ArrayTransac3onOpera3on �

•  Arraycontainssomeimportfields– Array:arraytype,length,head,cachedlast-usedsegment

–  Segment:lea,length,size,elements

•  Whenyouchangeoneofthefields,youmustalsochangesomeotherstokeepthearrayvalid–  E.g.WhenyouconvertanIntarraytoFloatarray,theintelementsinthesegmentsneedalsobechangedtofloats

Page 34: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ArrayTransac3onOpera3on(.cont) �

•  ManyJavaScriptarrayAPIswillmakechangetothearray– shia,unshia,splice,…– Thecorepartofsuchcoderequiresatomicityandconsistency

–  Justliketransac3onindatabase,sowecallthemarraytransac3onopera3ons

– Breakarraytransac3onopera3onscancausetrouble

Page 35: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ArrayTransac3onOpera3on-Example�

•  ConvertaNa3veIntarraytoNa3veFloatarray �

Foreachsegmentinarray:segment->ChangeElementsToFloat()

SetArrayType(NaDveFloatArray)�

Ifthecodereturnsunexpectedlyinthemiddleoftheitera%on,

youwillgetaNa%veIntArraywithsomeFloatsegments

Page 36: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

BreakArrayTransac3onOpera3on �

•  Callbackinthetransac3onopera3on– Commonpa_ernofEdgebugs

•  Excep3onthatbreakscodeflow– OutofMemoryExcep3onsJ

Page 37: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Let’sParty!�

Page 38: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.unshia�

nElemntsToUnshiG=NumberofElementstoUnshiGForeachsegmentinarray:

segment->leG+=nElemntsToUnshiG (1)SetUnshiGElementsToHeadSegment(); (2)Array->length+=nElemntsToUnshiG; (3)�

Transac3onOpera3onofArray.unshia�

Page 39: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

nElemntsToUnshiG=NumberofElementstoUnshiGForeachsegmentinarray:

segment->leG+=nElemntsToUnshiG (1)SetUnshiGElementsToHeadSegment(); (2)Array->length+=nElemntsToUnshiG; (3)�

Break�

Setelementstotheheadsegmentcancauserealloca%onoftheheadsegment,whichcanthrowOut-of-Memoryexcep%on�

Page 40: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.unshia�

•  BybreakingtheArray.unshiatransac3onopera3on– Wehaveaninconsistentarraythat:

array->lastSegment->lea+array->lastSegment->length

>array->length

– Whilethearraymanipula3ngcodeassumesthat:array->lastSegment->lea+array->lastSegment->length

<=array->length

Page 41: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.unshia�

•  CallArray.unshiaagainontheinconsistentarray,wecangetanarraythat:arr->lastSegment->length>arr->lastSegment->size

•  Anarraysegmentwhoselengthislargerthansizecancauseheapoverflowinmanyplaces– SuchasJavaScriptArray::DirectSetElementAt

Page 42: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.unshia�

•  Aheapoverflowinarraysegmentisquitesimpletoexploit

•  Justallocateanotherarraysegmentaaertheoverflowedsegment,thenwecanoverwritethelengthandsizefiledofnextsegment

lea� length � size�

Overflow �

0xffffffff� 0xffffffff�

OverflowedSegment �

NextSegment �

Page 43: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.unshia�

•  UsedtoexploitEdgeatPwn2Own2017•  FixedasCVE-2017-0238�

Demo �

Page 44: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:JavascriptNa3veIntArray::ToNa3veFloatArray�

•  Thisfunc3onconvertsanintarraytofloatarray�

Foreachsegmentinarray:seg->size>>=1 (1)if(seg->length>(seg->size>>=1)) seg=AllocateNewSegment (2) Seg->ChangeElementToFloat() (3)Adjust(seg->length) (4)

Transac3onOpera3onofJavascriptNa3veIntArray::ToNa3veFloatArray�

Page 45: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Foreachsegmentinarray:seg->size>>=1 (1)if(seg->length>(seg->size>>=1)) seg=AllocateNewSegment (2) Seg->ChangeElementToFloat() (3)Adjust(seg->length) (4)

Break�

AllocateanewarraysegmentcanthrowOut-of-Memoryexcep%on.Atthispoint,seg->sizehasbeendivededby2,whileseg->lengthremainsunchanged.�

Page 46: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

•  BybreakingtheToNa3veFloatArraytransac3onopera3on– WecanhaveanarraysegmentthatSeg->length>Seg->size

•  GetRCEexactlythesamewayasArray.unshia– OneofthebackupbugsforPwn2Own2017– Wepreparedseveralsimilarbugsasbackups(e.g.Array.splice)

RCECase:JavascriptNa3veIntArray::ToNa3veFloatArray�

Page 47: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

PatchTime–AprilFix�

•  MicrosoafixedourPwn2OwnbuginApril•  Thefixisali_lesurprise–  ItdoesnotfixtheOOMexcep3ons–  Insteadittriestobreaktheexploittechweused

•  Addedanewfunc3on“CheckLengthVsSize”•  Toavoidheapoverflowscausedby“segment->length>segment->size” �

Page 48: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

CheckLengthVsSize�Ifdetected“segment->length>segment->size”,crashtheprocessimmediately�

Page 49: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ProblemofTheAprilFix�

•  ItbreakssomeOOMexploitsinourhand•  Buttherootcauses3llnotfixed– Rootcause:OOMexcep3onbreaksarraytransac3onopera3on

•  AndthereareotherOOMvulnerabili3esthatdonotrequire“seg->length>seg->size”toexploit�

Page 50: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Let’sCon3nueParty�

OOMbugscans3llfightinthenext10months�

OOMバグはあと10ヶ月は戦える! �

Page 51: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.reverseSegmentUseAaerFree�

Reversethewholesegmentlist (1)Ifheadisleafsegment:

head=ReallocateNonLeafSegment (2)�

Transac3onOpera3onofArray.reverse�

Page 52: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

LeafSegment�

•  Leafsegment– Puredatasegment– NextSegmentwillNOTbescannedwhenGC

•  Nonleafsegment– NextSegmentwillbescannedwhenGC

NonLeaf � NonLeaf � Leaf �

Leaf � NonLeaf � NonLeaf �

ü�

X �Thelast2segmentswillnotbescannedbyGCandwillbefreedunexpectedly,causinguseaaerfree��

Page 53: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.reverseSegmentUseAaerFree�

NonLeaf �

Step1:Reversethesegmentlist�

Step2:Reallocateheadifit’sleafsegment�

NonLeaf � Leaf �

Leaf � NonLeaf � NonLeaf �

NonLeaf � NonLeaf � NonLeaf �

Break�

Reallocatenonleafsegmentmaycauseout-of-memoryexcep%on �

Page 54: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.reverseSegmentUseAaerFree�

•  BybreakingtheArray.reversetransac3onopera3on,wecanaccessanarraysegmentthathasalreadybefreed

•  Easytogetfullremotecodeexecu3on– Reusethefreedmemoryofthearraysegment– Getafakearraysegment(achieveOOMaccess,typeconfusion,…) �

Page 55: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.reverseSegmentUseAaerFree�

•  FixedasCVE-2017-8549inJuneCPU

•  Got$15,000fromedgebugbounty– ManythankstoMicrosoaJ �

Page 56: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:ConvertToVarArrayBufferOverflow�

•  JavascriptNa3veFloatArray::ConvertToVarArraybufferoverflow �

Foreachsegmentinarray:ifsegisleafsegment: seg=ReallocateNonLeafSegment()(1)

seg->size*=2 (2)seg>ChangeIntElementsToVar() (3)

Array->ChangeTypeToVarArray() (4)�

Page 57: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Seg->size*=2? �

•  In32-bitsedge,sizeof(Var)=4,sizeof(Float)=8•  Sowhenconver3ngfloatsegmenttovarsegment,wecandoublethecapacity(size)ofthesegment �

Float� Float�

var� var� var� var�

Page 58: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Foreachsegmentinarray:ifsegisleafsegment: seg=ReallocateNonLeafSegment()(1)

seg->size*=2 (2)seg>ChangeIntElementsToVar() (3)

Array->ChangeTypeToVarArray() (4)�

Break�

Reallocatenonleafsegmentmaycauseout-of-memoryExcep%on.Ifwebreakat(1)inthemiddleoftheitera%on,somesegments’sizewillalreadybedoubled,andthedoubledsizewillnotberestored. �

Page 59: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:ConvertToVarArrayTypeConfusion �

•  Bybreakingthetransac3onopera3oninJavascriptNa3veFloatArray::ConvertToVarArray– Wegetafloatarray,withsomedouble-sizedsegments

•  Wecandirectlyread/writeoutoftheboundsofthesegments– Findamonkeytofinishtheexploit�

Page 60: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

PatchTime(Again) �

•  FinallyMicrosoastartstofixtherootcause– Probablybecausewecon3nuestoreportOOMbugsaaerPwn2Own

•  Thefix– CrashtheprocesswhendetectedOOMexcep3onincertainfunc3ons

Page 61: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

AutoDisableInterrupt�•  Aclassforprotec3ngaregionofcode•  Crashestheprocessiftheprotectedcoderegionthrowsanyexcep3on

•  Solvedtherootcause– Addedtomanyimportfunc3onssuchasunshia,splice,arrayconversions,…

– Maybeforgetsomefunc3on?

Page 62: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.reverse(Again) �

•  AaertheAutoDisableInterruptpatch– Array.reverseisnotprotectedbyit

•  CVE-2017-8619fixedtheOOMsegmentUAFissuewereported

•  ThenwefoundanotherOOMissueinthesamefunc3on– CVE-2017-8753– TypeconfusioncausedbyinvalidlastUsedSegment

Page 63: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

lastUsedSegment�

•  JavaScriptarraywillcachethelastusedarraysegment,tospeeduparrayaccess

•  Sowhenasegmentisremovedfromthearray,thelastUsedSegmentmustalsogetupdated,otherwiseitwillcausetrouble�

Page 64: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

RCECase:Array.reverse(Again) �lastUsedSegment=head; (1)head=AllocateNewHead(); (2)Ifthelastsegmentisleaf:

ReallocateLastSegmentToNonLeaf();(3)lastUsedSegment=head; (4)�

Break�

Reallocatenonleafsegmentmaycauseout-of-memoryExcep%on.Ifwebreakat(3),thearraywillhavealastUsedSegmentpointstoaninvalidatedsegment �

Page 65: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ExploitanInvalidatedlastUsedSegment�

•  Specialthankstoourteammember@LiuLongforthemethodtoexploitsuchbugs

•  Exploitmethod– Changethetypeofthearray(e.g.IntArray->FloatArray)

– ThelastUsedSegmentwillnotgetupdatedwhenchangingarraytype

– ThenweaccesselmentinlastUsedSegment,wegettypeconfusion

Page 66: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

AndItCon3nuous… �

•  CVE-2017-8753fixedinSeptember•  EndofOOMexploitinedge?•  Let’scheckitoutJ•  Demo3me,maybe

Page 67: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

FromOut-of-MemorytoASLRBypass �

Page 68: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

ExhaustMemoryin64-bitsEdgeBrowser? �

•  Usuallyyouarenotabletodothis– Thebrowser(andthewholesystem)willgetsloworfreezebeforeyouusingupthememory

– Becauseyoucommi_edtoomuchmemory

•  Un3lwefindaninteres3ngfeaturein64-bitsbrowser �

Page 69: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

TheFastArrayBuffer��

•  In64-bitsedge,whenyouallocateanarraybufferwhosesizeislargerthan0x10000(64KB),itwillbea“fastarraybuffer”– ab=newArrayBuffer(0x10000);//createavirtualarraybuffer

•  Edgereserves0x100000000(4GB)bytesforeachfastarraybuffer �

Page 70: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

4GBforeachbuffer? �

Page 71: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

WhatDoesThatMean �

•  Whenweallocatea64KBfastarraybuffer,therealcommi_edmemoryis64KB

•  Butedgewillreserve4GBvirtualmemoryspaceforit

•  Sowecanoccupy4GBmemorybyjustcommi�ng64KBmemory

Page 72: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Commit64KB,reserve4GB�

Page 73: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

UserModeMemorySpacein64-bitsEdge�

•  Windows10uses48-bitsforusermodememory

•  Userheapaddresswillbealwayslessthan0x800000000000

•  Soweonlyneedtospraylessthan0x8000arraybufferstoexhaustusermodememoryspace�

Page 74: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

5LinestoExhaustMemoryin64-bitsEdge�

vararr=newArray(0x10000/2);try{ for(i=0;i<arr.length;i++) arr[i]=newArrayBuffer(0x10000);}catch(e){//outofmemoryexcep3on} �

Page 75: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

AttheEndofSpray�

rcx=0000000800000000 �rcx=0000000700000000 �rcx=0000000600000000 �rcx=0000000500000000 �rcx=0000000400000000 �rcx=0000000300000000 �rcx=0000000200000000 �rcx=0000000100000000 ��

Tooursurprise,whenwefinishedsprayingmostofthearraybuffers,itbeginstoallocatememoryatverypredictableaddresses�

Page 76: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

GetFixedContentatFixedAddress�

•  Aaerwefinishedthespray,weknowoneofthefastarraybufferswillbeallocatedatafixedaddress(e.g.0x200000000)

•  Ifwefreethatarraybuffer,andspraysomeinteres3ngobjects(e.g.JavaScriptarray),weknowtheseobjectswillbeallocatedatthatfixedaddress,thuswebypassedASLR

Page 77: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

0x10000000 �

0x20000000 �

0x30000000 �

… �

FastArrayBuffer�

FastArrayBuffer�

FastArrayBuffer�

FastArrayBuffer�

FastArrayBuffer�

0�

sprayobjects �

Page 78: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Demo �

Page 79: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Effect�

•  Wecanputcontrolledcontentatcontrolledaddressin64-bitsedge

•  Makesexploita3onofcertainbugseasier– Write-to-anyonce– Useaaerfree– Typeconfusion

Page 80: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Limita3on �

•  Ittakestoolongtofinishthespray– ~300secondsonmylaptop

•  Notsuitableforreala_ack•  Niceop3ontobeusedincontestssuchasPwn2OwnJ

Page 81: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

BeyondASLRBypass �

•  Aaerweexhaustedthe64-bitsmemoryspace,wecanmakecontrollableOOMjustlikein32-bitsprocess

•  OOMvulnerabili3esthatareonlyexploitablein32-bitsprocesscanbeexploitedin64-bitsnowifcombinedwiththisissue

Page 82: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Conclusion �

•  Out-of-Memoryexcep3onsinbrowsersareoaenignoredbydevelopers/bughunters

•  Itiss3llpossibletofindexploitableifwefocusoncontrollableonesinmodernbrowser

•  Wes3llneedtotakeOOMissuesseriously�

Page 83: Yuki chen from_out_of_memory_to_remote_code_execution_pac_sec2017_final

Thankyou!�


Recommended