Linux系统安全-入侵检测与防护思路

1 系统安全简介及现状分析

主机安全涉及防御的整个纵深,内容繁多,如防火墙、WAF、RASP、IDS、IPS、安全审计、病毒杀毒、补丁管理、安运与安服等等。本文的目标主要是解决单点的系统威胁的发现与防御问题,属于系统安全的范畴,主要包含攻击发现、本地提权、rootkit防护三方面的内容。

本文目标在操作系统层面仅限于Linux系统,体系架构上以X86为主,兼顾ARM64。公司目前的主机系统主要是Intel XEON架构。既然以服务器系统为主,所以必须应对生产服务器对稳定性及性能的苛刻要求,并在此前提下达成安全上的需求。

2 核心需求

  1. 实现入侵行为的检测与防护,保障服务安全
  2. 稳定性与性能兼顾,保证服务可用性

总之,从检测能力及防护能力上着手,进一步接近并达成反入侵的需求,确实做好安全与保障。

3 攻击路径

大部分的入侵行为均可分成以下几个阶段:

  1. 扫描探测:通过扫描、社工或钓鱼等方式以了解主机信息,如网络结构、操作系统及服务类型等
  2. 漏洞触发:针对系统漏洞或配置错误发起攻击,前期攻击办能搭载较轻量的payload
  3. 主体下载:成功触发漏洞并达成了RCE (shellcode执行)或取得了shell权限,然后下载工作负载,如挖矿、勒索程序
  4. 主体执行:运行新下载的工作负载以启动真正的攻击,如挖矿、勒索、横向攻击、提权或持久化
  5. 本地提权:利用系统漏洞组合攻击,这一步有难度较高,且并非必需,主要由攻击意图决定
  6. 后门固化:即持久化,并隐藏自身或伪装、混淆

在主机这个单点上由于缺少关联数据,针对“扫描探测”只能做有限应对,如弱密码爆破场景,其它复杂场景需要汇集终端及其它主机的数据综合分析以作判定。第二步的漏洞触发也是很难检测到的,如未知0DAY漏洞本身就没有任何的先验知识,毕竟漏洞的存在是不可回避的事实。好在从第三步开始,主机端均有机会发现并做出合理判定,因为攻击意图必须以特定的攻击行为方能达成。

攻击行为相对于系统正常行为来说还是少之又少,并且多数攻击行为和正常操作并没有太大差异,这也是攻击检测的难点。攻击行为可分为两部分分别应对:可疑攻击和未知攻击,可疑攻击部分毕竟有先验知识,可以划定出较清楚的边界,此部分可以马上着手实现,这也是本文的重点。

4 可疑攻击

这部分主要依据经验总结,是针对当前HIDS的补充和增强,检测部分主要有4类检测项目,实现思路部分先做个简单阐述,等商定后再做详细详解。

4.1 攻击检测

4.1.1 CPU关键控制位

此部分主要针对CPU硬件的安全特性的检测,攻击者为了展开攻击或扩大成果不得不关闭这些安全特性:

  1. MSR寄件器EFER.NXE位:即DEP/NX位,数据区防执行,本安全特性默认开启,Linux系统允许通过grub的kernel参数开启或关闭。另外亦可通过修改MSI寄存Extended Feature Enable Register (EFER)的Bit 11调节。EFER寄存器是位于MSR的C0000080H处。
  2. CR4.SMEP位:Supervisor Mode Execution Prevention,此功能可阻止内核特权模式下运行用户层代码,可阻止ret2usr类的攻击。
  3. CR4.SMAP位:Supervisor Mode Access Prevention,配合EFLAGS的AC位可开启或关闭,可以阻止内核特权模式下直接访问用户层内存。在必须访问用户内存时,系统支持函数copy_to/from_user会临时设置EFLAGS的AC位。此特性从Linux 3.7开始支持。
  4. CR4.TSD位:Time Stamp Disable, 高精度计数器,可用于时序攻击,如Meltdown及Spectre/MDS等针对CPU漏洞的攻击所采用的就是rdtsc或rdtscp指令以精准确定CPU cache是否命中。
  5. CR4.PCE位: Performance-monitor Counter Enable,类似TSD,但精度上不如TSC。

4.1.2 内核检查项

这部分主要是针对内核对象及内核空间的检测,需要内核权限:

  1. 内核镜像: KIMAGE_VADDR, kpti/kaslr等属性
  2. 核心表项:idt/syscall table/shadow kernel
  3. 内核模块:映射区域:MODULES_VADDR - MODULES_END,3条链:module/sysfs/kobject
  4. 关键内核对象:file/dentry/inode_operations等,涉及文件系统(包含/proc、设备等重要数据结构,常被rootkit篡改以隐藏进程、网络连接、病毒文件等
  5. 内核通知链notifier_chain: 内核支持几十个,较重要的有module、keyboard等,后者可用于实现keylogger
  6. 网络驱动netfilter内部结构及操作表项
  7. binfmt: 二进制可执行行程序加载:elf程序运行、内核模块加载等

4.1.3 进程检查项

此部分检测针对用户进程,主要是进程相关的核心数据结构、以及对进程自身的R3用户空间的内存的检测:

  1. 可执行内存区域检测: a) W + X 内存映射区,针对jit程序存在误报可能 b) 不属于任何模块的映射区:如通过【REF1: ELF反射加载器】自展开加载的模块或程序
  2. VDSO及vsyscall映射区域防篡改校验:常用于ret2dir及DirtyCow攻击,可通过PFN与内容HASH进行校验
  3. 运行时安全属性检测: a) LD_PRELOAD: 动态库搜索路径,最好程序运行时进行检查 b) 第三方模块注入,如Apache插件,第三方注入在Linux系统上并不常见
  4. task_struct结构:如属主权限信息:uid/suid/euid/gid/egid/fsuid/fsgid, cap_effective/inheritable/permitted等,定时检测可以发现“任意内存写”攻击 a) 非法pid值检查:利用非法pid值可以达成进程隐藏 b) 线程Stack Pointer检查 (Stack Pivot攻击),难点是:go/rust/jit的

4.1.4 高危调用

这里我们主要关注进程、程序/动态库/模块加载、内存及文件相关的调用,与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

重点关注项:

  1. prctl: 进程项调节
  2. ptrace: 调试
  3. mmap/mprotect (W+X):内存映射、可执行权限设置
  4. dlopen/dlmopen: 动态库加载
  5. LKM/module加载时针对modprobe_path的检查
  6. execve/execveat等:针对主、客体的关联判断,另外可增加主被动交互的侦测,如通过bash.readline可以判断是否是用户手动输入
  7. commit_creds/setuid/seteuid/setegid...
  8. chown/chmod +s/rename/unlink/link等:文件属主、属性相关操作

4.2 实现思路简述

需要两种检测机制:

4.2.1 定时检测:CPU及纯内核数据

此部分需要周期性的定时检测,实现方式有多种,如hrtimer/timer回调,延时工作队列(delayed workqueue)、硬件PMU或Intel PT等机制,目前来看延时工作队列的方式足以满足需求,如果后期对实时性要求更高可改用高精度时钟(hrtimer),这两种方式是都是Linux内核本身所支持的,有良好的普适性和稳定性。

在涉及内核对抗的情况下,可采用PMU或PT等硬件机制,硬件机制还能应对基于虚拟化的攻击,参考实现有【REF3: HARDWARE-ASSISTED ROOTKITS】及【REF4: GhostHook – Bypassing PatchGuard with Processor Trace Based Hooking】。

4.2.2 事件触发检测:进程相关数据

  1. 模块加载、进程创建等操作可通过通知链或kprobe监控点触发,如LD_PRELOAD及modprobe_path等项目
  2. 进程相关数据检测:要通过进程调度事件触发(trace_sched_switch),当进程时间片用完被调试出去时检测task_struct结构及相关内存映射属性等项目
  3. 高危调用

这部分数据的检测要注意事件回调的上下文环境,部分数据检测会涉及进程用户层内存的访问,属于softirq的hrtimer回调中是不能进行此操作的,需要转至workqueue或私有内核线程。

另外,纯用户层内存的检测亦可以通过R3 HOOK【REF2: TrustSec: LINUX: HOW’S MY MEMORY】或uprobe机制实现(自Linux 3.8开始支持),但必要性并不大,完全内核态的实现没有引入过多复杂性。

5 未知攻击

针对未知攻击一直没有较好的应对方式,一些比较苛刻的环境采用了可信计算的机制,即非白即黑的策略。可信计算主要解决了程序来源的问题,并不能有效应对程序的漏洞问题。业界公司应对内存安全的方案,所解决的也是类似的未知攻击及内存安全问题。

本章节所描述的应对思路便遵循了非白即黑的策略,当然此部分并不是完全的可信计算,而是一种轻量级的程序来源可信及可信执行的工程化实现。

5.1 程序可信

程序可信所解决的是来源问题,有两种可实现方式:

  1. 白名单机制:利用现有的IMA/Integrity进行来源控制
  2. 针对ELF文件增加新section,所有的程序均要做此处理,技术上需要修改elf加载器

此部分对用户行为有较大影响,程序发布及扩散环节都要做处理,特别是第二种方式。

5.2 执行可信

执行可信考虑的不是程序的来源,而是程序自身的代码逻辑,可分为两种粒度的控制:

  1. 指令控制流防护(CFI):需要编译器在编译阶段生成指令时加入分支指令操作的判断,这部分相对已经成熟,gcc及llvm均有支持,会增加程序的体量和性能损耗,但总体上可控。grSecurity的RAP方式就是类似的方式,可参见:【REF5: grSecurity RAP】
  2. 关键API调用序列防护:在API或系统调用层次上实现的执行防护,需要预先针对可执行程序进行静态或动态分析以生成规则,并在运行时进行插桩检测,同RASP异曲同工,只是所解决的问题不在一个层面上。相关的参考有【REF6: BlackBox: Lightweight Security C Monitoring for COTS Binaries】及【REF7: Virsec Trusted Execution】

5.3 脚本防护

Linux下可执行脚本种类繁多,且功能较大,没有统一的方式来应对,可常用的应对方案有以下几中:

  1. 用行为沙箱或类RASP的方式来做启发式分析
  2. 通过文件集进行执行管控: 如/tmp目录、web服务upload目录(新上传)脚本防执行,当然也有些例外情况,如安装包会自动生成脚本并执行
  3. 全量收集以进行后续人工分析及机器学习分类

6 其它功能

6.1 自保功能:防杀防卸载 6.2 ARM64等新体系结构的支持 6.3 代码优化及性能提升

7 样本数据库建设

安全不只是技术,还是人的行为管理和数据的运营,所以有必要从以下两个方面来强化数据的收集与关联:

7.1 行为数据及画像库

常登录的服务器、登录时间、经常的操作、来源ip等习惯行为数据

7.2 程序样本数据库

所有的程序(可执行程序、动态库、脚本)及安装包、来源信息的整理,现在360、腾讯等公司均已建立了较为完备的样本库,同样亦适用于URL/IP、威胁及漏洞等数据

8 参考资料

  1. REF1: ELF反射加载器
  2. REF2: TrustSec: LINUX: HOW’S MY MEMORY
  3. REF3: Hardware-Assisted Rootkits: Abusing Performance Counters on the ARM and x86 Architectures
  4. REF4: GhostHook – Bypassing PatchGuard with Processor Trace Based Hooking
  5. REF5: grSecurity RAP
  6. REF6: BlackBox: Lightweight Security C Monitoring for COTS Binaries
  7. REF7: Virsec Trusted Execution
  8. REF8: Integrity Measurement Architecture (IMA)

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注