Talos Vulnerability Report

TALOS-2016-0183

Apple OS X Scene Kit DAE XML Code Execution Vulnerability

July 18, 2016
CVE Number

CVE-2016-1850

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: -> 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.

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

Credit

Discovered by Tyler Bohan of Cisco Talos