us 16-subverting apple-graphics_practical_approaches_to_remotely_gaining_root_chen_he_grassi_fu

Post on 12-Apr-2017

1.874 Views

Category:

Internet

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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!

top related