主机安全涉及防御的整个纵深,内容繁多,如防火墙、WAF、RASP、IDS、IPS、安全审计、病毒杀毒、补丁管理、安运与安服等等。本文的目标主要是解决单点的系统威胁的发现与防御问题,属于系统安全的范畴,主要包含攻击发现、本地提权、rootkit防护三方面的内容。
本文目标在操作系统层面仅限于Linux系统,体系架构上以X86为主,兼顾ARM64。公司目前的主机系统主要是Intel XEON架构。既然以服务器系统为主,所以必须应对生产服务器对稳定性及性能的苛刻要求,并在此前提下达成安全上的需求。
总之,从检测能力及防护能力上着手,进一步接近并达成反入侵的需求,确实做好安全与保障。
大部分的入侵行为均可分成以下几个阶段:
在主机这个单点上由于缺少关联数据,针对“扫描探测”只能做有限应对,如弱密码爆破场景,其它复杂场景需要汇集终端及其它主机的数据综合分析以作判定。第二步的漏洞触发也是很难检测到的,如未知0DAY漏洞本身就没有任何的先验知识,毕竟漏洞的存在是不可回避的事实。好在从第三步开始,主机端均有机会发现并做出合理判定,因为攻击意图必须以特定的攻击行为方能达成。
攻击行为相对于系统正常行为来说还是少之又少,并且多数攻击行为和正常操作并没有太大差异,这也是攻击检测的难点。攻击行为可分为两部分分别应对:可疑攻击和未知攻击,可疑攻击部分毕竟有先验知识,可以划定出较清楚的边界,此部分可以马上着手实现,这也是本文的重点。
这部分主要依据经验总结,是针对当前HIDS的补充和增强,检测部分主要有4类检测项目,实现思路部分先做个简单阐述,等商定后再做详细详解。
此部分主要针对CPU硬件的安全特性的检测,攻击者为了展开攻击或扩大成果不得不关闭这些安全特性:
这部分主要是针对内核对象及内核空间的检测,需要内核权限:
此部分检测针对用户进程,主要是进程相关的核心数据结构、以及对进程自身的R3用户空间的内存的检测:
这里我们主要关注进程、程序/动态库/模块加载、内存及文件相关的调用,与Linux LSM的监控点基本符合。以4.4.131的内核为例,系统共提供了多达198个监控点回调,较新的5.4.2内核已经支持多达216监控回调:
类别 | 钩子函数个数 | 功能 |
---|---|---|
ptrace | 2 | ptrace操作的权限检查 |
能力机制 | 3 | Capabilities相关操作的权限检查 |
磁盘配额 | 2 | 配盘配额管理操作的权限检查 |
超级块 | 13 | mount/umount/文件系统/超级块相关操作的权限检查 |
dentry | 2 | dentry相关操作的权限检查 |
文件路径 | 11 | 文件名/路径相关操作的权限检查 |
inode | 27 | inode相关操作的权限检查 |
file | 13 | file相关操作的权限检查 |
程序加载 | 5 | 运行程序时的权限检查 |
进程 | 27 | 进程/进程相关操作的权限检查 |
IPC | 21 | IPC消息/共享内存/信号量等操作的权限检查 |
proc文件系统 | 2 | proc文件系统相关操作的权限检查 |
系统设置 | 2 | 日志,时间等相关操作的权限检查 |
内存管理 | 1 | 内存管理相关操作的权限检查 |
安全属性 | 7 | 对安全相关数据结构的操作的权限检查 |
网络 | 37 | 网络相关操作的权限检查 |
XFRM | 11 | XFRM架构想要关操作的权限检查 |
密钥 | 4 | 密钥管理相关操作的权限检查 |
审计 | 4 | 内核审计相关操作的权限检查 |
Android Binder | 4 | Android Binder架构有关操作的权限检查 |
总计 | 198 |
重点关注项:
需要两种检测机制:
此部分需要周期性的定时检测,实现方式有多种,如hrtimer/timer回调,延时工作队列(delayed workqueue)、硬件PMU或Intel PT等机制,目前来看延时工作队列的方式足以满足需求,如果后期对实时性要求更高可改用高精度时钟(hrtimer),这两种方式是都是Linux内核本身所支持的,有良好的普适性和稳定性。
在涉及内核对抗的情况下,可采用PMU或PT等硬件机制,硬件机制还能应对基于虚拟化的攻击,参考实现有【REF3: HARDWARE-ASSISTED ROOTKITS】及【REF4: GhostHook – Bypassing PatchGuard with Processor Trace Based Hooking】。
这部分数据的检测要注意事件回调的上下文环境,部分数据检测会涉及进程用户层内存的访问,属于softirq的hrtimer回调中是不能进行此操作的,需要转至workqueue或私有内核线程。
另外,纯用户层内存的检测亦可以通过R3 HOOK【REF2: TrustSec: LINUX: HOW’S MY MEMORY】或uprobe机制实现(自Linux 3.8开始支持),但必要性并不大,完全内核态的实现没有引入过多复杂性。
针对未知攻击一直没有较好的应对方式,一些比较苛刻的环境采用了可信计算的机制,即非白即黑的策略。可信计算主要解决了程序来源的问题,并不能有效应对程序的漏洞问题。业界公司应对内存安全的方案,所解决的也是类似的未知攻击及内存安全问题。
本章节所描述的应对思路便遵循了非白即黑的策略,当然此部分并不是完全的可信计算,而是一种轻量级的程序来源可信及可信执行的工程化实现。
程序可信所解决的是来源问题,有两种可实现方式:
此部分对用户行为有较大影响,程序发布及扩散环节都要做处理,特别是第二种方式。
执行可信考虑的不是程序的来源,而是程序自身的代码逻辑,可分为两种粒度的控制:
Linux下可执行脚本种类繁多,且功能较大,没有统一的方式来应对,可常用的应对方案有以下几中:
6.1 自保功能:防杀防卸载 6.2 ARM64等新体系结构的支持 6.3 代码优化及性能提升
安全不只是技术,还是人的行为管理和数据的运营,所以有必要从以下两个方面来强化数据的收集与关联:
常登录的服务器、登录时间、经常的操作、来源ip等习惯行为数据
所有的程序(可执行程序、动态库、脚本)及安装包、来源信息的整理,现在360、腾讯等公司均已建立了较为完备的样本库,同样亦适用于URL/IP、威胁及漏洞等数据
Windows HIPS (Host Intrusion Prevent System) 主机入侵防御系统核心部分可以归纳为3D,即AD(Application Defend,应用程序防御体系)、RD(Registry Defend,注册表防御体系)和FD(File Defend,文件防御体系)。另外还有ND(Network Defend,网络防火墙)及DD(Device Defend,设备/外设防护),后两者也算是管控的范畴
Windows的用户权限管理比较宽松,AD防护不仅复杂还面临较大的攻击面:
针对AD防护,仅利用系统内核层回调很难达成全面防护,只有当攻击已发生且已经成功的情况下才能发现攻击,此时恶意攻击已然达成。AD防护的短板极有必要采用R0或R3 HOOK的方式予以弥补和加固。
操作 | 方式 | 说明 |
---|---|---|
创建 | - | 通用回调可以在进程启动时得到通知,但在“进程为什么会启动”的原因上缺少必要信息,R0/R3 HOOK可以作为必要的补充手段来实现全方面的进程监控 |
普通进程 | 在进程加载阶段可侦测,可采用手段:FD及通用回调 | |
脚本程序 | 可侦测,如cmd batch、powershell、python及WScript或CScript等,可侦测到解释程序的启动及相关命令行参数 | |
计划任务 | 可侦测,可通过父进程判断是不是计划任务,但计划任务的创建无从感知。当然计划任务的创建亦可从文件系统层感知并发现,但此方式只是个间接方案 | |
服务创建及修改 | 加载时通过进程回调可侦测,服务创建及修改可通过RD侦测 | |
驱动创建及修改 | 同服务 | |
WMI串链 | 可侦测新进程启动,但不能定位由谁创建 | |
DCOM串链 | 可侦测,但不能定位原始启动进程 | |
DDE加载 | 可侦测 | |
MSI安装拦截 | 可侦测 | |
PICO/WSL进程 | 可发现、可拦截(Win10系统) | |
... | ||
结束 | - | 通用回调可以在得到进程退出通知,但时机上已经太晚了;只能通过R3或R0 HOOK实现更早和更好时机上的拦截 |
窗口消息 | 通过SendMessage/PostMessage/PostThreadMessage方式直接发送退出消息 | |
动作模拟 | 通过模拟按键及鼠标输入,直接发送ALT+F4或者鼠标点击事件 | |
结束进程 | TerminateProcess/NtTerminateProcess | |
停止或结束线程 | SuspendThread/TerminateThread/ NtSuspendTHread/NtTerminateThread | |
调试模式 | NtDebugActiveProcess DebugSetProcessKillOnExit ... | |
job调度 | 通过AssignProcessToJobObject及TerminateJobObject强制关闭进程,或通过job作业限制进程的执行调度 | |
WMI利用 | ||
WinStation | ||
执行劫持 | 通过远程线程、APC或SetThreadContext将流程导向ExitProcess | |
资源耗尽 | 耗尽进程的Handle/VM资源等以造成程序运行错误 | |
镜像破坏 | 通过VirtualProtectEx改变关键页面属性至PAGE_NOACCESS等,或通过WriteProcessMemory进行破坏 | |
内核攻击 | 方式非常多,不在我们考虑之列 | |
... | ||
注入 | - | 在R3 HOOK统一框架设计中有详细描述,在此只简单列举常用方式。通过模块加载系统回调可以感知注入事件的发生,但不能直接拦截 |
APC注入 | R0及R3均可攻击,除R0/R3 HOOK外没有好的方案 | |
远程线程注入 | R0及R3均可攻击,可通过线程创建回调侦测到 | |
消息钩子 | 可通过模块加载侦测,但无法溯源至“消息钩子” | |
线程Context劫持 | R0及R3均可攻击,不可侦测,只能采用HOOK方案 | |
内存写入 | R0及R3均可攻击,不可侦测,只能采用HOOK方案 | |
UserModeCallback | 不可侦测,只能采用HOOK方案 | |
Section Un-mapping | 不可侦测:UnMapViewOfSection/NtUnmapViewOfSectionEx | |
SetWindowLong[Ptr]注入 | 不可侦测,只能采用HOOK方案 | |
打印、输入法注入 | 可通过模块回调侦测到,但无法溯源 | |
DLL劫持 | DLL搜索路径篡改、DLL文件替换等 | |
... | ||
其它 | - | 隐私窃取、信息泄漏 |
消息拦截 | 不可侦测 | |
KeyLogger | 一般均是通过DLL注入实现 | |
白利用、提权、沙箱逃逸 | 发现与拦截均有难度 |
RD防护通过注册表操作回调基本可以达成我们针对注册表操作的监控、审计及拦截的需求。注册表回调操作自Windows XP系统之后均有支持,但XP系统的支持并不完善,有可能需要采用OB HOOK等方式以弥补回调功能的缺失。
Vista之后系统针对注册表操作增加了事务处理,WDK已有演示程序。
操作 | 前置回调 | 后置回调 |
---|---|---|
键删除 | RegNtPreDeleteKey | RegNtPostDeleteKey: SRV2003 |
值创建、改变 | RegNtPreSetValueKey | RegNtPostSetValueKey: SRV2003 |
值删除 | RegNtPreDeleteValueKey | RegNtPostDeleteValueKey: SRV2003 |
键属性修改 | RegNtPreSetInformationKey | RegNtPostSetInformationKey: SRV2003 |
键改名 | RegNtPreRenameKey | RegNtPostRenameKey: SRV2003 |
子键枚举 | RegNtPreEnumerateKey | RegNtPostEnumerateKey: SRV2003 |
值枚举 | RegNtPreEnumerateValueKey | RegNtPostEnumerateValueKey: SRV2003 |
获取键信息 | RegNtPreQueryKey | RegNtPostQueryKey: SRV2003 |
值内容提取 | RegNtPreQueryValueKey | RegNtPostQueryValueKey: SRV2003 |
RegNtPreQueryMultipleValueKey | RegNtPostQueryMultipleValueKey: SRV2003 | |
子键创建 | RegNtPreCreateKey | RegNtPostCreateKey |
子键创建 | RegNtPreCreateKeyEx: SRV2003 | RegNtPostCreateKeyEx: SRV2003 |
子键打开 | RegNtPreOpenKey | RegNtPostOpenKey |
子键打开 | RegNtPreOpenKeyEx: SRV2003 | RegNtPostOpenKeyEx: SRV2003 |
子键关闭 | RegNtPreKeyHandleClose | RegNtPostKeyHandleClose: SRV2003 |
RegNtPreFlushKey: VISTA | RegNtPostFlushKey: VISTA | |
RegNtPreLoadKey: VISTA | RegNtPostLoadKey: VISTA | |
RegNtPreUnLoadKey: VISTA | RegNtPostUnLoadKey: VISTA | |
安全描述符提取 | RegNtPreQueryKeySecurity: VISTA | RegNtPostQueryKeySecurity: VISTA |
安全描述符设置 | RegNtPreSetKeySecurity: VISTA | RegNtPostSetKeySecurity: VISTA |
RegNtPreRestoreKey: VISTA SP2 | RegNtPostRestoreKey: VISTA SP2 | |
RegNtPreSaveKey: VISTA SP2 | RegNtPostSaveKey: VISTA SP2 | |
RegNtPreReplaceKey: VISTA SP2 | RegNtPostReplaceKey: VISTA SP2 | |
RegNtPreQueryKeyName: WIN10 | RegNtPostQueryKeyName: WIN10 | |
RegNtCallbackObjectContextCleanup: VISTA |
针对FD的防护将基于Windows FS Mini Filter架构实现,Windows FS Mini Filter可支持Win2k SP4、XP SP2及最新的Windows操作系统。XP及Win2k系统上的支持最新版本Windows的支持有些差别,在实现时要多加注意。另外Vista之后文件操作事务的支持增加了攻击面,使得针对文件的攻击手段更加隐蔽,因此文件事务操作的支持是必须的。
Mini Filter框架不仅可对本地及网络文件进行监控,亦支持邮槽及命名管道的操作监控,后期可根据实际需求进行灵活扩展。
操作 | 描述 | 备注 | |
---|---|---|---|
IRP_MJ_CREATE | 文件打开、删除、覆写(清空)操作 | ||
IRP_MJ_CLEANUP | 文件句柄关闭 | ||
IRP_MJ_CLOSE | |||
IRP_MJ_CREATE_MAILSLOT | 只针对邮槽驱动 | ||
IRP_MJ_CREATE_NAMED_PIPE | 只针对管道驱动 | ||
IRP_MJ_DEVICE_CONTROL | 与应用层通信、存储设备通信 | ||
IRP_MJ_DIRECTORY_CONTROL | 目录项管理 | ||
IRP_MJ_FILE_SYSTEM_CONTROL | |||
IRP_MJ_FLUSH_BUFFERS | |||
IRP_MJ_INTERNAL_DEVICE_CONTROL | |||
IRP_MJ_LOCK_CONTROL | byte range lock(flock)支持 | ||
IRP_MJ_PNP | 设备热插拔处理 | ||
IRP_MJ_QUERY_EA | EA数据流处理 | ||
IRP_MJ_QUERY_INFORMATION | 文件信息处理 | ||
IRP_MJ_QUERY_QUOTA | 用户Quota支持 | ||
IRP_MJ_QUERY_SECURITY | 安全属性及安全描述 | ||
IRP_MJ_QUERY_VOLUME_INFORMATION | 卷属性操作 | ||
IRP_MJ_READ | 读操作 | ||
IRP_MJ_SET_EA | EA创建或写入 | ||
IRP_MJ_SET_INFORMATION | 设置文件信息、改名、删除文件等 | ||
IRP_MJ_SET_QUOTA | 设置用户Quota | ||
IRP_MJ_SET_SECURITY | 设置安全描述符 | ||
IRP_MJ_SET_VOLUME_INFORMATION | 设置卷属性、卷标信息 | ||
IRP_MJ_SHUTDOWN | 关机事件 | ||
IRP_MJ_SYSTEM_CONTROL | WMI | ||
IRP_MJ_WRITE | 写操作 | ||
IRP_MJ_ACQUIRE_FOR_CC_FLUSH | 锁操作回调 | ||
IRP_MJ_ACQUIRE_FOR_MOD_WRITE | 锁操作回调: mmap | ||
IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION | 锁操作回调: Section首次创建 | ||
IRP_MJ_FAST_IO_CHECK_IF_POSSIBLE | Fast i/o调用检测 | ||
IRP_MJ_MDL_READ | MDL i/o,一般用于SRV | ||
IRP_MJ_MDL_READ_COMPLETE | |||
IRP_MJ_MDL_WRITE_COMPLETE | |||
IRP_MJ_NETWORK_QUERY_OPEN | |||
IRP_MJ_PREPARE_MDL_WRITE | |||
IRP_MJ_RELEASE_FOR_CC_FLUSH | 锁操作回调 | ||
IRP_MJ_RELEASE_FOR_MOD_WRITE | 锁操作回调 | ||
IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION | 锁操作回调 | ||
IRP_MJ_VOLUME_DISMOUNT | 卷卸载操作 | ||
IRP_MJ_VOLUME_MOUNT | 新卷加载操作 |
ND所实现的就是一个轻量的防火墙,可以将五元组信息与进程进行关联。Windows的网络框架随不同的版本有较大的变动,NDIS、TDI、WSK/Winsock Kernel、WFP/Windows Filter Platform
DD即设备防护,主要应用于对外设的管控,可实现设备的停用或限制
1: Magnesium Object Manager Sandbox, A More Effective Sandbox Method for Windows 7
2: MSDN: Filtering Registry Calls
3: Filter Manager Support for Minifilter Drivers
4: MSDN: REG_NOTIFY_CLASS enumeration
5: CodeMachine: Kernel Callback Functions
6: OSR: Kernel Mode Extensions Driver
7: WDK Samples: Registry Logging
8: https://blog.csdn.net/whatday/article/details/52623878
9: https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/handling-notifications