Post on 23-May-2020
Don'tTrustYourEye:AppleGraphicsIsCompromised!LiangChen (@chenliang0817)MarcoGrassi (@marcograss)Qidan He (@flanker_hqd)
CanSecWest Vancouver2016
AboutUs
• LiangChen• SeniorSecurityResearcher@Tencent KEENSecurityLab• Mainfocus:Browserexploitation,OSX/iOSsandboxescape
• MarcoGrassi• SeniorSecurityResearcher@Tencent KEENSecurityLab• Mainfocus:VulnerabilityResearch,OSX/iOS,Android,Sandboxes
• Qidan He• SeniorSecurityResearcher@Tencent KEENSecurityLab• Mainfocus:Vulnerabilityauditing/fuzzing,OS
Tencent KEENSecurityLab
• PreviouslyknownasKeenTeam
• AllresearchersmovedtoTencent becauseofbusinessrequirement
• Newname:TencentKEENSecurityLab
• YesterdayourunionteamwithTencentPCManager(Tencent SecurityTeamSniper)won“MasterofPwn”inPwn2Own2016
Agenda
• Applegraphicsoverview
• Fuzzingstrategy
• Casestudy
• Summary
Applegraphicsoverview
Whyattackthegraphicdrivers
• Thispartofthegraphicstacksisreachablefromthebrowsersandboxandresidesinthekernel.• Achievingkernelcodeexecutionwillgiveusprettymuchunrestrictedaccesstothetargetmachine.• EspeciallytruenowthatOSXintroduced“SystemIntegrityProtection”,oftengaininguserspace rootisnottheendoftheexploitationkillchain,youhavetocompromisethekerneltodisable“SIP”.• CompromisingthekernelbeforewasanecessityonlyoniOS,nowit’sstartingtobecomemorerelevantalsoonOSX.
SafariWebProcess sandboxattacksurface
• Youcanfindthe”com.apple.WebProcess.sb”sandboxprofileandseewhatisreachable(andtheimported“system.sb”).• (allowiokit-open• (iokit-connection"IOAccelerator")• (iokit-user-client-class"IOAccelerationUserClient")• (iokit-user-client-class"IOSurfaceRootUserClient")
• iokit-connectionallowsthesandboxedprocesstoopenalltheuserclient underthetargetIOService(muchlessrestrictivethaniokit-user-client-class)
UserClients underIntelAccelerator
UserClient Name Type
IGAccelSurface 0
IGAccelGLContext 1
IGAccel2DContext 2
IOAccelDisplayPipeUserClient2 4
IGAccelSharedUserClient 5
IGAccelDevice 6
IOAccelMemoryInfoUserClient 7IGAccelCLContext 8IGAccelCommandQueue 9IGAccelVideoContext 0x100
UserClients underIntelAccelerator
• Eachuserclient hasaIOService pointstoIntelAccelerator object
• IntelAccelerator objectisglobalunique• Createduponbooting
• MostoperationontheIntelAccelerator requiresLock(otherwisevulnerabletoraceconditionattack)• Exceptforsomereadoperations
UserClient Interface
• ImplementedbydifferentKexts
• Forexample:IGAccelGLContext• Method0x200– 0x206
• ClassIGAccelGLContext inAppleIntelBDWGraphics• Method0x100– 0x105
• ClassIOAccelGLContext inIOAcceleratorFamily2• Method0x0– 0x7
• ClassIOAccelContxt2inIOAcceleratorFamily2
• Evenwithinmethodcalls,itschildclass’smethodcanbecalledbecauseofpolymorphism
• Anyproblems?• Problem1:Doesthedeveloper fullyunderstandwhattheirparent’simplementationis?• Problem2:Doesthemethod implementerknowwhichfunctioncallhim,whatcheckisperformed?• Ifnot,vulnerabilitiesareintroduced
IGAccelGLContext IOAccelGLContext2 IOAccelContext2
AppleIntelHD5000Graphics IOAcceleratorFamily2 IOAcceleratorFamily2
Fuzzingstrategy
PassiveFuzzing
• Loadsome2Dor3Dgame/App• Writeadylib tohookIOKit APIs:• IOConnectMapMemory/IOConnectUnmapMemory• IOConnectCallMethod/IOConnectCallScalarMethod
• Randomlychangethecontentoftheparameters• IanBeerfromGoogleProjectZerodidit2yearsago.• FoundseveralbugsinprocessingsidebandbuffersinGLContext/CLContext::submit_data_buffers
PassiveFuzzing– ProsandCons
• Pros:• Easytoimplement• Evenforrandomfuzzing,itiseffective
• Cons:• Hardtoreproducetheissue• Cannotcoveralltheinterface
Activefuzzing
• Bysendingrandomdatatoeachinterface
• Needquitesomereverseengineeringworktoconstraintheuserinput• Otherwisenoteffective
• Howtomakeitmoreeffective?
Activefuzzing– HowtomakemoreeffectiveTIPS1
• Idealtargetforfuzzing:IGAccelSurface• Nottoomuchparametercheckbeforeperformcomplicatedoperation• IsmajorlycalledbyWindowServer process:
• NotsupposetobefrequentlyusedbySafari/UserApps• ManysituationsarenotwellconsideredwhenbeingcalledfromSafari/UserAppsdirectly.
• Severalcrashesbyfuzzingwiththissingleuserclient.
Activefuzzing– HowtomakemoreeffectiveTIPS2
• UsesimilarapproachforIGAccelGLContextwillnotgenerateanycrashes,why?• Theuserclient isbettertested.• GLcontextisnot initializedbyjustcalling
IOServiceOpen• Wemustmakeitsm_context tonon-NULL
• Twoapproaches:• InitializetheGLcontextbyrunningsomehelloworld
OpenGLapps,thenfindthemach_port oftheopenedGLContext userclient
• CallIOConnectAddClient toaddaIGAccelSharedUserClient tothenewlycreatedIGAccelGLContext• Willsetthem_context field
Activefuzzing– HowtomakemoreeffectiveTIPS3
• Userclientsareinter-connected
• Forexample• IfaIGAccelSurface userclientiscreated,itwillbeaddedtoIntelAccelerator::IOAccelSurfaceList• EachIGAccelSurface hasauniquesurfaceID,therearesystemcreatedIGAccelSurface (withSurfaceID1,2,0xffffffe0)• UsercreatedIGAccelSurface rangesitssurfaceIDfrom0x3– 0xffffffff• CanbeobtainedbycallingIOAccelDevice2::get_surface_info tobruteforceenumeratetheIDs• TheseIDscanbeusedtofuzz interfacesinotheruserclients (suchasIOAccel2DContext2::set_surface)
• Creatingalotofuserclientswithsuchrulesbuilt,willincreasetheeffectivenessalot.
Hybridfuzzing– combineactiveandpassivefuzzing
• Usedylid hooktorecordtheIOConnect call
• Foreachcall,dumpthemappedmemory(forexample,memorytype0,1,2forIGAccelGLContext)
• Duringactivefuzzing,givepossibilitytousetherecordedparameter
• Gotseveralcrashes
CaseStudy
IOKit vulnerability:CVE-????-????
• RaceconditioninanexternalMethod inAppleIntelBDWGraphics.• AffectseveryrecentMacwithIntelBroadwell CPU/Graphics.• DiscoveredbycodeauditingwhenlookingforsandboxescapesintoIOKit UserClients reachablefromtheSafariWebProcess sandbox.• Unfortunatelyitgotpartiallypatched1-2weeksbeforepwn2own!LLL .Areplacementwasneeded.L• UnpatchedinOSX10.11.3,onlypartialfixin10.11.4beta6.• Reliablyexploitable.• Wrong/partialfixmistakeresponsiblydisclosedtoApple.
IOKit vulnerability:CVE-????-????
• IGAccelCLContext andIGAccelGLContext are2UserClientsthatcanbereachedfromtheWebProcess Safarisandbox.• ThelockingmechanismsintheseUserClients isnottoogood,somemethodsexpectsonlyawellbehavedsinglethreadedaccess.• Firstwetargetedunmap_user_memory
IOKit vulnerability:someunsafecode
Racecondition– Howtotriggerit?
1. OpenyourtargetUserClient (IGAccelCLContext)2. Callmap_user_memory toinsertoneelementintotheIGHashTable3. Callwith2racingthreadsunmap_user_memory.4. Repeat2and3untilyouareabletoexploittheracewindow.5. Doublefreeonfirsthand6. PROFIT!
Chanceofstableexploit?
• Theunmap raceisnotstable• Easytotriggernullpointerdereferenceifwe’reremoving*same*element• BoththreadspassesIGHashtable::contains• Onethreadremovesandwhenanotherdogets,NULLisreturned• Nocheckonreturnvalue
• Actuallyagoodnull-pointer-dereferencebug• ButcannotbypassSMAPandcannotusedasSandboxbypass
• Doublefreewindowissmall
Chanceofstableexploit?
• StructureofIGHashTable<unsignedlonglong,IGAccelMemoryMap>• Keyistheuserspace addressofpassedinmap_user_memory
• Whenmap_user_memory iscalled• ::containssearcheshashtable fordup
• Iteratethroughcorrespondingslot’shashlist anddomemcmp onkey• Ifnotfound,insertitandcreate/savereftoanIOAccelMemoryMap
• Whenunmap_user_memory iscalled• ::containssearchesagain• Iffound,call::removeandcallsavedIOAccelMemoryMap’s ptr’s releasevirtualfunction
IGHashTable structure
• struct IGVector• Int64currentSize• Int64capacity• Void*storage
• struct IGElement (orwhatevernameyourlike)• Vm_address_t address• IOAccelMemoryMap*memory• IGElement*next• IGElement*prevs
IGHashTable structure(cont.)
• struct IGHashTable::Slot• IGElement*elementHead• void*tail• Size_t linkedListSize
• Whenthehashtable isempty…init with16slots
IGHashTable insertion
• Whenmap_user_memory called• Retrieveshashindex usingpassedaddress• Ifslotalreadyoccupied
• AppendtotailoflinkedlistonSlot• When(totElemCnt – occupiedSlotCnt)/totElementCnt>0.51
• AndoccupiedSlotCnt/vecCapacity >26• Thehashtable slotswillbeexpanded*2
• Createnewslotvector, iteratealloldvaluesandaddintoit• Freeoldstorage(double freehere?)
IGHashTable examplefigure
• Whenelementisinserted• Slotislocatedusinghashfunction
IGHashTable examplefigure
• Whenelementisinsertedagain
IGHashTable examplefigure
• Whenelementisremoved• Locateslotusinghashindexfunction• Iterateallitemsonlist,compareforvalue(headQword)• Whenmatch,doremove
IGHashTable examplefigure
• Whenelementisremoved• Locateslotusinghashindexfunction• Iterateallitemsonlist,compareforvalue(headQword)• Whenmatch,doremove
Racetounlink
• Calltwothreadstocontinuouslyremovetwo*adjacent**different*elements• Iftheremovefinishednormally• Justtryagain,nothingbadwillhappened
• Iftheremovefinished*abnormally*• We’llhaveafreedkalloc.32elementonlist!
• Next->prev =prev;• *prev =next;(prev->next=next)
Racetounlink
Racetounlink
Racetounlink
Racetounlink(ifracefailed)
Racetounlink(ifracesuceed)
• Whenbeginslistis:• ele1->ele2->ele3->ele4
• ele2->prev =ele3• ele3->prev =ele4
• ele1->next=ele3• ele2->next=ele4
• Nowlistis(searchingusingnextptr):• ele1->ele3->ele4• Howeverele3isfreedactually!
Racetounlink(ifracesucceed)
TurningintoUAF
• Fillingfreedholesusingio_service_open_extended• Callunmap_user_memory withtailaddressaftereachracetodetect• Ifracefailed,nothinghappensaslistisintact• Ifracesucceeded,containsandgetwilluseourcorruptedelement!
• Traversethelistandtriggervirtualcall• Unmap_user_memory
Craftfreeelementonlist
Crashwith0x4141414141414141
Next:controlRAXthenSuccessfullyRIPcontrolRAXisnowaspray-friendlyaddress
SuccessfullyRIPcontrolRAXisnowaspray-friendlyreachableheapaddress
RIPcontrolistrivial!
Racecondition– thepartialfix
• ByreversingOSX10.11.4aroundbeta5wesadlynoticedthatAppleintroducedsomeadditionallocks.L
POC/EXPsoonavailableongithub
• https://github.com/flankerhqd/unmap_poc
Racecondition– thepartialfix
• UnfortunatelyforApple,thisfixisincompletein10.11.4betaX• Whosayswecanonlyraceunmap_user_memory?• This“add”operationinsidemap_user_memory isoutsideanylock!• Wecanracewith1thread unmap_user_memory andwithanothermap_user_memory forexample,tocorrupttheIGHashTable!
Turningitintoainfoleak
• Byracing::addand::remove,we’repossibletocraftadanglingelementconnectedby“prev”pointer.• AddOperation• cur->prev =*tail• Prev->next=cur• *tail=cur
• RemoveOperationontail• cur->prev->next=0• *tail=cur->prev
Turningitintoainfoleak
• Byracing::addand::remove,we’repossibletocraftadanglingelementconnectedby“prev”pointer.
Turningitintoainfoleak
• Byracing::addand::remove,we’repossibletocraftadanglingelementconnectedby“prev”pointer.
Turningitintoaninfoleak (CVE-2016-????)
• Thewindowissmallbutstillhassuccessrate• Roughlyafter10secswecangetapanic
• “Afreedzonehasbeenmodifiedatoffset0x10blabla….”(the“next”location)• POCwillbealsoavailableatflankerhqd/unmap_poc
• Wecangetaheapaddressifwecanfillinthefreedzonethenreadout• Usingopen_extendedpropertiesandreadoutproperties
• Ormore?Useimagination!
Turningitintoaninfoleak (CVE-2016-????)
• Thewindowissmallbutstillhassuccessrate• Roughlyafter10secswecangetapanic
• “Afreedzonehasbeenmodifiedatoffset0x10blabla….”(the“next”location)• POCwillbealsoavailableatflankerhqd/unmap_poc
• Wecangetaheapaddressifwecanfillinthefreedzone• Usingopen_extendedpropertiesandreadoutproperties
• Ormore?Useimagination!
kASLR infoleak:CVE-????-????
• OSXkernelimplementskernelAddressSpaceLayoutRandomization.• InordertodokernelROPforoursandboxescape,andbypassSMEP/SMAPmitigationswemustknowthekASLR slide.• Ainfoleak wasneeded!• FortunatelyIntelBDWgraphicdriverisverygenerous,andoffersalsoakASLR infoleak vulnerability!• Stillunpatchedin10.11.3and10.11.4betas,responsiblydisclosedtoApple.
kASLR infoleak:CVE-????-????
• ThistimewewilllookatanotherKEXTinBDWgraphicdriverstack:AppleIntelBDWGraphicsFramebuffer• ItaffectsthesameMacmodelsastheracediscussedbefore.• ThisparticularIOKit driverisleakinginformationinsidetheIOKitregistry,thatwillhelpustoguessthekASLR slide
• Thiscodesimplywillsetthe“fInterruptCallback”propertyinIOregistryasthePOINTERv3+3176.• ThisisnotaTEXTpointeraswewillsee,butthatallocationisdoneveryearlyinthebootprocess,thiswillallowustoguessthekASLR slideanywayevenwithoutanexactinformation.• ThisinformationcanbeleakedfromtheWebProcess Safarisandboxsoit’sperfecttohelpinakernelbasedsandboxescape.
kASLR infoleak:sometestsandexperiments
• Wewillretrievethe“fInterruptCallbacks”pointerseveraltimesafterreboot,inordertogetdifferentkernelrandomizationoffsets.• WewillretrievetherealkASLR slideeverytime,bydisablingSIPandrunningasrootaprogramthatleverages“kas_info”systemcall,thatallowsyoutogetthekASLR slideifyourunasrootandSIPisoff.
Testbed:
Focusontheredlinescolumns,thisisthe“band”ofinterestforkASLR slide,theotherpartsofthedifferenceIsirrelevanttoourpurposes.Asyoucanseewehaveonly3outcomesinthedifferencebetweentheleakandkASLR slide,0x9e7,0x9e8,0x9e9
kASLR infoleak:outcomes
• Withjustaquickanalysis,thankstothisinfoleak,wehaveimprovedourchancestopredictthekASLR slidefromaround1in256values(afullbyteofpossiblekASLR randomslides)tojust1in3.• Itcanbeprobablybeevenimprovedstatisticallysincethose3valuesseemstodon’thaveaequallydistributedprobability.
Summary
• Graphicdriversofferabigattacksurfacereachablefromthebrowsersandbox.• RaceconditionsinXNUareonlystartingtogetattentionbythesecuritycommunitynow.• OSXdeploysseveraleffectivemitigations (thinkaboutSMAP,notyetwidespreadonotherOses),butgoodexploitationtechniquesandgoodvulnerabilitiescanbypassthem.
Acknowledgments
• Qoobee• Wushi
Questions?
Twitter:@keen_lab