本文地址:https://www.ebpf.top/post/offensive-bpf-getting-started

在近几年来,eBPF 在 Linux 社区和之外得到了越来越多的关注。

eBPF 在攻击场景中的使用也逐渐引起大家的关注。因此,我决定从红队的角度进入深入探讨,以让大家对此有个整体的认识,以下系列文章则是对于这个历程的分享。

offensive-bpf

与我此前的机器学习攻防系列的形式类似,本站将会提供一系列围绕 BPF 在攻击环境中使用的样例,这也包括如何检测 BPF 被滥用的内容。

点击 ebpf 标签可以看到所有相关的内容。

至此,让我们开始吧。

1. 什么是 BPF (Berkeley Packet Filtering)

经典 BPF(cBPF) 允许用户空间程序(例如 tcpdump)设置过滤器抓取符合条件的网络数据包。真正执行的过滤在在内核中进行,这种方式极大地提高了性能,因为仅需要将过滤后的数据报文复制到用户空间。

eBPF 则是在 cBPF 的技术上将其扩展为了一种用户跟踪和 hook 的通用技术。

eBPF 可安全高效地扩展内核的功能,而无需修改内核源代码或加载内核模块。 (ebpf.io)

当前,当我们谈论 BPF 时,通常指的是 eBPF(而不是 cBPF ),所以为了方便,后续将只使用 BPF 这个术语。

BPF 允许用户编写程序,在内核的沙盒中运行。

2. BPF 使用场景

BPF 程序可在内核或用户空间的任何地方触发执行,当前甚至可以直接卸载到网卡上运行。

ebpio-overview

注:原始图片来自 https://ebpf.io,有修改

在安全中的攻击性场景下,能够将 BPF 程序卸载到网卡上执行是一件非常 有意义的事情。这意味着 BPF 在网卡上运行,只将过滤后的数据包传递到内核执行。

BPF 技术核心使用场景是跟踪、可观察性、性能分析和安全等方面。

许多最新的检测、监控软件和性能跟踪工具都是基于 BPF 技术,在云原生环境中,BPF 被大量采用(例如 Cilium)。

2.1 BPF 程序,map 和事件

BPF 基础能力就一组核心技术组成。

prog.map.events

这些组成包括:

  • BPF 程序:通常用 C 语言编写,并可翻译成 BPF 字节码,并 JIT 成机器本地指令。【备注:原文有误,已修订】

  • map:用于内核和用户空间通信的双向数据结构。

  • 事件(Event):BPF 基于事件触发运行,(例如,内核函数的进入 / 退出)。

BPF 程序允许我们在内核空间中运行编写的程序。这种方式与灵活的轻量级内核模块类似,但与内核模块相比,BPF 运行的机制具有更高的可靠性保证。

专用验证器(Verifier)确保 BPF 程序运行是稳定的,不会使操作系统崩溃。

2.2 BPF 程序加载

特权用户通过使用 bpf() 系统调用将 BPF 程序加载到内核。对于大多数 BPF 程序类型(参见 附录 )运行都需要需要 rootCAP_BPF 能力。程序的加载过程大致如下:

  • 加载:用户空间程序在 bpf() 系统调用中使用 BPF_PROG_LOAD 参数加载程序(如需要,还可以创建 map)。

  • 配置:用户空间程序将 BPF 程序与事件/探测关联。例如,通过 ioctl() 调用(例如 PERF_EVENT_IOC_SET_BPF)。

  • 执行:当对应触发事件时,BPF 程序都将在指定的上下文中运行!

上述的这些能力为开发人员(和攻击者)提供了极大的灵活性和能力。

非持久性: BPF 程序并不是持久化的,在机器在重启必须再次启动。

3. 攻防 BPF - 另外的使用场景!

obpf

从非安全角度来看,BPF 程序具有超能力,这非常有趣。据我目前所知,它们可以:

  • hook 系统调用和用户空间函数调用
  • 操作用户空间数据结构
  • 覆盖系统调用返回值
  • 调用 system() 生成新进程( bpftrace 内置特性)
  • 某些 BPF 程序可以卸载到硬件设备(如网卡)
  • 能够针对 BPF 代码的产生链式攻击
  • 与安全和检测工具混合(例如,通过 hook bpf 调用本身)

BPF 攻击程序可能会作为 rootkit 安装在机器上,并且 BPF 也可被用来突破容器限制。这非常令人兴奋,还有一些很好的场景来执行红队行动,以帮助其加强意识和提升检测能力。

4. 入门

使用 BPF 技术有三个等级:

  • 第一等级:利用现有的 BPF 程序,例如,有 sslsniff-bpcc
  • 第二等级:编写少量代码的程序并使用 bpftrace 运行它们。
  • 第三等级:使用 libbpf 和其他较低级别的框架编写更复杂的程序。通过 clang 等工具编译成 BPF 字节码。

当然,你也可以直接使用提供的工具编写 BPF 字节码,这可能是第四等级。

我的目标是更详细地探索其中的每一等级(部分我已经探索过),并展示相关的成功和学习心得。

5. 学习资源

在结束这篇开始的文章时,我想介绍一下我用来入门最有用的资源。对于一般的 BPF 信息、示例代码和代码片段,我发现 Liz RiceBrendan Gregg 的教程非常有用 – 这些教程可以快速帮助你理解 BPF 能做什么,以及其是如何被用来做有意义的事情。

在进阶方面,内容还不多,但这 3 个教程的质量很高:

上述这些教程都提供了很好的见解,而且内容丰富。

6. 资源

7. 附录

BPF 程序有诸多不同的程序类型,如 TRACEPOINT、KPROBE、XDP、PERF_EVENT。

部分特定类型的程序可以由低权限的用户运行。

部分可有权限用户运行的程序类型:

  • BPF_PROG_TYPE_SOCKET_FILTER
  • BPF_PROG_TYPE_CGROUP_SKB

要查看是否启用/禁用了非特权 BPF,可通过执行以下命令查看:

cat /proc/sys/kernel/unprivileged_bpf_disabled

也可如下命令进行禁用 :

sudo sysctl kernel.unprivileged_bpf_disabled=1

原文链接:https://embracethered.com/blog/posts/2021/offensive-bpf/

作者:wunderwuzzi

发布时间: 2021 年 9 月 30 号