Late in 2015 I was looking for a way to create an instance of an IOKit user client with a visible
NULL pointer dereference when I discovered something intriguing: the default implementation of
IOService::newUserClient checks the
IOUserClientClass property on the service when determining
what user client class to allocate. This caught my attention because IOKit provides an API to set
arbitrary properties on an
IOService from user space. If any
IOService allowed setting the
IOUserClientClass property, that would create an opportunity for kernel code execution.
I immediately started looking for
setProperty calls with attacker-controlled keys and values.
Amazingly, I found that
IOHIDevice would iterate the attacker-supplied properties dictionary and
indiscriminately add each key-value pair to its own set of properties. This post is about how I
leveraged this vulnerability to gain read/write access to physical memory from user space, and how
this awesome primitive can be used to get fully reliable kernel code execution.
I reported this issue to Apple in January of 2016, and it was assigned CVE-2016-1825. It was fixed in OS X El Capitan 10.11.5. A proof-of-concept exploit for this vulnerability (and the variant CVE-2016-7617) is available in my physmem repository on GitHub. This vulnerability is not present on iOS.