CVE-2016-1850
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.
OSX El Capitan - 10.11.4
https://developer.apple.com/scenekit/
7.4 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N/E:U
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: -> 0x10078dc5f <+33>: 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 SceneKit`daeElement::getID() const + 33
frame #2: 0x000000010041a578 SceneKit`C3DIO_COLLADA_CreateUniqueIDForEntityWithExtraString + 22
frame #3: 0x0000000100413ff0 SceneKit`C3DIO_COLLADA_ReadGeometry(domGeometry*, __C3DLibrary*, __CFArray*, __CFDictionary*,
__CFDictionary const*, bool) + 348
frame #4: 0x0000000100415173 SceneKit`C3DIO_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.
<node id="Box" name="Box">
<rotate sid="rotateZ">0 0 1 0</rotate>
<rotate sid="rotateY">0 1 0 0</rotate>
<rotate sid="rotateX">1 0 0 0</rotate>
<!-- pointLightShape1 is a light object not a geometry object thus has different properties causing the illegal access -->
<instance_geometry url="#pointLightShape1-lib"/>
<instance_light url="#ambientLight-lib"/>
</node>
```
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.
```
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
```
2016-05-16 - Vendor Disclosure
2016-07-18 - Patch released
Discovered by Tyler Bohan of Cisco Talos