Shooting the OS X El Capitan Kernel Like a Sniper Liang Chen @chenliang0817 Qidan He @flanker_hqd About us • LiangChen • SeniorSecurityResearcher • Mainfocus:browservulnerabilityresearch,OSXkernel,AndroidRoot • Qidan He • SeniorSecurityResearcher • Mainfocus: Sandboxescape,mobilesecurity,Kernelresearch • Tencent SecurityTeamSniper(KeenLab andPCManager)wonMaster ofPwn inthisyear’sPwn2Own Agenda • OS X kernel exploitation mitigation recap • New approach to exploit kernel under sandboxed process • Demo OS X kernel mitigation • kASLR • kslide isassigneduponbooting.(Kexts andkernelsharethesameslide) • DEP • Disallow kernel RWX • SMEP • Disallow kernel code execution from userland address space Mitigation introduced by El Capitan • SMAP • Disallow memory access from userland address space • Enabled only on supported CPU architecture • From unsupported architecture • Supported architecture Mitigation introduced by El Capitan • OOL leak mitigation 1: Structure change in vm_map_copy Before El Capitan Kdata pointer isgood candidateforAARwithoverflow vulnerability After El Capitan Kdata pointerisremoved Mitigation introduced by El Capitan • OOL leak mitigation 1: Structure change in vm_map_copy • StillabletoachievelimitedOOBread,byincreasingsizefield • “OSXkernelisasstrongasitsweakestpart”: http://powerofcommunity.net/poc2015/liang.pdf • “Free to other zone” approach by @qwertyoruiop: • “AttackingtheXNUKernelinElCapitan”:https://www.blackhat.com/docs/eu15/materials/eu-15-Todesco-Attacking-The-XNU-Kernal-In-El-Capitain.pdf Mitigation introduced by El Capitan • OOL leak mitigation 2 • Introduced in 10.11.1 • Changing size field can lead to panic when reading/receiving OOL data Mitigation introduced by El Capitan • OOL leak mitigation 2:What happened mach_msg_ool_descriptor_t vm_map_copy Tworedundant sizefields Mitigation introduced by El Capitan • OOL leak mitigation 2 • Checkmach_msg_ool_descriptor_t.size ==mach_msg_ool_descriptor_t.address.size Panicifsizemismatch Whatifcopy->sizeis modified inbetween? TOCTTOU?Ah! Mitigation introduced by El Capitan • OOL leak mitigation • Makegeneralinfoleakapproachharder • Stillvulnerable • TOCTTOUissueexists(Althoughverysmalltimewindow) • Otherapproaches • Effectivemitigation • Harderkernelexploitation • Evenforperfectoverflowvulnerability(length+contentbothcontrollable) OS X kernel exploitation requirement • Leakkslide • vm_map_copy followedbyvtable object- Mitigated • Leakaddresspointerofcontrollabledata • BypassSMAP/SMEP • NeededbybothROPapproachandAAR/AAWprimitiveapproach • mach_port_kobject – Mitigated • Evenworsethingis… • Weneedperfectoverflowbugtoachievethose • Manybugs/exploitationapproacharenotreachablefromremoteattack surface(Safaribrowser) How about non-perfect write? Even harder… Remind me the hard time of IE exploitation in 2012... Memory Spraying • Heap spraying concept on browsers • • • • Helpful to exploitation development (Extremely useful before we got info leak) Widely used on 32bit systems Effective when memory is larger than address space On 64bit systems, less effective Run the code three times: Result in: 256 *4G memory to reliably fill specific data at target address Memory Spraying in Kernel • OOL vm_map_copy is still good candidate for memory spraying • OOL data keeping in kernel before receiving • But… • OS X Kernel is 64bit • Address space larger than physical memory • Seems hard? Memory Spraying in Kernel • Question? • Is OS X Kernel address space really large (than physical address) ? • kalloc random? Memory Spraying in Kernel • Kernel/Kext textbase • • • • Fixedbase+kslide Kslide range:(0x00– 0xff)<<21,max0x1fe00000 Addresscoveragelessthan512MB+Kernel+Kext size Muchsmallerthanphysicalmemorysize • Kernel/Kext data base • Fixedbase+kslide • Muchsmallerthanphysicalmemorysize also Memory Spraying in Kernel • How about kalloc zone address • zone_map->hdr.links.start • Heavily dependent on kslide zone_map.hdr.start kslide zone_map.hdr.start - kslide 0xffffff803b1d4000 0x1c400000 0xffffff801edd4000 0xffffff802071e000 0x1800000 0xffffff801ef1e000 0xffffff80247cc000 0x6a00000 0xffffff801ddcc000 0xffffff803610c000 0x18200000 0xffffff801df0c000 • Not too far away from the end of kernel • Allocation starts from low to high Memory Spraying in Kernel • Conclusion • Spray with OOL approach • With more than 512 MB *2 • Reliable (Controllable data at fixed address) Memory Spraying in Kernel Memory Spraying in Kernel • Why spraying? • Agoodworkaroundtoleaksomekalloc-ed address • LocatekernelROPchaintobypassSMAP/SMEP,thankstoOOL’sspraying feature • Othergoodfeaturestohelpour“Sniper” • Snipermeansremotely(frombrowser),faraway(address),butreliable Case Study CVE-2016-1815 – ‘Blit’zard - our P2O bug • ThisbugliesinIOAcceleratorFamily • Avectorwritegoesout-of-boundundercertaincarefullyprepared situations(8IOkit calls)inanewlyallocatedkalloc.48block • FinallygoesintoIGVector::addleadtoOOBwrite 0x28 0x1 size IGV ector F ake IGV ector capa capa 48′ block storage deadbeefsize storage size F ake IGV ector capa controlled 48′ block storage • • • • rect_pair_t ispairoftworectangles,totally8floats,inrange[-0xffff,0xffff](hex) Overwritestartsatstorage+24,endsatstorage InIEEE.754representationthefloatisinrange[0x3f800000,0x477fff00], [0xbf800000, 0xc77fff00] Wewillnotdiscussaboutthedetailedreasonofthisvulnerability here Found a write-something vulnerability? • Writeanythinganywhere– pieceofcake • Write*more**restricted*somethinganywhere? • Whatifyoucanonlywriteeightfloatscontinuouslyinrange[-0xffff, 0xffff]? • Translatetorange • 0x3f8000003f800000- 0x477fff00477fff00 • 0xbf800000bf800000- 0xc77fff00 c77fff00 Challenges • HowtoturnitintoRIPcontrol? • Writewhere?Writewhat?Stability?MustSandboxreachable! • HowtodefeatkASLR? • Pwn theApplewithasinglebug? Hard, but not impossible! Challenge #1 • Overwritingvm_map_copy length? • Applefixedthatin10.11.1 • Stillhavewaystobypass... • Notapplicabletoourvulnerability • Why? • Adjacentwrite • Writevalueqwordnotgood • 0x3f....3f.... • 0xbf....bf.... • Overwritingsomeaddress? HIGH LOW bf ff 80 ff 00 ff 00 80 bf 81 80 ab 00 cd 00 ef 0xffffff80 81abcdef IOUserClient Object HIGH ff ff ff 80 bf 81 80 ab 00 cd 00 ef bf 80 00 00 LOW 0xffffff80 81abcdef IOUserClient Object RAXRSIcontrollable • Whynotoverwritevptr atheadofuserclients? • Highbytesare0xffffff7f,addresscontentnotcontrollable • ExceptRootDomainUserClient • Butsizetoosmall…problems? • N*PAGE_SIZEallocationsaremorereliableandpredictable • Speedissues • SpraySpeeddecreasesasuserclient countincreases • Why? • ChildIOUserClient needtolinktotheirparentIOService IORegistryEntry::attachToParent IORegistryEntry::attachToChild (childalreadycontainsrefsto parent,NoneedtocallattachToParent again `links`isOSArray arrayMember performslinear search Ohman…Totaltimecomplexityhere:O(N^2) setObject inmakeLinks Freeing,allocatingandcopying… TotalSprayTime 500 AverageSprayTime 450 40 400 35 350 30 300 25 250 20 200 15 150 10 100 5 50 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 (Xaxismultiplyby 0x500*5,yaxisinsecond) It’sin2016andwestillhaveaO(N^2)time complexityfunctioninthecoreofamodern operatingsystem… Hey man check your accelerator • NearlyallIOAcceleratorFamily2userclients havea`service`pointer associated • PointtoIntelAccelerator • Virtualfunctioncalls • Heaplocationstartswith0xffffff80yeah • Overwriteitandpointittocontrollablememory! • Wecannotdirectlycallthefake`service`’s virtualfunction • Headerofvm_map_copy cannotbecontrolled • Anindirectvirtualfunctioncallisneeded • Selector0x0(context_finish)isoursuperstar • Virtualfunctioninvokedonservice->mEventMachine Preparing memory • Spray0x50,000ool_msgs,pushingheapcovering0xffffff80bf800000 (B)withcontrolledcontent(ool) • kASLR willpushheaplocationuporpullheapdownateachboot • Thisisastablefixpoint addressreachableinspraying • Higheraddressesnotapplicable • freemiddlepartsofool,fillwithIGAccelVideoContext covering 0xffffff8062388000 (A) • PerformwriteatA- 4+0x528descending • CalleachIGAccelVideoContext’s externalMethod anddetect corruption (theoffsetwas0x1230in10.11.3,changedafterwards) Fortherecord • NowwehaveknownaddressAcoveredwithIGAccelVideoContext. • KnownaddressBcoveredwithvm_map_copy contentcontrolled. • Withtheseinmindsletsmovefurthertoinfoleak Selector0x100ofIGAccelVideoContext AppleIntelBDWGraphics::get_hw_steppings cometorescue! Leaking strategy • Bysprayingwecanensure0xf…62388000(A) (liesan IGAccelVideoContext • And0xf...Bf800000(B)liesanvm_map_copywithsize0x2000 • OverwritetheservicepointertoB,pointtocontrolledvm_map_copy filledwith0x4141414141414141 (at0x1288settoA- 0xD0) • Testfor0x41414141bycallingget_hw_steppings onsprayed userclients • Ifmatch,wegettheindexofuserclientbeingcorrupted • a2[4]returnsabyteatA! service field +0x528 IntelAccelerator … IGAccelVideoCont IGAccelVideoCont ext ext 0xff… 62388000 … vm_map_copy vm_map_copy 0xff… bf800000 KALLOC.8192 ZONE service field +0x528 IntelAccelerator … …vm_map_copy … IGAccelVideoCont IGAccelVideoCont ext ext … 0xff… 62388000 vm_map_copy vm_map_copy 0xff… bf800000 +0x528 IntelAccelerator … vm_map_copy … IGAccelVideoCont IGAccelVideoCont ext ext 0xff… 62388000 KALLOC.8192 ZONE … vm_map_copy vm_map_copy 0xff… bf800000 +0x528 IntelAccelerator … vm_map_copy … IGAccelVideoCont IGAccelVideoCont ext ext 0xff… 62388000 … vm_map_copy vm_map_copy 0xff… bf800000 +0x1288 +0x1140 bf800000 bf801000 vm_map_copy header niddle(filled 0x41414141) KALLOC.8192 ZONE filled with 0x41414141 Leaking strategy? • Wait…whatifthepredictaddressfallatthe1stpageinsteadof0th? • Middleofuserclients- 50%chance • Middleofvm_map_copy- 50%chance • Writetwicetoensure100%successrate • OOBwriteatAandA+0x1000 • A- 0xD0bothat0x1288and0x288 forvm_map_copy +0x1000lies0 +0x528 IntelAccelerator … vm_map_copy … IGAccelVideoCont IGAccelVideoCont ext ext 0xff… 62388000 … vm_map_copy vm_map_copy 0xff… bf800000 +0x1288 +0x1140 bf800000 bf801000 vm_map_copy header niddle(filled 0x41414141) KALLOC.8192 ZONE filled with 0x41414141 0xff… 62388000 +0x1528 IntelAccelerator … vm_map_copy … 0xff… 6238a000 0xff… bf800000 +0x528 IGAccelVideoCont IGAccelVideoCont ext ext … vm_map_copy vm_map_copy 0xff… 62389000 +0x140 +0x288 0xff… bf7ff000 +0x1140 +0x1288 0xff… bf800000 vm_map_copy header niddle(filled 0x41414141) KALLOC.8192 ZONE 0xff… bf801000 filled with 0x41414141 vm_map_copy 0xff… 62388000 +0x1528 IntelAccelerator … vm_map_copy … 0xff… 6238a000 0xff… bf800000 +0x528 IGAccelVideoCont IGAccelVideoCont ext ext … vm_map_copy vm_map_copy 0xff… 62389000 +0x140 +0x288 0xff… bf7ff000 +0x1140 +0x1288 0xff… bf800000 vm_map_copy header niddle(filled 0x41414141) KALLOC.8192 ZONE 0xff… bf801000 filled with 0x41414141 vm_map_copy Fill ool_msg with service offset point to 0xf… …N Trigger IOConnect Call redo with vptr value let N=N+1, free and refill ool_msgs 8 bytes all leaked? KEXT vptr leaked kernel offset leaked Leaked byte zero? Replace with …N +1000 Leaking strategy • WecanuseanadditionalreadtodetermineiftheaddressisatAor A+0x1000 • IfwetryAbutitsactuallyatA+0x1000,wewillreadbyteat+0x1000of IGAccelVideoContext,whichis0,thenwecantryagainwithA+0x1000toread thecorrectvalue • Freeandfillthevm_map_copy livingatBtoincrementthelocationto readby1byte • Freeandfillvm_map_copy ,modifiedwithleakedvptr toleakkernel sectionoffset,thuskslide • Betterway exists- exerciseforreadersJ Final workflow • Spray0x50000ool_msgs withdatasize0x2000(2GB),taintwith 0x41414141,writeAat0x1288and0x288offset • Freemiddlepartsofool_msgs,fillinIGAccelVideoContext • Triggeroob writeatA- 0x4+0x528andA-4+0x528+0x1000 • IterateallopenedIGAccelVideoContextuserclients,callget_hw_steppings andlookfor4141,adjust0x1288and0x288ifneeded • ChangetoA+0x1000if0got • Advancereadlocation1byteby1,readoutKEXTvtableaddressandthen kernaddressoffset • Refillool_msgsbundledwithROPchain,callcontext_finish • Pwn Conclusion • Wediscussedpreviousexploitationtechniquesandtheirexploitations • Wepresentanewgeneralizedexploitationtechniqueworkingeven onrestrictedOOBwriteabstractedfromour`blitzard`exploitation Credits • MarcoGrassi • Qoobee • Wushi • Windknown • qwertyoruiop • Ufotalent Demo&&Questions? • POCwillbeavailableathttps://github.com/flankerhqd/blitzard/ ina fewweeks • Wewilltalkaboutthe`blitzard`itselfinternalsatLasVegasBlackhat USA2016,seeyouthereJ