ios vulnerabilities technical details

Similar documents
Revisiting the Kernel Security Enhancements in ios 10 MOSEC Liang Tencent Keen Lab

Microsoft Office Protected-View Out-Of- Bound Array Access

CMPSC 497 Other Memory Vulnerabilities

KCon. Breaking ios Mitigation Jails to Achieve Your Own Private Jailbreak. Min(Spark) Alibaba Mobile Security

KeenLab ios Jailbreak Internals: Userland Read-Only Memory Can Be Dangerous

SA31675 / CVE

Play with FILE Structure Yet Another Binary Exploitation Technique. Abstract

Memory Corruption 101 From Primitives to Exploit

BLACKBERRY PWNAGE THE BLUEJAY STRIKES

Cling: A Memory Allocator to Mitigate Dangling Pointers. Periklis Akritidis

CSE 509: Computer Security

Identifying Memory Corruption Bugs with Compiler Instrumentations. 이병영 ( 조지아공과대학교

KeenLab ios Jailbreak Internals:

Defeat Exploit Mitigation Heap Attacks. compass-security.com 1

Heap Off by 1 Overflow Illustrated. Eric Conrad October 2007

Lecture 08 Control-flow Hijacking Defenses

WINDOWS 10 RS2/RS3 GDI DATA-ONLY EXPLOITATION TALES

Bypassing Windows heap protections

CSE 127 Computer Security

Core GraphicsMemory Corruption CVE PDF Indexed colorspace buffer overflow

CS 161 Computer Security

com_apple_avebridge::submi tdata NULL Dereference

Linux Kernel Futex Fun: Exploiting CVE Dougall Johnson

Jailbreaking. Apple Watch. Max Bazaliy. December 4-7, 2017

Beyond Stack Smashing: Recent Advances in Exploiting. Jonathan Pincus(MSR) and Brandon Baker (MS)

PRESENTED BY: SANTOSH SANGUMANI & SHARAN NARANG

Pangu 9 Internals. Tielei Wang and Hao Xu

Pointers II. Class 31

Attacking the XNU Kernel in El Capitan. Luca Todesco BlackHat EU 2015

CPSC 213, Summer 2017, Term 2 Midterm Exam Solution Date: July 27, 2017; Instructor: Anthony Estey

Other array problems. Integer overflow. Outline. Integer overflow example. Signed and unsigned

TI2725-C, C programming lab, course

Secure Coding Techniques

Verification & Validation of Open Source

INITIALISING POINTER VARIABLES; DYNAMIC VARIABLES; OPERATIONS ON POINTERS

System Assertions. Andreas Zeller

14 May 2012 Virtual Memory. Definition: A process is an instance of a running program

ISA564 SECURITY LAB. Code Injection Attacks

CS 261 Fall C Introduction. Variables, Memory Model, Pointers, and Debugging. Mike Lam, Professor

com_apple_avebridge::query Completion Invalid Read

Software Security II: Memory Errors - Attacks & Defenses

Bypassing Browser Memory Protections

Outline. Heap meta-data. Non-control data overwrite

Non-stack Based Exploitation of Buffer Overrun Vulnerabilities on Windows NT/2000/XP

MediaTek Log Filtering Driver Information Disclosure

CNIT 127: Exploit Development. Ch 1: Before you begin. Updated

(Early) Memory Corruption Attacks

ARM Angel SWI Instruction Usage

CS 161 Computer Security

Changelog. Corrections made in this version not in first posting: 1 April 2017: slide 13: a few more %c s would be needed to skip format string part

Dissecting a 17-year-old kernel bug

ios Kernel Heap Armageddon

DHCP is hard. Felix Wilhelm HITB Dubai 2018

Foundations of Network and Computer Security

Microsoft Office CTaskSymbol Use- After-Free Vulnerability

The Geometry of Innocent Flesh on the Bone

CS527 Software Security

About unchecked management SMM & UEFI. Vulnerability. Patch. Conclusion. Bruno Pujos. July 16, Bruno Pujos

UniSan: Proactive Kernel Memory Initialization to Eliminate Data Leakages

Preventing Use-after-free with Dangling Pointers Nullification

Sandwiches for everyone

Brave New 64-Bit World. An MWR InfoSecurity Whitepaper. 2 nd June Page 1 of 12 MWR InfoSecurity Brave New 64-Bit World

Machine Problem 1: A Simple Memory Allocator

RCU. ò Walk through two system calls in some detail. ò Open and read. ò Too much code to cover all FS system calls. ò 3 Cases for a dentry:

MWR InfoSecurity Security Advisory. Intersystems Caché CSP (Caché Server Pages) Stack Overflow. 17 th December 2009

Memory corruption vulnerability exposure can be mitigated through memory hardening practices

VFS, Continued. Don Porter CSE 506

CNIT 127: Exploit Development. Ch 18: Source Code Auditing. Updated

Heap Arrays and Linked Lists. Steven R. Bagley

C Introduction. Comparison w/ Java, Memory Model, and Pointers

CS 31: Intro to Systems Pointers and Memory. Kevin Webb Swarthmore College October 2, 2018

BUFFER OVERFLOW. Jo, Heeseung

Buffer Overflow. Jo, Heeseung

SafeDispatch Securing C++ Virtual Calls from Memory Corruption Attacks by Jang, Dongseok and Tatlock, Zachary and Lerner, Sorin

Carnegie Mellon. Cache Lab. Recitation 7: Oct 11 th, 2016

2 Sadeghi, Davi TU Darmstadt 2012 Secure, Trusted, and Trustworthy Computing Chapter 6: Runtime Attacks

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

C and C++ Secure Coding 4-day course. Syllabus

Outline. Format string attack layout. Null pointer dereference

typedef void (*type_fp)(void); int a(char *s) { type_fp hf = (type_fp)(&happy_function); char buf[16]; strncpy(buf, s, 18); (*hf)(); return 0; }

Computer Architecture Background

bytes per disk block (a block is usually called sector in the disk drive literature), sectors in each track, read/write heads, and cylinders (tracks).

CS 31: Intro to Systems Pointers and Memory. Martin Gagne Swarthmore College February 16, 2016

Linux Memory Layout. Lecture 6B Machine-Level Programming V: Miscellaneous Topics. Linux Memory Allocation. Text & Stack Example. Topics.

seven Virtual Memory Introduction

CSCI 237 Sample Final Exam

Lecture Embedded System Security A. R. Darmstadt, Runtime Attacks

CS140 Operating Systems Final December 12, 2007 OPEN BOOK, OPEN NOTES

ENEE 457: Computer Systems Security. Lecture 16 Buffer Overflow Attacks

Motivation was to facilitate development of systems software, especially OS development.

Use Dynamic Analysis Tools on Linux

Fastbin_dup into stack exploitation

Buffer-Overflow Attacks on the Stack

SA30285 / CVE

Microcontroller Systems. ELET 3232 Topic 8: Structures, Arrays, & Pointers

CS11001/CS11002 Programming and Data Structures (PDS) (Theory: 3-1-0) Allocating Space

Mitigating the unkn0wn When your SMB exploit fails. Nicolas Joly

lpengfei Ding & Chenfu Bao lsecurity Researcher & Baidu X-Lab lfocused on Mobile, IoT and Linux kernel security

In Java we have the keyword null, which is the value of an uninitialized reference type

CS 322 Operating Systems Practice Midterm Questions

Transcription:

ios vulnerabilities technical details CVE- 2017-6979 A race condition vulnerability in the IOSurface.kext driver allows an attacker to bypass the sanity checks for the creation of an IOSurface object. The function IOSurfaceRoot::createSurface is responsible for the creation of the IOSurface object. It receives an OSDictionary, which it forwards to the function IOSurface::init. IOSurface::init parses the properties and in case one of these are invalid (e.g, a width that exceeds 32 bits), returns 0, and the creation of the IOSurface is halted. The IOSurfaceRoot object must hold a lock while calling IOSurface::init because IOSurface::init adds the IOSurface object to the IOSurfaceRoot s list of surfaces. Figure 1 shows code that calls IOSurface::init: surface = (IOSurface*)OSMetaClass::allocClassWithName("IOSurface"); IORecursiveLockLock(surface_root->iosurface_array_lock); if (!surface ) IORecursiveLockUnlock(surface_root->iosurface_array_lock); return 0; init_res = IOSurface::init(surface, surface_root, task_owner, surface_data); IORecursiveLockUnlock(surface_root->iosurface_array_lock); /* < IOSurfaceRoot s surfaces list is unlocked and can be accessed by anyone. */ if (!(init_res & 1) ) IOSurface::release(surface); return 0; Figure 1 - Creation of an IOSurface object and handling a failure In case the IOSurface::init function fails, IORecursiveLockUnlock will be called. A bogus IOSurface object will still be in the system and in the IOSurfaceRoot s list of surfaces (thus accessible to everyone). At this particular moment, an attacker can increase the refcount of the IOSurface (creating, for instance, an IOSurfaceSendRight object attached to the surface) and prevent the bogus IOSurface object from being destroyed.

This leads to the creation and existence of an IOSurface in the kernel which the attacker controls its properties (IOSurface- >width = - 1 for example). Such an IOSurface object can be given to other mechanisms in the kernel which might rely on a valid width/height/one of the properties to work, thus causing heap overflows/other problems that might lead to an elevation of privileges of the attacker. CVE- 2017-6989 A vulnerability in the AppleAVE.kext kernel extension allows an attacker to drop the refcount of any IOSurface object in the kernel. Selector numbers 4 and 7 in the AppleAVE2UserClient interface (DriverPreInit and SetSessionSettings) receives multiple IOSurface IDs from the user. The supplied IDs are then given to the IOSurfaceRoot s function IOSurfaceRoot::lookup_surface (suggested name) that will either return NULL or the surface s kernel pointer. The result from IOSurfaceRoot::lookup_surface will be then further used by the kernel, unless the user supplied the kernel pointer himself. In that particular case, the kernel ignores the IOSurface ID supplied by the user (it will only validate that the ID is not 0) and will take the user-supplied pointer and use it as an IOSurface object. Figure 2 demonstrates how the kernel skips the call to IOSurfaceRoot::lookup_surface when a user-supplied kernel pointer exists: /* If an attacker supplies a pointer here, it will be used as a pointer to an IOSurface object */ if (!*(user_input + 0x2F) ) iosurface_object = get_iosurface(apple_ave_driver, user_supplied_surface_id, user_client->task_owner); *(user_input + 0x2F) = iosurface_object; Figure 2 - The kernel accepts a usermode- supplied kernel pointer Providing that the attacker did supply a valid IOSurface pointer, the refcount of that IOSurface object is not increased.

The kernel will later utilize this IOSurface object. Upon freeing resources from that AppleAVE object (by calling selector number 2 of AppleAVEUserClient), some of the refcounts of those IOSurface objects will be decreased. data_containing_user_supplied_iosurface_power = *(_QWORD *)(v8 + 0x5878); if ( data_containing_user_supplied_iosurface_power ) v10 = 0LL; v14 = *(_DWORD *)(data_containing_user_supplied_iosurface_power + 8); if (!v14 ) goto LABEL_65; v15 = 0LL; do mapped_user_data = get_kernel_address_of_mapped_surface_data(data_containing_user_supplied_iosur face_power, v15); v17 = *( int64 **)(mapped_user_data + 0x11D8); if ( v17 ) v10 = sub_fffffff00669e948(v9, v8, v17, 0); IOFree (*(_QWORD *)(mapped_user_data + 0x11D8), 0x28LL); *(_QWORD *)(mapped_user_data + 0x11D8) = 0LL; v15 = (unsigned int)(v15 + 1); data_containing_user_supplied_iosurface_power = *(_QWORD *)(v8 + 0x5878); while ( v14!= (_DWORD)v15 ); if ( data_containing_user_supplied_iosurface_power ) // This drops the refcount of the IOSurface LABEL_65: v18 = cleanup_stuff((_qword *)data_containing_user_supplied_iosurface_power); operator delete(v18); *(_QWORD *)(v8 + 0x5878) = 0LL; Figure 3 - cleanup_stuff drops the refcount of any chosen IOSurface object provided that the user knows the kernel address of the object. This allows an attacker to drop the refcount of any IOSurface he knows (or arbitrarily call any function with offset 0x78 from a vtable of an object).

CVE- 2017-6994 An information disclosure vulnerability in the AppleAVE.kext kernel extension allows an attacker to leak the kernel address of any IOSurface object in the system. Selector number 7 in the AppleAVE2UserClient interface (kaveuserclientdriverpreinit) receives multiple IOSurface IDs from the user. The supplied IDs are then given to the IOSurfaceRoot s function IOSurfaceRoot::lookup_surface (suggested name) that will either return NULL or the surface s kernel pointer. The following picture demonstrates one of the IDs being given and checked later for success or failure: params_set_buffer_surface = get_iosurface(user_client->provider, input_buffer[3], user_client->task_owner); *(input_buffer + 0x31) = params_set_buffer_surface; if(!params_set_buffer_surface ) printf("aveuc ERROR: in->parametersetsbuffer NULL.\n"; goto exit; Figure 4 - the kernel looks up the address of an IOSurface object by its ID which is supplied by the user Shortly afterwards, the function copies some of these kernel pointers back to the output buffer, which is then sent directly to user mode (with the kernel pointers included): *output_buffer = *(input_buffer + 0x31); Figure 5 - The kernel return the kernel pointer of a chosen IOSurface object This allows an attacker to retrieve the kernel pointer of any IOSurface object, ultimately helping to bypass PAN\kASLR.

CVE- 2017-6995 A type confusion vulnerability in the AppleAVE.kext kernel extension allows an attacker to send an arbitrary kernel pointer which will be used by the kernel as a pointer to a valid IOSurface object. Selector numbers 4 and 7 in the AppleAVE2UserClient interface (DriverPreInit and SetSessionSettings) receives multiple IOSurface IDs from the user. The supplied IDs are then given to the IOSurfaceRoot s function IOSurfaceRoot::lookup_surface (suggested name) that will either return NULL or the surface s kernel pointer. The result from IOSurfaceRoot::lookup_surface will be then further used by the kernel, unless the user supplied the kernel pointer himself. In that particular case, the kernel will simply ignore the IOSurface ID supplied by the user (it will only validate that the ID is not NULL) and will take the user-supplied pointer and use it as an IOSurface object. The snippet below shows how the kernel skips the call to IOSurfaceRoot::lookup_surface when a user-supplied kernel pointer exists: if(!*(input_buffer + 0x2F) ) frame_queue_buffer = get_iosurface(user_client->provider, user_controlled_surface_id, user_client->task_owner); *(input_buffer + 0x2F) = frame_queue_buffer; if(!frame_queue_buffer ) printf("aveuc ERROR: in->framequeuebuffer NULL.\n"); goto exit; Figure 6 - A user- supplied pointer is treated just as if it were a valid IOSurface kernel pointer The function will later use that pointer as an IOSurface object. This behavior happens a lot on both selectors 4 and 7. This allows an attacker to hijack the kernel execution and therefore execute code in the context of the kernel.

CVE- 2017-6996 An attacker can leak sensitive kernel memory. Selector numbers 4, 7 and 8 in the AppleAVE2UserClient interface (DriverPreInit, SetSessionSettings and ResetBetweenPasses) receives multiple IOSurface IDs from the user. Those selectors eventually lead to the same function (address 0xFFFFFFF006B91A98 on a compiled kernelcache on iphone 7, ios 10.3.1). This function maps the IOSurface s buffers to the kernel in the function CreateBufferFromIOSurface. From that mapping, a FrameInfo object is created. One of the parameters that is supplied by FrameInfo is InfoType. If the attacker supplies InfoType 0x4569, a pointer is taken from the backed IOSurface s buffer, which the user completely controls: // kernel_address is the backed-buffer of the IOSurface. // An attacker can completely control its content. some_pointer_we_control = *(_QWORD *)(iosurface_kernel_map + 0x11D8); // Allocation happens appropriately... unless an attacker supplies his own pointer. if ( some_pointer_we_control (some_pointer_we_control = IOMalloc(0x28LL) && (*(_QWORD *)(iosurface_kernel_map + 0x11D8) = some_pointer_we_control)!= 0LL) )... Figure 7 - A completely controlled user pointer is taken from the IOSurface mapped memory The offset 0x11D8 depends on the kernel version. The attacker s pointer is later passed to the function MapYUVInputFromCSID: // Our data is de-referenced, meaning we can actually put a valid pointer here v90 = MapYUVInputFromCSID( driver, frame_stuff, *(unsigned int8 ***)(iosurface_kernel_map + 0x11D8), v89, 0, ( int64)"inputyuv", *(_DWORD *)(iosurface_kernel_map + 0x14), (unsigned int8)frame_stuff->field_4a88); Figure 8 - The kernel takes a user- controlled pointer and transfers it to MapYUVInputFromCSID

The function then performs multiple operations on the attacker s pointer, leading both to a memory corruption and to information disclosure. controllable_pointer = ( int64 *)kernel_address_plus_0x11d8_dereferenced; The function allows the attacker to put a newly allocated 0x70 bytes block in any kernel-pointer: uninitialized_iosurfacebuffermgr = operator new(0x70ll); // This function initializes v19 and returns it. IOSurfaceBufferMgr = (unsigned int8 *)initialize_iosurfacebuffermgr( uninitialized_iosurfacebuffermgr, *(_QWORD *)&v15->mmu_manager, ( int64)v15); *controllable_pointer = ( int64)iosurfacebuffermgr; Figure 9 - The kernel puts in a user- controlled pointer, a kernel- allocated memory Because controllable_pointer might be a pointer to data that is controlled by an attacker, it is possible to have an arbitrary kernel read primitive here: The attacker can simply modify *controllable_pointer after the call to initialize_iosurfacebuffermgr and change it to an arbitrary address. The kernel will read from that address and put its content into the mapped (and user accessible) data: // Even though *controllable_pointer was set to the 0x70 bytes block address, // the attacker can modify *controllable_pointer because its content might be controllable by the attacker. // This leads to an arbitrary kernel read any_address_we_want = *controllable_pointer; controllable_pointer[1] = *(_QWORD *)(*controllable_pointer + 0x38); controllable_pointer[2] = *(_QWORD *)(any_address_we_want + 0x40); v26 = *(_QWORD *)(any_address_we_want + 0x50); controllable_pointer[3] = v26; Figure 10 - The kernel takes an address from a user- controlled pointer, reads from that address, and put its content back into the IOSurface buffer

CVE- 2017-6997 An attacker can free any pointer of size 0x28. Selector numbers 4, 7 and 8 in the AppleAVE2UserClient interface (DriverPreInit, SetSessionSettings and ResetBetweenPasses) receives multiple IOSurface IDs from the user. Those selectors eventually lead to the same function (address 0xFFFFFFF006B91A98 on a compiled kernelcache on iphone 7, ios 10.3.1). This function maps the IOSurface s buffers to the kernel in the function CreateBufferFromIOSurface. From that mapping, a FrameInfo object is created. One of the parameters that is supplied by FrameInfo is InfoType. If the attacker supplies InfoType 0x4569, a pointer is taken from the backed IOSurface s buffer, which the user completely controls. If the attacker supplies no pointer, the kernel allocates data and puts it in kernel_address + 0x11D8 (the offset 0x11D8 depends on the kernel version). // kernel_address is the backed-buffer of the IOSurface. // An attacker can completely control its content. some_pointer_we_control = *(_QWORD *)(iosurface_kernel_map + 0x11D8); // Allocation happens appropriately... unless an attacker supplies his own pointer. if ( some_pointer_we_control (some_pointer_we_control = IOMalloc(0x28LL) && (*(_QWORD *)(iosurface_kernel_map + 0x11D8) = some_pointer_we_control)!= 0LL) )... Figure 11 - The kernel takes an address from a user- controlled memory Later on, while in the InfoType 0x4569 handler, that pointer is freed even if the attacker supplied his own pointer: // We can free any 0x28 bytes block in the kernel IOFree(*(_QWORD *)(iosurface_kernel_map + 0x11D8), 0x28LL); Figure 12 - The kernel frees a user- controlled address This allows the attacker to free any pointer of size 0x28, causing a memory corruption or denial of service in case the attacker supplies a pointer which does not belong to the kalloc.40 zone.

CVE- 2017-6998 An attacker can hijack kernel code execution due to a type confusion Selector numbers 4, 7 and 8 in the AppleAVE2UserClient interface (DriverPreInit, SetSessionSettings and ResetBetweenPasses) receives multiple IOSurface IDs from the user. Those selectors eventually lead to the same function (address 0xFFFFFFF006B91A98 on a compiled kernelcache on iphone 7, ios 10.3.1). This function maps the IOSurface s buffers to the kernel in the function CreateBufferFromIOSurface. From that mapping, a FrameInfo object is created. One of the parameters that is supplied by FrameInfo is InfoType. If the attacker supplies InfoType 0x4569, a pointer is taken from the backed IOSurface s buffer, which the user completely controls. // kernel_address is the backed-buffer of the IOSurface. // An attacker can completely control its content. some_pointer_we_control = *(_QWORD *)(iosurface_kernel_map + 0x11D8); // Allocation happens appropriately... unless an attacker supplies his own pointer. if ( some_pointer_we_control (some_pointer_we_control = IOMalloc(0x28LL) && (*(_QWORD *)(iosurface_kernel_map + 0x11D8) = some_pointer_we_control)!= 0LL) )... Figure 13 - The kernel takes an address from a user- controlled memory The offset 0x11D8 depends on the kernel version (on iphone 7, ios 10.3.1 it is 0x16B0). The attacker s pointer is later passed to the function address 0xFFFFFFF006B8C50C (kernelcache on iphone 7, ios 10.3.1): X23 is the IOSurface's backed-memory so 0x16B0 is controlled by us FFFFFFF006B926EC LDR X2, [X23,#0x16B0] FFFFFFF006B926F0 MOV W3, #0 This is the AppleAVE2Driver instance FFFFFFF006B926F4 MOV X0, X20 A struct containing a lot of the information from our IOSurfacebacked memory FFFFFFF006B926F8 MOV X1, X19 FFFFFFF006B926FC BL unmap_surface_buffer Figure 14 - Usage of the user- controlled address

The function checks whether the first pointer within our controllable pointer is not NULL, and if so, it transfers the pointer to 0xFFFFFFF006B97C24 (iphone 7, ios 10.3.1): signed int64 fastcall unmap_surface_buffer( int64 driver, int64 frame_stuff, int64 *our_controllable_pointer, char a4) v4 = a4; v5 = our_controllable_pointer; v6 = frame_stuff; v7 = kioreturnerror; if ( our_controllable_pointer ) if ( *our_controllable_pointer ) if ( frame_stuff ) do_something_with_our_pointer_(*our_controllable_pointer); Figure 15 - Further usage of the user's controlled address 0xFFFFFFF006B97C24 is a very short function that takes our pointer, extracts another pointer from offset 0x58 and uses it as an object. It uses its vtable, which allows an attacker to hijack the kernel flow: int64 fastcall do_something_with_our_pointer_( int64 our_controllable_pointer) int64 v1; // x19@1 int64 result; // x0@1 v1 = our_controllable_pointer; result = *(_QWORD *)(our_controllable_pointer + 0x58); if ( result ) // Can easily be byassed if our_controllable_pointer + 0x10 is NULL sub_fffffff0066bf04c(result, 0LL); result = (*( int64 (**)(void))(**(_qword **)(v1 + 0x58) + 0x28LL))(); *(_QWORD *)(v1 + 0x58) = 0LL; return result; Figure 16 - A vtable is fetched from the user- controlled address, and a function is being called from that vtable

CVE- 2017-6999 A user-controlled pointer is zeroed. Selector numbers 4, 7 and 8 in the AppleAVE2UserClient interface (DriverPreInit, SetSessionSettings and ResetBetweenPasses) receives multiple IOSurface IDs from the user. Those selectors eventually lead to the same function (address 0xFFFFFFF006B91A98 on a compiled kernelcache on iphone 7, ios 10.3.1). This function maps the IOSurface s buffers to the kernel in the function CreateBufferFromIOSurface. From that mapping, a FrameInfo object is created. One of the parameters that is supplied by FrameInfo is InfoType. If the attacker supplies InfoType 0x4569, a pointer is taken from the backed IOSurface s buffer, which the user completely controls. If the pointer is not NULL, its first 0x28 bytes are zeroed. This can be seen here: if ( some_pointer_we_control (some_pointer_we_control = IOMalloca_67(0x28LL), (*(_QWORD *)(iosurface_kernel_map + 0x11D8) = some_pointer_we_control)!= 0LL) ) bzero(some_pointer_we_control, 0x28LL); Figure 17 - A user controlled address is being NULLed Afterwards, a pointer is taken from that buffer, which the user completely controls. If the pointer is not NULL, its first 0x28 bytes are zeroed. This allows an attacker to nullify the first 0x28 bytes of any kernel pointer.