欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

CVE-2016-1825浅析:从用户态空间设置IOKit注册属性导致的越权读

来源: 作者: 时间:2019-02-24 19:29 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助

0x001 前言
CVE-2016-1825是IOHIDFamily.kext内核扩展内的一个洞,在OS X 10.11.5以前版本的系统都存在该漏洞,由于允许IOHIDevice重新设置IOUserClientClass属性,导致任意代码执行。

 
0x002 调试环境
虚拟机: OS X Yosemite 10.10.5 14F27
主机: macOS Mojave 10.14.2 18C54
内核调试环境的搭建可以参照这一文:
macOS内核提权:利用CVE-2016-1758获取kernel slide(Part1)
 
0x003 内核扩展源码分析
在开始分析之前,先来了解一些概念:
1.IOKit?
IOKit是用于设备驱动程序的框架和内核子系统,与IOKit的所有交互都以IOKit主端口开始,这是另一个特殊的机器端口,允许访问IOKit Registry。 IOKit Registry允许用户态程序查找可用的硬件,而设备驱动程序可以通过实现UserClient将接口暴露给用户空间。用户空间实际与IOKit驱动程序的UserClient交互的主要方式是通过io_connect_method,此方法由IOKitUser库函数IOConnectCallMethod封装。
2.IOKit Registry?
IOKit Registry实际上是一个驱动程序可以声明键值对的地方(其中键是一个字符串,其值是属于CoreFoundation的数据类型),驱动程序还可以指定其中一些键是可配置的,这意味着从用户空间可以使用IOKit Registry的API来设置新值。
获取macOS kext扩展源码
[传送门]
打开IOHIDSystem/IOHIDevice.cpp,找到IOHIDevice::setProperties、IOHIDevice::setParamProperties方法
// RY: Override IORegistryEntry::setProperties().  This will allow properties
// to be set per device, instead of globally via setParamProperties.
IOReturn IOHIDevice::setProperties( OSObject * properties )
{
    OSDictionary * propertyDict = OSDynamicCast(OSDictionary, properties);
    IOReturn       ret          = kIOReturnBadArgument;
    if ( propertyDict ) {
        if (propertyDict->setOptions(0, 0) & OSDictionary::kImmutable) {
            OSDictionary * temp = propertyDict;
            propertyDict = OSDynamicCast(OSDictionary, temp->copyCollection());
        }
        else {
            propertyDict->retain();
        }
        propertyDict->setObject(kIOHIDDeviceParametersKey, kOSBooleanTrue);
        ret = setParamProperties( propertyDict );
        propertyDict->removeObject(kIOHIDDeviceParametersKey);
        propertyDict->release();
    }
    return ret;
}
IOReturn IOHIDevice::setParamProperties( OSDictionary * dict )
{
    IOHIDEventService * eventService = NULL;
    if ( dict->getObject(kIOHIDEventServicePropertiesKey) == NULL ) {
        IOService * service = getProvider();
        if ( service )
            eventService = OSDynamicCast(IOHIDEventService, service);
    }
    if ( dict->getObject(kIOHIDDeviceParametersKey) == kOSBooleanTrue ) {
        OSDictionary * deviceParameters = OSDynamicCast(OSDictionary, copyProperty(kIOHIDParametersKey));
        if ( !deviceParameters ) {
            deviceParameters = OSDictionary::withCapacity(4);
        }
        else {
            if (deviceParameters->setOptions(0, 0) & OSDictionary::kImmutable) {
                OSDictionary * temp = deviceParameters;
                deviceParameters = OSDynamicCast(OSDictionary, temp->copyCollection());
                temp->release();
            }
            else {
                // do nothing
            }
        }

[1] [2] [3] [4] [5]  下一页

0x001 前言
CVE-2016-1825是IOHIDFamily.kext内核扩展内的一个洞,在OS X 10.11.5以前版本的系统都存在该漏洞,由于允许IOHIDevice重新设置IOUserClientClass属性,导致任意代码执行。

 
0x002 调试环境
虚拟机: OS X Yosemite 10.10.5 14F27
主机: macOS Mojave 10.14.2 18C54
内核调试环境的搭建可以参照这一文:
macOS内核提权:利用CVE-2016-1758获取kernel slide(Part1)
 
0x003 内核扩展源码分析
在开始分析之前,先来了解一些概念:
1.IOKit?
IOKit是用于设备驱动程序的框架和内核子系统,与IOKit的所有交互都以IOKit主端口开始,这是另一个特殊的机器端口,允许访问IOKit Registry。 IOKit Registry允许用户态程序查找可用的硬件,而设备驱动程序可以通过实现UserClient将接口暴露给用户空间。用户空间实际与IOKit驱动程序的UserClient交互的主要方式是通过io_connect_method,此方法由IOKitUser库函数IOConnectCallMethod封装。 copyright 无奈人生
2.IOKit Registry?
IOKit Registry实际上是一个驱动程序可以声明键值对的地方(其中键是一个字符串,其值是属于CoreFoundation的数据类型),驱动程序还可以指定其中一些键是可配置的,这意味着从用户空间可以使用IOKit Registry的API来设置新值。
获取macOS kext扩展源码
[传送门]
打开IOHIDSystem/IOHIDevice.cpp,找到IOHIDevice::setProperties、IOHIDevice::setParamProperties方法
// RY: Override IORegistryEntry::setProperties().  This will allow properties
// to be set per device, instead of globally via setParamProperties.
IOReturn IOHIDevice::setProperties( OSObject * properties )
{
    OSDictionary * propertyDict = OSDynamicCast(OSDictionary, properties);
    IOReturn       ret          = kIOReturnBadArgument;
    if ( propertyDict ) {
        if (propertyDict->setOptions(0, 0) & OSDictionary::kImmutable) { 无奈人生安全网
            OSDictionary * temp = propertyDict;
            propertyDict = OSDynamicCast(OSDictionary, temp->copyCollection());
        }
        else {
            propertyDict->retain();
        }
        propertyDict->setObject(kIOHIDDeviceParametersKey, kOSBooleanTrue);
        ret = setParamProperties( propertyDict );
        propertyDict->removeObject(kIOHIDDeviceParametersKey);
        propertyDict->release();
    }
    return ret;
}
IOReturn IOHIDevice::setParamProperties( OSDictionary * dict ) www.wnhack.com
{
    IOHIDEventService * eventService = NULL;
    if ( dict->getObject(kIOHIDEventServicePropertiesKey) == NULL ) {
        IOService * service = getProvider();
        if ( service )
            eventService = OSDynamicCast(IOHIDEventService, service);
    }
    if ( dict->getObject(kIOHIDDeviceParametersKey) == kOSBooleanTrue ) {
        OSDictionary * deviceParameters = OSDynamicCast(OSDictionary, copyProperty(kIOHIDParametersKey));
        if ( !deviceParameters ) {
            deviceParameters = OSDictionary::withCapacity(4);
        }
        else {
            if (deviceParameters->setOptions(0, 0) & OSDictionary::kImmutable) { www.wnhack.com
                OSDictionary * temp = deviceParameters;
                deviceParameters = OSDynamicCast(OSDictionary, temp->copyCollection());
                temp->release();
            }
            else {
                // do nothing
            }
        }
www.wnhack.com

[1] [2] [3] [4] [5]  下一页 无奈人生安全网

。 (责任编辑:admin)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。