端点安全
EndpointSecurity 框架是苹果公司在WWDC2019中公布的一个框架,并在 macOS Catalina 系统中引入,提供了一套系统安全API,用于替代 Kauth KPI,代替内核扩展框架的功能。该框架是用C语言编写的,可有效利用内存并提升性能,与Kauth框架相比,EndpointSecurity 框架提供了非常丰富的有关系统事件的信息,以前需要再内核扩展中才能检索到信息,现在通过相对简单的API即可访问,这使得开发者能够十分方便的用工具对其进行调试,从而开发变得更加容易。同时有效的减少了一些由于扩展故障导致的系统奔溃的情况。
-
EndpointSecurity框架跨越了用户层、系统层、内核层三个不同的层。SystemExtensions.framework负责激活和停用系统扩展。sysextd是系统守护进程,验证系统扩展并将它们移动到适当的地系统位置,然后发送消息请求相关的守护进程加载扩展。endpointsecurityd是一个系统守护进程,涉及管理和启动端点安全系统扩展。libEndpointSecurity.dylib是系统扩展用来与内核通信的C语言库,使用I/OKit与端点安全KEXT通信。
具体架构见下图:
-
EndpointSecurity框架的核心在内核中实现,位于/System/Library/Extensions/EndpointSecurity.kext的内核扩展中(13系统苹果隐藏了内核扩展的二进制执行文件,如果想研究的可以在11系统中去找),这个KEXT主要由几个关键组件构成:EndpointSecurityDriver内核扩展的入口点,是操作系统与断点安全框架之间的主要交互点。EndpointSecurityEventManager负责实现内核钩子,允许框架通过拦截系统调用来监控系统事件。EndpointSecurityClientManager管理与用户空间客户端的通信,跟踪那些客户端已连接并需要接收事件通知。EndpointSecurityMessageManager向用户空间客户端发送消息和事件通知。
-
EndpointSecurity框架可以监控的事件分为以下几类:-
Process events
-
File system events
-
Memory mapping events
-
Clock events
-
Kernel events
-
Socket events
-
-
EndpointSecurity框架目前已有100种事件,还在不断增加中,整体上可以分为授权事件类型和通知事件类型两类AUTH授权事件:提供了拦截事件的能力,允许事件通过或者阻止事件执行。可以用来防止恶意软件执行、阻止对文件系统进行未经授权的修改或者加载某些恶意的动态库等等,还可以对恶意行为进行检测并告知用户某些可能得恶意活动。NOTIFY通知事件:更多的是基于警报的检测和响应,提供有关已经发生但没有机会干预的系统事件信息,可以向用户发送提醒信息,如某些系统事件可能与恶意行为相关等。
-
EndpointSecurity运行机制,当进程使用es_new_clientAPI连接EndpointSecurity子系统时,会设置ES客户端处理消息队列,每个ES客户端都有自己的订阅集,用来控制接收那些事件。如果内核中有事件被触发,并且客户端订阅了该事件,EndpointSecurity会拦截这个事件,这些数据收集封装成es_message_t消息,然后再发往相应的ES客户端排队等待事件处理代码块出进行处理。同时EndpointSecurity会尽量缓存,避免需要传递的AUTH事件消息数量过多。 -
es_message_t消息主要包含三类信息- 消息元数据,包含事件类型、消息生成时间、版本号等信息。
- 进程信息,比如可执行文件信息、完整文件状态信息、代码签名和进程及用户ID等信息。
- 特定事件数据,例如SIGNAL事件包含收到信号的进程相关信息和信号编号,EXEC事件包含被执行文件和可执行参数等信息,OPEN事件包含被打开文件和打开标志的相关信息。
-
EndpointSecurity有少量的运行时要求,必须满足才能成功建立ES事件流-
恰当的ES权限,在申请配置文件中选择
com.apple.developer.endpoint-security.client。 -
系统扩展需要额外的权限
com.apple.developer.endpoint-security.client才能安装这个扩展,并且得获得用户同意才能完成安装。 -
需要用户同意完全磁盘访问权限
-
若部署在托管设备上,需要MDM负责辅助分发(定义扩展的负载、隐私偏好负载)
-
-
EndpointSecurity框架几个重要的APIes_new_client使用该方法为EndpointSecurity子系统创建新客户端,并将新客户端连接到子系统。es_subscribe使用该方法来订阅系统事件。es_unsubscribe使用该方法取消订阅某些事件集。es_respond_auth_result使用该方法来允许或拒绝授权事件,此外可以对事件结果进行缓存。es_copy_message使用此方法来复制发送到处理程序的消息,必须通过es_free_message来释放。
-
EndpointSecurity注意点-
事件需要调用
es_subscribe订阅处理,否则该事件则隐式允许。 -
消息订阅需要在订阅事件前通过
es_subscribe来订阅处理,否则就会错过消息或者漏掉事件。 -
EndpointSecurity子系统强制要求截止期,所有早起启动客户端必须在截止期前发送就绪信号,一旦过期所有第三方执行自动允许继续。 -
EndpointSecurity框架不支持网络连接相关的事件,因为在网络扩展中做了处理,但Unix域套接字例外,因此可以将端点安全和网络扩展用一个系统扩展使用,需要在Info.plist中设置网络扩展和端点安全的键值就行。 -
对于多个ES客户端,消息的顺序就只相对于每个ES客户端的订阅来处理。
-
-
EndpointSecurity事件类型typedef enum { // The following events are available beginning in macOS 10.15 ES_EVENT_TYPE_AUTH_EXEC , ES_EVENT_TYPE_AUTH_OPEN , ES_EVENT_TYPE_AUTH_KEXTLOAD , ES_EVENT_TYPE_AUTH_MMAP , ES_EVENT_TYPE_AUTH_MPROTECT , ES_EVENT_TYPE_AUTH_MOUNT , ES_EVENT_TYPE_AUTH_RENAME , ES_EVENT_TYPE_AUTH_SIGNAL , ES_EVENT_TYPE_AUTH_UNLINK , ES_EVENT_TYPE_NOTIFY_EXEC , ES_EVENT_TYPE_NOTIFY_OPEN , ES_EVENT_TYPE_NOTIFY_FORK , ES_EVENT_TYPE_NOTIFY_CLOSE , ES_EVENT_TYPE_NOTIFY_CREATE , ES_EVENT_TYPE_NOTIFY_EXCHANGEDATA , ES_EVENT_TYPE_NOTIFY_EXIT , ES_EVENT_TYPE_NOTIFY_GET_TASK , ES_EVENT_TYPE_NOTIFY_KEXTLOAD , ES_EVENT_TYPE_NOTIFY_KEXTUNLOAD , ES_EVENT_TYPE_NOTIFY_LINK , ES_EVENT_TYPE_NOTIFY_MMAP , ES_EVENT_TYPE_NOTIFY_MPROTECT , ES_EVENT_TYPE_NOTIFY_MOUNT , ES_EVENT_TYPE_NOTIFY_UNMOUNT , ES_EVENT_TYPE_NOTIFY_IOKIT_OPEN , ES_EVENT_TYPE_NOTIFY_RENAME , ES_EVENT_TYPE_NOTIFY_SETATTRLIST , ES_EVENT_TYPE_NOTIFY_SETEXTATTR , ES_EVENT_TYPE_NOTIFY_SETFLAGS , ES_EVENT_TYPE_NOTIFY_SETMODE , ES_EVENT_TYPE_NOTIFY_SETOWNER , ES_EVENT_TYPE_NOTIFY_SIGNAL , ES_EVENT_TYPE_NOTIFY_UNLINK , ES_EVENT_TYPE_NOTIFY_WRITE , ES_EVENT_TYPE_AUTH_FILE_PROVIDER_MATERIALIZE , ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_MATERIALIZE , ES_EVENT_TYPE_AUTH_FILE_PROVIDER_UPDATE , ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_UPDATE , ES_EVENT_TYPE_AUTH_READLINK , ES_EVENT_TYPE_NOTIFY_READLINK , ES_EVENT_TYPE_AUTH_TRUNCATE , ES_EVENT_TYPE_NOTIFY_TRUNCATE , ES_EVENT_TYPE_AUTH_LINK , ES_EVENT_TYPE_NOTIFY_LOOKUP , ES_EVENT_TYPE_AUTH_CREATE , ES_EVENT_TYPE_AUTH_SETATTRLIST , ES_EVENT_TYPE_AUTH_SETEXTATTR , ES_EVENT_TYPE_AUTH_SETFLAGS , ES_EVENT_TYPE_AUTH_SETMODE , ES_EVENT_TYPE_AUTH_SETOWNER // The following events are available beginning in macOS 10.15.1 , ES_EVENT_TYPE_AUTH_CHDIR , ES_EVENT_TYPE_NOTIFY_CHDIR , ES_EVENT_TYPE_AUTH_GETATTRLIST , ES_EVENT_TYPE_NOTIFY_GETATTRLIST , ES_EVENT_TYPE_NOTIFY_STAT , ES_EVENT_TYPE_NOTIFY_ACCESS , ES_EVENT_TYPE_AUTH_CHROOT , ES_EVENT_TYPE_NOTIFY_CHROOT , ES_EVENT_TYPE_AUTH_UTIMES , ES_EVENT_TYPE_NOTIFY_UTIMES , ES_EVENT_TYPE_AUTH_CLONE , ES_EVENT_TYPE_NOTIFY_CLONE , ES_EVENT_TYPE_NOTIFY_FCNTL , ES_EVENT_TYPE_AUTH_GETEXTATTR , ES_EVENT_TYPE_NOTIFY_GETEXTATTR , ES_EVENT_TYPE_AUTH_LISTEXTATTR , ES_EVENT_TYPE_NOTIFY_LISTEXTATTR , ES_EVENT_TYPE_AUTH_READDIR , ES_EVENT_TYPE_NOTIFY_READDIR , ES_EVENT_TYPE_AUTH_DELETEEXTATTR , ES_EVENT_TYPE_NOTIFY_DELETEEXTATTR , ES_EVENT_TYPE_AUTH_FSGETPATH , ES_EVENT_TYPE_NOTIFY_FSGETPATH , ES_EVENT_TYPE_NOTIFY_DUP , ES_EVENT_TYPE_AUTH_SETTIME , ES_EVENT_TYPE_NOTIFY_SETTIME , ES_EVENT_TYPE_NOTIFY_UIPC_BIND , ES_EVENT_TYPE_AUTH_UIPC_BIND , ES_EVENT_TYPE_NOTIFY_UIPC_CONNECT , ES_EVENT_TYPE_AUTH_UIPC_CONNECT , ES_EVENT_TYPE_AUTH_EXCHANGEDATA , ES_EVENT_TYPE_AUTH_SETACL , ES_EVENT_TYPE_NOTIFY_SETACL // The following events are available beginning in macOS 10.15.4 , ES_EVENT_TYPE_NOTIFY_PTY_GRANT , ES_EVENT_TYPE_NOTIFY_PTY_CLOSE , ES_EVENT_TYPE_AUTH_PROC_CHECK , ES_EVENT_TYPE_NOTIFY_PROC_CHECK , ES_EVENT_TYPE_AUTH_GET_TASK // The following events are available beginning in macOS 11.0 , ES_EVENT_TYPE_AUTH_SEARCHFS , ES_EVENT_TYPE_NOTIFY_SEARCHFS , ES_EVENT_TYPE_AUTH_FCNTL , ES_EVENT_TYPE_AUTH_IOKIT_OPEN , ES_EVENT_TYPE_AUTH_PROC_SUSPEND_RESUME , ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME , ES_EVENT_TYPE_NOTIFY_CS_INVALIDATED , ES_EVENT_TYPE_NOTIFY_GET_TASK_NAME , ES_EVENT_TYPE_NOTIFY_TRACE , ES_EVENT_TYPE_NOTIFY_REMOTE_THREAD_CREATE , ES_EVENT_TYPE_AUTH_REMOUNT , ES_EVENT_TYPE_NOTIFY_REMOUNT // The following events are available beginning in macOS 11.3 , ES_EVENT_TYPE_AUTH_GET_TASK_READ , ES_EVENT_TYPE_NOTIFY_GET_TASK_READ , ES_EVENT_TYPE_NOTIFY_GET_TASK_INSPECT // The following events are available beginning in macOS 12.0 , ES_EVENT_TYPE_NOTIFY_SETUID , ES_EVENT_TYPE_NOTIFY_SETGID , ES_EVENT_TYPE_NOTIFY_SETEUID , ES_EVENT_TYPE_NOTIFY_SETEGID , ES_EVENT_TYPE_NOTIFY_SETREUID , ES_EVENT_TYPE_NOTIFY_SETREGID , ES_EVENT_TYPE_AUTH_COPYFILE , ES_EVENT_TYPE_NOTIFY_COPYFILE // The following events are available beginning in macOS 13.0 , ES_EVENT_TYPE_NOTIFY_AUTHENTICATION , ES_EVENT_TYPE_NOTIFY_XP_MALWARE_DETECTED , ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED , ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGIN , ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGOUT , ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOCK , ES_EVENT_TYPE_NOTIFY_LW_SESSION_UNLOCK , ES_EVENT_TYPE_NOTIFY_SCREENSHARING_ATTACH , ES_EVENT_TYPE_NOTIFY_SCREENSHARING_DETACH , ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGIN , ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGOUT , ES_EVENT_TYPE_NOTIFY_LOGIN_LOGIN , ES_EVENT_TYPE_NOTIFY_LOGIN_LOGOUT , ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD , ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_REMOVE // ES_EVENT_TYPE_LAST is not a valid event type but a convenience // value for operating on the range of defined event types. // This value may change between releases and was available // beginning in macOS 10.15 , ES_EVENT_TYPE_LAST } es_event_type_t; -
EndpointSecurity官方Demo,具体的操作可以参考代码,这里就不一一列举了