IORegistryIterator race condition vulnerability analysis and exploit-vulnerability warning-the black bar safety net

2016-03-10T00:00:00
ID MYHACK58:62201672411
Type myhack58
Reporter 佚名
Modified 2016-03-10T00:00:00

Description

Author: shrek_wzw@360NirvanTeam

0x00 description


CVE-2 0 1 5-7 0 8 4 is due to the IORegistryIterator the user does not consider the state of multiple threads simultaneously call the case, causing a Race Condition that can lead to arbitrary code execution. Vulnerability exists in MAP version 3 2 4 8. 2 0. 5 5 before the kernel, i.e. Mac OS X 10.11.2, iOS 9.2, and watchOS 2.1, the tvOS 9.1 before the system version. The official repair Bulletin<https://support.apple.com/en-us/HT205637>is.

0x01 vulnerability background


IORegistryIterator is used to MAP the kernel is used to traverse to access the IO Registry Entry of a class. In MAP version 3 2 4 8. 2 0. 5 5 before the kernel, i.e. Mac OS X 10.11.2, iOS 9.2, and watchOS 2.1, the tvOS 9.1 prior version of the system, in operation IORegistryIterator the lack of locking mechanism, a user mode process by multi-thread calls cause a Race Condition, and ultimately can achieve arbitrary code execution. This vulnerability is by Google Project Zero's Ian Beer reports, the CVE number CVE-2 0 1 5-7 0 8 4 in.

0x02 vulnerability analysis


Ian Beer<https://code.google.com/p/google-security-research/issues/detail?id=598>given a vulnerability description, as well as a lead to Double Free PoC code.

is_io_registry_iterator_exit_entry is IORegistryIteratorExitEntry corresponding to the kernel interface, it will call IORegistryIterator::exitEntry function.

|

1

2

3

4

5

6

7

8

9

|

/ Routine io_registry_iterator_exit /

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 );

}

---|---

.

1

2

3

4

5

6

7

8

9

1 0

1 1

1 2

1 3

1 4

|

bool IORegistryIterator::exitEntry( void )

{

IORegCursor * gone;

...

if( where != &start) {

gone = where; // Race Condition

where = gone->next;

IOFree( gone, sizeof(IORegCursor)); // gone may be released two times

return( true);

} else

return( false);

...

}

---|---

However, due to the lack of lock protection through a multi-thread calls IORegistryIteratorExitEntry, resulting in the gone points to the memory area to be released twice, causing a crash. A schematic diagram is as follows:

! p1

0x03 exploit


Due to Double Free easy to use, the Pangu Team in its blog post<http://blog.pangu.io/race_condition_bug_92/>proposed another idea, you can stable use Race Condition arbitrary code execution. Following this idea for the specific analysis, in the known Kernel Slide the case on Mac OS X 10.11 on the realization of mentioned rights.

1. Attack process

By observing the operation of the IORegistryIterator function enterEntry, and found that it contains the one-way linked list insert node operation, as follows:

1

2

3

4

5

6

7

8

9

1 0

1 1

1 2

1 3

1 4

1 5

|

void IORegistryIterator::enterEntry( const IORegistryPlane * enterPlane )

{

IORegCursor * prev;

prev = where;

where = (IORegCursor *) IOMalloc( sizeof(IORegCursor));

assert( where);

if( where) {

where->iter = 0;

where->next = prev; //linked list head insertion New the where node, where->next points to the old where

where->current = prev->current;

plane = enterPlane;

}

}

---|---

[1] [2] [3] [4] next