Upload
liang-chen
View
1.876
Download
2
Embed Size (px)
Citation preview
SUBVERTINGAPPLEGRAPHICS:PRACTICALAPPROACHESTOREMOTELYGAININGROOT
LiangChen(@chenliang0817)Qidan He(@flanker_hqd)
Marco Grassi (@marcograss)Yubin Fu(@fuyubin1993)
Aboutus
• Tencent KEENSecurityLab (PreviouslyknownasKeenTeam)
• 8Pwn2Ownwinnersin3years• MobilePwn2Own2013iOS,Pwn2Own2014OSX,Pwn2Own2014Flash,Pwn2Own2015Flash,Pwn2Own2015AdobeReader,Pwn2Own2016Edge,Pwn2Own2016OSX*2
• Wepwn OSXtwiceinPwn2Own2016withrootprivilegeescalation
• KeenLab withTencentPCManager(Tencent SecurityTeamSniper)won“MasterofPwn”inPwn2Own2016
Agenda
• Apple GraphicsOverview
• Userland AttackSurface
• KernelAttackSurface
Apple GraphicsOverview
Applegraphicsarchitecture
SandboxedApp WindowServer Service
Userland
Kernelland
UserlandGraphics
IGAccelSurface IGAccelGLContext IGAccelVideoContext…
IOAcceleratorFamily2
Nvidia GraphicsImplementation
IntelGraphicsImplementation
Whygraphics?
• OnOSX,storedin/System/Library/Frameworks/We-bKit.framework/Versions/A/Resources/com.apple.WebProcess.sb
• OniOS,binaryfileembedinkernel:• Sandbox_toolkit:https://github.com/sektioneins/sandbox_toolkit
• What’s in sandbox profile:• File opration• IPC• IOKit• Sharedmem• Etc.
Graphiccomponentsallowedin Safari sandbox profile
• Userland:Com.apple.windowserver.active• Apple Graphics usermode daemon• Managewindow/shape/session/workspace, etc.• Running as _windowserver context
Graphiccomponentsallowedin Safari sandbox profile
• Kernel• (iokit-connection"IOAccelerator")• iokit-connectionallowsthesandboxedprocesstoopenalltheuserclientunderthetargetIOService(muchlessrestrictivethaniokit-user-client-class)
UserClient Name TypeIGAccelSurface 0IGAccelGLContext 1IGAccel2DContext 2IOAccelDisplayPipeUserClient2
4
IGAccelSharedUserClient 5IGAccelDevice 6IOAccelMemoryInfoUserClient
7
IGAccelCLContext 8IGAccelCommandQueue 9IGAccelVideoContext 0x100
Userland AttackSurface
MIG overview
• Apple’sIPCimplementation
mach_msg_header_tmsg
• msg isthekeytosendmessagetoanotherprocess
• Msgh_bits• Simplemessageif0x00xxxxxx• Complex(descriptor)messageif0x8xxxxxxx
Simple message + 3 types of descriptor
• Simple message• Easy to understand
• Port descriptor• Send a port to the remote process• Similar to DuplicateHandle inWindows (can be seen in Chrome sandbox)
• OOL descriptor• Send a pointerto the remote process
• OOL Port descriptor• Send a pointercontainingan array of ports to the remote process
WindowServer overview
• Two private framework:• CoreGraphics• QuartzCore
• Safari sandbox allows to open com.apple.windowserver.active service• Implemented by CoreGraphics framework• QuartzCore framework not allowed by Safari sandbox, but…
CoreGraphics API
• Client side API• Starts with CGSxxxx
• Service side API• Starts with __X
CoreGraphics API grouping
• Workspace• Window• Transitions• Session• Region• Surface• Notifications
• Hotkeys• Display• Cursor• Connection• CIFilter• Event Tap• Misc
Thinking as a hacker
• Before OS X Lion, no apple sandbox• But there is WindowServer• From OS X Lion, apple sandbox is introduced• What we can do to WindowServer service with sandbox by easythinking?• Movemouse position– Yes, by calling _XWarpCursorPosition• Click – Yes, by calling event tap APIs like __XPostFilteredEventTapDataSync
• WindowServerwill then call IOKit IOHIDFamily to handle the event• Set hotkey – Yes, by calling _XSetHotKey
Bypass sandbox
• Movemouse + click == bypass sandbox• Set hotkey == bypass sandbox• After Apple sandbox is introduced, whole windowserver.active API isallowed by safari, Apple might forget to enhancewindowserver?
Reality
• You are wrong, Apple is notthatbad• Movemouse – Still allowed• Click – checked, no way from sandbox• SetHotKey – checked, no way fromsandbox
How about Window related API• Why thinking about Window API• Easy to cause UAF issues (in MSWindows)
• Connection_holds_rights_on_windowcheck• Only the window creator holds thiswriter
• Some tricks to bypass this check inhistory• Many other API doesn’t have thischeck, worthwhile for furtherresearch (Fuzzing, code auditing)
Why windowserver?
• Running in root? No• Running in user account? No• It is running in _windowserver• _windowserver is nothing, nothing, nothing
_windowserver 1746.60.8691040067708??Ss 三07下午69:35.83/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/WindowServer -daemon
But,WindowServer is privilegechameleon!
CVE-2014-1314: Design issue
• Session related API• _XCreateSession
• Create a new login session
• Fork a new process
• By default is/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow
• But user can specify the customized loginpath by sending amach message
• The forked process will be setuid to thecurrent user’s context
• Wow, we bypassed sandbox and run a sub-process under user’s context, outsidesandbox!
CVE-2014-1314: the fix
• Deny allrequest from a sandboxed process to call _XCreateSession• Effective, no way to bypass• Sandbox_check everywhere,makesmetired…ItisobviousthatApplerealizeditisdangerousinCoreGraphics
QuartzCore – The hidden interface
• What is QuartzCore?• Also knownas CoreAnimation• Morecomplexgraphicsoperation
• Animation• Multi-layer handling
• But… Safari sandbox doesn’t allow open com.apple.CARenderServer• Challenge? Sandbox doesn’t allow == we cannot open?
• If you think yes, you stop here• If you think no andmake it open, then you own a new territory.
• Chrome JS renderer cannot open any file, but in fact it can do operation incache folder, why?• Duplicatea handle !
QuartzCore – The hidden interface
• Another way is: a port descriptor message!• Yes, that is CGSCreateLayerContext• It sends a mach_msg to WindowServer• __XCreateLayerContext handles the request inWindowServer• Open a port of com.apple.CARenderServer• Send a replymessage with a port descriptor toclient
• Yay, we got the QuartzCore - Running at aseparate and new thread in WindowServer
Sandboxed process calls CGSCreateLayerContext
WindowServer server creates QuartzCore Client Port
Send the message back with port descriptor
Sandboxed process obtains the Port
QuartzCore – a new territory
• No sandbox check• Nothing…• 3 minutes code auditing, I find something…
CVE-????-???? Logic issue
• In _XSetMessageFile• Can specify arbitrary file path• And append content to that file• Content cannot be controlled• No use?
Chameleon – Now I want you to be root!
CVE-2016-1804 :UAFinmulti-touch (Pwnie 2016Nomination)
• Misc APIinCoreGraphics:_XSetGlobalForceConfig• Introducedforforcetouchpurpose• NewlyintroducedAPIiseasiertocauseproblem
• In_mthid_unserializeGestureConfiguration itcalledCFRelease tofreetheCFData
• Afterthat,theCFData isfreedagain• Doublefree
Exploitable?
• Problemstobesolved• FillinthecontrollabledatabetweentwoFREEs
• Especiallythefirst8bytesoftheCFData• Heapsprayingin64bitprocess/infoleak
• First8bytespointingtotheusercontrollabledata(vtable likeobject)• ASLR• ROP
Exploitation of CVE-2016-1804:Fillinthedata
• Lookslikehard• Twofreestooclose• Nowaytofillinbetweenthetwofreesinthesamethread
• Racecondition?• AllCoreGraphics serverAPIrunsinaserverloopatasinglethread(Gatedandqueued)• Whathappenedifracefailed?(Crash?Ofcourse!Ofcourse!Areyousure)
• Giveup?(Yes,wegiveupthisvulnerabilityforquitesomedays)
Aninterestingandlegacydoublefreeproblem• If this is the case
• Result is:
• time window too small, crashed in case of race failure
• If the case is like this
• No crash!• First 8 bytes of CFData unchanged• Windows LFH like
• Means we can try again and again until successful
• CoreGraphics server APIs are all processed in a single thread…• Any other way
QuartzCore - Thehiddeninterface
• Yes,weneedhiddeninterface’shelp• Thatis,QuartzCore• QuartzCore serverAPIsaresingledthreadedalsobutitisaseparatethreadagainstCoreGraphics
Thread1: CoreGraphics Thread2:QuartzCore
First Free
Double Free
Allocate memory with same size
Fill
Nextquestion?WhatserverAPIsyouchoosetofillindata
• APIsmustmeetthefollowingcriteria:• Createsomestructurethatsizeis0x30(sameasCFData)• Everybyteofthe0x30structurecanbecontrolled(Oratleastthefirst8byte)
• Whatkindofmessageyouchoose?• Simplemessage?Ofcoursenot,atleastthefirst8bytecannotbecontrolledfully.• Portdescriptor?Ofcoursenot.• OOLdescriptor?Yes,becauseitallowsspecifyingapointertoabufferandpasstotheremoteprocess.
Badnewsoncemore• HowmanyAPIsinQuartzCore acceptsOOLdescriptor?• Onlyone…• Thatis_XRegisterClientOptions(Itaccepts3portdescriptorfollowedbyanOOLdescriptor)
What’sin_XRegisterClientOptions
• AcceptaserializedPropertyList(SameconceptasListvsJSON)• WhatisCFPropertyList?
• CheckwhatApplesays• CanbeCFData,CFString,CFArray,CFDictionary,CFDate,CFBoolean,andCFNumber
• Whichonewechoose?• OfcourseCFDictionary,becausethisAPIonlyacceptsCFDictionary asvaliddata• SoCFArray alsogood
Again,whatstructuretofillin
• Firstthinking• UseCFDictionary andputmanyCFData/CFString intotheCFDictionary(BecauseyoucancontrolcontentofCFData/CFString)• Badnews:CFData notgoodbecauseitselfis0x30inlength,thefirst8bytesstruct CFData itselfisnotcontrollable,butonlyitscontent.Reducethereliabilitybyhalf• Worsenews:OnlyCFMutableDataandCFMutableStringhaveseparatecontrolledbuffer. Deserialized CFxxxx are not mutable, which the controlleddata is inlined… (Except for large data, but those are not good to fill in 0x30data)
Our last hope
• Rely on CFPropertyListCreateWithData• Cannot rely on CFData/CFString• What if the CFPropertyListCreateWithDatacreates some internal struct and free it• Also useful?
• Ok, let’s focus onCFPropertyListCreateWithDataimplementation• Wow, it is open sourced!
What is CFPropertyListCreateWithData
• Deserialization logic• Parse serialized buffer data andtransform to basic CFxxxx structures• A complicated implementationwithrecursive functions• _CFPropertyListCreateWithData ->__CFTryParseBinaryPlist ->__CFBinaryPlistCreateObjectFiltered
• CFBinaryPlistCreateObjectFiltered• Tokenparsing
Oh,Unicodesavestheworldagain!• CasekCFBinaryPlistMarkerUnicode16String
• Atempbufferisallocatedandfreedafterprocessing
Allocatethebuffer,sizeusercontrolled
Copytheusercontrolleddatatothebuffer
Freethebuffer
Exploitation of CVE-2016-1804:Fillinthedata
• Wrapup:• Createthread1,triggeringthevulnerabilityagainandagain• Createthread2,sendarequestto_XRegisterClientOptions• WithaCFDictionary/CFArray full ofcontrolled UnicodeCFString
• CFStringCreateWithCharacters createsUnicode16CFString
Exploitation of CVE-2016-1804:Fillinthedata
Exploitation of CVE-2016-1804:Heapspray
• Asimpletest
• Runit3times
• The5th byteisrandom..• Itmeansyouneed256*4Gforreliableheapspray• Bad…
Exploitation of CVE-2016-1804:Heapspray
• Anothertest
• Runit3times
• 5th bytealways0x1• Sprayingwillbeveryreliable
Exploitation of CVE-2016-1804:Heapspray
• Strategy is different• Need persistent in memory• Need to allocate large block of memory (Memory is less randomized)• Both CoreGraphics API and QuartzCore API are good candidate
• Something is same• Need to pick up a OOL descriptormessage
Exploitation of CVE-2016-1804:Heapspray
• CGXSetConnectionProperty is agood candidate• Get the CFDictionary object fromglobal, if not exist then create• Set the key/value pair according touser’s input• Can set the valuemany times bysendingmultiplemessages wherekeys are different
Exploitation of CVE-2016-1804: ASLR / Codeexecution• ASLR is easy as it shares the same base address with Safari webkit• Code execution:• http://phrack.org/issues/66/4.html• ROP
Exploitation of CVE-2016-1804: Root?
• Wait wait, we got only _windowserver context?• Really? Nono• We can setuid to current user as we get codeexecution, just similar as CVE-2016-1314• Why not setuid and setgid to 0? Crazy! Let‘stry…• Successful…• Why?
• _windowserver isprocesseuid,uid isstillroot!• Three bugs , three different privilegeobtained…So I call it Chameleon.
Demo
KernelAttackSurface
TheIOAccelSurface Family
• IOAccelSurface familyplaysanimportantroleinApple'sGraphicsDriverSystem• HowevertheinterfacewasoriginallydesignedforWindowServer usesolelyandvulnerabilitiesareintroducedwhennormalprocessescancallintothisinterface• CVE-2016-1815– `Blitzard`ourp2obug
KeyFunctions
• Set_id_mode• Thefunctionisresponsibleininitializationofthesurface.Bitwised presentationtypeflagsarespecified,buffersareallocatedandframebuffers connectedwiththissurfacearereserved.Thisinterfacemustbecalledpriortoallothersurfaceinterfacestoensurethissurfaceisvalidtobeworkedon.
• surface_control• Basicattributesforthecurrentsurfacearespecifiedviathisfunction,i.e.theflushingrectangleofcurrentsurface.
• surface_lock_options• Specifieslockoptionsthecurrentsurfacewhicharerequiredforfollowingoperations.Forexample,asurfacemustfirstbelockedbeforeit'ssubmittedforrendering.
• surface_flush• Exchangebackupandcurrentbuffer.Triplebufferingisenabledforcertainsurfaces.
Basicrenderunit
• ThebasicrepresentingregionunitinIOAccelerator subsystemisa8bytesrectanglestructurewithfieldsspecifiedinsurface_controlfunction.• int16x;• int16y;• int16w;• int16h;
TypicalGraphicsPipeline
set_scale andsubmit_swap
• Thesurface’sholdingdrawingregioncanbescaledandcombinedwiththeoriginalrectangleregiontoformarectanglepair,rect_pair_t• Thedrawingregionspecifiedinsurface_control isrepresentedinint16• Afterscalingit’srepresentedasIEEE.754float.
• Submit_swap submitsthesurfaceforrenderingpurposeanditwillfinallycallsintoblit opertion.
Blit_param_t
• Thepairandblit_param_t fromsubmit_swap willbepassedtoblit3d_submit_commands.• Thetwomostinterestingfieldsaretwoints atoffset0x14and0x34,whichisthecurrentandtarget(physical)surface’swidthandheight.
Blit3d_submit_commands
• Differentincomingsurfacearecroppedandresizedandmergedtomatchthedisplaycoordinatesystemwithcalculatedscalingfactor.• AfternormalizationtwoflushingrectanglesaresubmittedtoGPUviaBlitRectList
Overflowinblit3d_submit_commands
• TheOSXgraphicscoordinatesystemonlyacceptsrectanglesinrange[0,0,0x4000,0x4000]todrawonthephysicalscreen• Howeveralogicalsurfacecanholdrectangleofnegativecoordinateandlength.• representedbyasigned16bitinteger,translatestorange[-0x8000,0x7fff].
• Theblit functionneedstoscalethelogicalrectangletofititinthespecificrange.
blit3d_submit_commandscheckforcurrentsurface'swidthandtargetsurface'sheight.Ifeitherofthemislargerthan0x4000,Hustonweneedtoscaletherectanglesnow.
• avectorarrayisallocatedwithsizeheight/0x4000hopingtostorethescaledoutputvalidrectangles.
• Thetargetsurface'sheightalwayscomesfromafull-screenresource,i.e.thephysicalscreenresolution.Likefornon-retinaMacbook Air,theheightwillbe900.
• Asnonmachasaresolutionoflargerthan0x4000,thevectorarray'slengthisfixedto1.
RectangletransformationsonXaxis
Ibelieveyouwon’twanttoreadthis…
• Decompiledblit3d_submit_commandsfunction
RewrittenasIDAhex-rayscannotproperlyhandleSSEfloatingpointinstructions
RewrittenasIDAhex-rayscannotproperlyhandleSSEfloatingpointinstructions
OOBleadstheway
• Thecodeimplicitlyassumesthatifthewidthissmallerthan0x4000,theincomingsurface'sheightwillalsobesmallerthan0x4000,whichisthecaseforbenignclientlikeWindowServer,butnotsureforfunkyclients.• Bysupplyingasurfacewithrect2.xsettovaluelargerthan0x4000,LINE1willperformaccessatvector_array[1],whichdefinitelygoesout-of-boundwithfunctionIGVector::addcalledonthisoob location,
Determinethesurfaceattributes
• Bysupplyingsize(0x4141,0x4141,0xffff,0xffff)forsurfaceandcarefullyprepareothersurfaceoptions,wehittheabovecodepathwithrectangle(16705,16705,-1,-1).• Theseargumentswillleadtoout-of-boundaccessatvec[1]• Afterpreprocessing,therectangleistransformedtoy16705,x321,height-1,len -1,triggeringoneoob write• Thenbailoutinwhileconditioninnextloop
RevisittheIGVector
• struct IGVector{• int64currentSize;• int64capacity;• void*storage;
• }• Thevulnerableallocationofblit3d_submit_commandsallocationfallsatkalloc.48,whichiscrucialforournextHeapFengShui.
HeapFengshui inkalloc.48
• kalloc.48isazoneusedfrequentlyinKernelwithIOMachPort actingasthemostcommonlyseenobjectinthiszoneandwemustgetridofit• PreviousworkmainlycomesupwithopenServiceExtended andvm_map_copy topreparethekernelheap.• Howeverthesearenotsuitableforourexploitation
HeapFengshui inkalloc.48(cont.)
• ool_msg sprayhassmallheapside-effect• butvm_map_copy’s head0x18bytesisnotcontrollablewhileweneedcontrolof8bytesatthehead0x8position
• io_open_service_extended hasmassivesideeffectinkalloc.48zonebyproducinganIOMachPort ineveryopenedsprayingconnection• io_open_service_extendedhasthelimitationofsprayingatmost37items,constrainedbythemaximumpropertiescountperIOServiceConnection canhold• Themoreitemswecanfill,thelesssideeffectwewillneedtoconsider
IOCatalogueSendData
• TheaddDrivers functionsacceptsanOSArray withthefollowingeasy-to-meetconditions:• OSArray containsanOSDict• OSDict haskeyIOProviderClass• incomingOSDictmustnotbeexactlysameasanyotherpre-existsOSDict inCatalogue
IOCatalogueSendData (cont.)
• prepareoursprayedcontentinthearraypartastheXMLshows,andslightlychangesonecharatendofperspraytosatisfycondition3• Weonlyneedcontrolof+8-+16bytesregion
Finalsprayroutineinkalloc.48
• Spray0x8000combinationof1vm_map_copy and50IOCatalogueSendData contentofwhichtotallycontrollable(bothofsize0x30),pushingallocationstocontinuousstableregion• freevm_map_copys at1/3to2/3part,leavingholesinallocation• triggervulnerablefunction,vulnerableallocationwillfallinholewepreviouslyleft
Inanearly100%chancetheheapwilllayoutasthisfigureillustrated,whichexactlymatchwhatweexpected.Spraying50ormore0x30sizedcontrollablecontentinonerollcanreducethepossibilityofsomeotherirrelevant0x30contentsuchasIOMachPort toaccidentallybejustplacedafterfreeblockoccupiedin.
KALLOC.8192 ZONE
vm_map_copy header
+0x1140
niddle(filled 0x41414141) filled with 0x41414141
+0x1288
IGAccelVideoContext
IGAccelVideoContext vm_map_copy vm_map_copy…
0xff… 623880000xff… bf800000
IntelAccelerator …
+0x1528
vm_map_copy …
0xff… bf801000
0xff… 62389000
+0x528
+0x288
0xff… bf800000
vm_map_copy
0xff… bf7ff000
+0x140
0xff… 6238a000
Exploitation:nowwhat?
• Wehaveanarbitrary-write-wherebutourvaluewrittenisconstrained.• Forexamplewecanusethis4byteoverwritewithvalue“0xbf800000”todoapartialoverwriteofthelesssignificant4bytesofthe“service”pointerofaIOUserClient.• Thisnewoverwrittenpointerwillbe“0xffffff80bf800000”.• Wecontrolthisheaplocationat”0xffffff80bf800000”!
A000ADDE80FFFFFF 000080BF80FFFFFF
BEFOREOOBWRITE AFTEROOBWRITE
Exploitation:kASLR bypassturningthisintoainfoleak
• OnOSXthekernelisrandomized,weneedtobypasskASLR.• OurtargetIOUserclient isoftypeIGAccelVideoContext• Weoverwritethe“accelerator”fieldofthisuserclient (offset0x528),likeexplainedinthepreviousslidepointingittoourcontrolledlocation• WethenabusetheexternalmethodIGAccelVideoContext::get_hw_steppings toleak1bytetouserspace,toreadavtable 1byteatatime.• Withthevtable addresswefollowittoreadaTEXTaddress(OSObject::release)tofinallygetthekASLR slide,bypassingit.
Exploitation:kASLR bypassturningthisintoainfoleak (2)
IGAccelVideoContext::get_hw_steppings( __int64 this, _DWORD *a2) {…__int64 accelerator = *(this + 0x528); // accelerator is 0xffffff80bf800000...a2[3] = *(unsigned __int8 *)(*(_QWORD *)(accelerator + 0x1230) + D0); // this is returned to userspace!…}
Exploitation:1byteinfoleakmemorylayout
Exploitation:rebasingandROPChain
• NowwiththekASLR slidewecandynamicallyrebaseourROPChainthatweuseforkernelcodeexecution.• AttheendoftheROPchainwewillabusekern_return_tKUNCExecute(char executionPath[1024], int uid, int gid) tospawnaarbitraryexecutableasrootinuserspace,bypassingallthemitigations (SMEP/SMAP,SIP)• SpawnarootOSXCalculatorforteh lulz!MicrosoftWindowscalculatorssucks:D
Exploitation:gainingRIPcontrol
• ThelastmissingpieceofthepuzzleistogetRIPcontrolandexecuteourROPpayloadinkernelandgainkernelcodexec• WewillagainabuseaIGAccelVideoContext andhissuperclassIOAccelContext2.• Ifyourecallfromthepreviousslides,wecorruptedapointeratoffset0x528topointtoourcontrolledlocation.• Wechoosethentotargetanothermethod,named“context_finish”,whichwillmakeavirtualfunctioncallthatwecantotallycontrol.• RIPControlisachievedandwestartexecute
Exploitation:gainingRIPcontrol(2)
IOAccelContext2::context_finishpush rbpmov rbp, rsp…mov rbx, rdi //thismov rax, [rbx+528h] // rax is a location with controlled content…call qword ptr [rax+180h] // RIP control…
ExploitationYoucancheckmoredetailsoftheexploitationinourWhitePaperUnfortunatelyherewehavetimeandspaceconstraintsButnow..ACOOLDEMOJ!AninterestingfactisthatyoucannotpoparootCalc bysudoJIfyouseearootCalc onyoursystem,u’re doomedbykernelexploitL
Demo
Acknowledgements
• Wushi• Windknown• LucaTodesco• Ufotalent
Thank you!