【云攻防系列】玩转eBPF—关于内核运行时安全的那些事儿

知识背景
当我们谈及运行时防护产品或方案时,人们的目光主要集中在主机、终端和目前最火热的云原生场景上。Falco、Tracee、Tetragon、Datadog-agent、KubeArmor 是现阶段云原生场景下比较流行的几款运行时防护方案。这些方案主要是基于 eBPF 挂载内核函数并编写过滤策略,在内核层出现异常攻击时触发预置的策略,无需再返回用户层而直接发出告警甚至阻断。

这样的方案优点是可以自定义乃至自动化配置策略,修改检测、阻断规则文件更快速,更新灵活性高、过滤条件丰富(进程、网络、文件等),更加重要的在内核直接处理各种事件,节省了数据传输和上下文切换带来的性能损耗,对于网络或者 Tracing 等短时间大量数据处理的场景,性能方面提升更高。劣势也很明显,也就是只能管控到进程这个粒度。如果发生误报的时候,杀死进程对系统稳定性和性能有很大的影响,也会涉及到正常业务的流转。

图片[1]-【云攻防系列】玩转eBPF—关于内核运行时安全的那些事儿-NGC660 安全实验室

我们都知道内核社区的传统就是相对安全性更侧重于性能和功能(这也是各大厂商最关注的部分),在需要牺牲性能来改善内核安全性时并不愿意折衷处理。其实从另一个角度来看,也不是内核社区不想合入有用的安全 Patch,从 LKML 里面关于 LSM 或者其他 Security 相关的订阅人数、世界上独立的内核安全公司数量来看,除了一些内核安全机制有相应大公司或大社区维护(SELinux (NSA)、AppArmor (OpenSuSE/Ubuntu)、PaX / grsecurity (Spender)),以及 PaX / grsecurity 和内核社区的历史渊源,所以在全球范围内,真实有效的内核安全开发者是少之又少。

Linux内核社区坚持”Security through obscurity”哲学,这意味着内核社区从来不主动申请CVE漏洞编号,即使如此,2021年1月到8月,有CVE编号的内核漏洞超过110个。再加上内核代码提交走的流程比较繁琐,应用到具体内核版本上,又存在周期长以及版本适配的问题,所以导致内核在安全方面发展的速度明显慢于其他模块。

图片[2]-【云攻防系列】玩转eBPF—关于内核运行时安全的那些事儿-NGC660 安全实验室

KRSI优势和流程
基于以上历史原因,eBPF 和基于函数的更细粒度管控方案重磅出炉,名字就叫内核运行时检测 KRSI(Kernel Runtime Security Instrumentation)。

KRSI 的原型通过 LSM (Linux security module)形式已经实现出来了,可以将 eBPF program 挂载到kernel 的 security hook(安全挂钩点)上。内核的安全性主要包括两个方面:Signals 和 Mitigations,这两者密不可分。

Signals 就是指一些可能意味着(并不是 100% 确定)系统有一些异常活动的迹象、事件;

Mitigation 则是指在检测到异常行为之后所采取的补救措施;

KRSI 基于 LSM 来实现,这也就使其能够进行访问控制策略的决策,但这不是 KRSI 的工作重心,主要是为了全面监视系统行为,以便检测攻击。从这种角度来看,KRSI 可以说是内核审计机制的扩展,使用eBPF 来提供比目前内核审计子系统更高级别的可配置性。

struct krsi_hook {

const char *name

enum krsi_hook_type h_type;

struct dentry *h_dentry;

struct mutex mutex;

struct bpf_prog_array __rcu *progs;

};

图片[3]-【云攻防系列】玩转eBPF—关于内核运行时安全的那些事儿-NGC660 安全实验室

在 KRSI 中,三个参数将直接传递给任何挂载的 BPF程序。这些程序可以通过 vma 指针来了解所有受影响的内存区域。它们还可以根据 vma->vm_mm 来获得调用进程的顶层内存管理数据(mm_struct 结构体)。简而言之,这些程序可以获取大量信息。

int security_file_mprotect(struct vm_area_struct *vma,

unsigned long reqprot,unsigned long prot);

图片[4]-【云攻防系列】玩转eBPF—关于内核运行时安全的那些事儿-NGC660 安全实验室

1、KRSI 允许适当的特权用户将 BPF 程序挂载到 LSM 子系统提供的数百个钩子中的任何一个上面;

2、为了简化这个步骤,KRSI 在 /sys/kernel/security/bpf 下面导出了一个新的文件系统层次结构——每个钩子对应一个文件;

3、可以使用 bpf() 系统调用将 BPF 程序(新的BPF_PROG_TYPE_LSM 类型)挂载到这些钩子上,并且可以有多个程序挂载到任何给定的钩子。

4、每当触发一个安全钩子时,将依次调用所有挂载的 BPF程序,只要任一 BPF 程序返回错误状态,那么请求的操作将被拒绝。

结论
内核安全问题,牵一发而动全身,尤其是在运行时安全方面。通过上述 eBPF 新型 program 类型,为 signals 和 mitigation 提供统一 API 的策略,并优化内核 LSM 框架和现有机制容易丢失系统调用的问题,从阻断一个函数调用运行的角度,来实现更细粒度,也更合理的检测方案,同时在内核Livepatch、漏洞检测以及防御提权相关攻击手段上,有着进一步的发展空间。eBPF 结合 LSM 的方案还在持续演进,功能和性能逐渐完善,详细请看内核社区 LSM 邮件列表或https://lore.kernel.org/all/?q=eBPF+LSM。创新研究院云安全团队将会持续关注相关内容和技术的演进。

本文原作者:深信服千里目安全实验室

本文转载于先知社区,如有侵权请联系删除

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享