本文作者:uiop@360SRC
看到越来越多使用eBPF的文章,奈何手边没有高版本的手机,只能使用开发版进行体验,踩了许多坑之后记录一下简单使用过程。
一、ebpf简介
eBPF 是一项革命性的技术,起源于 Linux 内核,可以在操作系统的内核中运行沙盒程序。它被用来安全和有效地扩展内核的功能,而不需要改变内核的源代码或加载内核模块。
eBPF 通过允许在操作系统内运行沙盒程序,应用程序开发人员可以在运行时,可编程地向操作系统动态添加额外的功能。然后,操作系统保证安全和执行效率,就像在即时编译(JIT)编译器和验证引擎的帮助下进行本地编译一样。eBPF 程序在内核版本之间是可移植的,并且可以自动更新,从而避免了工作负载中断和节点重启。
ebpf工作原理
eBPF 程序在事件触发时由内核运行,所以可以被看作是一种函数挂钩或事件驱动的编程形式。从用户空间运行按需 eBPF 程序的价值较小,因为所有的按需用户调用已经通过正常的非 VM 内核 API 调用(“syscalls”)来处理,这里 VM 字节码带来的价值很小。事件可由 kprobes/uprobes、tracepoints、dtrace probes、socket 等产生。这允许在内核和用户进程的指令中钩住(hook)和检查任何函数的内存、拦截文件操作、检查特定的网络数据包等等。
运行 eBPF 程序的步骤
用户空间将字节码和程序类型一起发送到内核,程序类型决定了可以访问的内核区域(主要是 BPF 辅助函数的各种子集)。
内核在字节码上运行验证器,以确保程序可以安全运行(kernel/bpf/verifier.c)。
内核将字节码编译为本地代码,并将其插入(或附加到)指定的代码位置。(如果启用了 JIT 功能,字节码编译为本地代码)。
插入的代码将数据写入环形缓冲区或通用键值 map。
用户空间从共享 map 或环形缓冲区中读取结果值。
eBPF 程序的高层次组件
后端:这是在内核中加载和运行的 eBPF 字节码。它将数据写入内核 map 和环形缓冲区的数据结构中。
加载器:它将字节码后端加载到内核中。通常情况下,当加载器进程终止时,字节码会被内核自动卸载。
前端:从数据结构中读取数据(由后端写入)并将其显示给用户。
数据结构:这些是后端和前端之间的通信手段。它们是由内核管理的 map 和环形缓冲区,可以通过文件描述符访问,并需要在后端被加载之前创建。它们会持续存在,直到没有更多的后端或前端进行读写操作。
二、为什么选择ebpf
Linux内核的主要目的是抽象硬件或虚拟硬件并提供一致的API(系统调用),允许应用程序运行和共享资源。为了实现这一目标,需要维护大量的子系统和层来分配这些职责。每个子系统通常允许某种级别的配置来满足用户的不同需求。如果无法配置所需的行为,则需要更改内核,从历史上看,留下两个选项:
原生支持
更改内核源代码并说服 Linux 内核社区需要进行更改。
等待数年新内核版本才能成为商品。
内核模块
编写内核模块
定期修复它,因为每个内核版本都可能会破坏它
由于缺乏安全边界而存在损坏 Linux 内核的风险 借助 eBPF,可以使用一个新选项,允许对 Linux 内核的行为进行重新编程,而无需更改内核源代码或加载内核模块。在很多方面,这与 JavaScript 和其他脚本语言如何解锁系统的演变非常相似,而系统的改变变得困难或昂贵。
三、开发版上环境搭建
环境搭建
使用rk3588开发版armbian系统+redroid作为开发环境 按照官方wiki刷好最新的armbian系统https://wiki.radxa.com/Rock5/5b/getting\_started 在armbian上使用redroid(新版armbian内核直接可以使用redroid了,也可以直接使用cuttlefish)
安装docker
1
2
3
4
5
6
7
8
9
$ sudo apt
-
get update
$ sudo apt
-
get upgrade
$ curl
-
fsSL test.docker.com
-
o get
-
docker.sh && sh get
-
docker.sh
$ sudo usermod
-
aG docker $USER
$ docker run
-
itd
-
-
rm
-
-
privileged \
-
-
pull always \
-
v ~
/
data:
/
data \
-
p
5555
:
5555
\
redroid
/
redroid:
12.0
.
0
-
arm64
编译支持ebpf功能的内核(如果是ubuntu可以按照官方教程编译)
下载依赖包
1
2
$ sudo apt
-
get update
$ sudo apt
-
get install
-
y git device
-
tree
-
compiler libncurses5 libncurses5
-
dev build
-
essential libssl
-
dev mtools bc python3 dosfstools bison flex rsync u
-
boot
-
tools make
安装python2
1
2
3
4
$ cd
/
usr
/
local
/
lib
/
$ sudo wget https:
/
/
www.python.org
/
ftp
/
python
/
2.7
/
Python
-
2.7
.tgz
$ sudo tar
-
zxvf Python
-
2.7
.tgz
$ sudo ln
-
snf
/
usr
/
local
/
lib
/
Python
-
2.7
/
python
/
usr
/
bin
/
python2
下载内核并修改支持ebpf配置
1
2
3
4
5
6
7
8
$ sudo apt install linux
-
source
-
5.10
.
110
-
legacy
-
rockchip
-
rk3588
$ mkdir kernel
$ cd kernel
/
$ tar
-
xf
/
usr
/
src
/
linux
-
source
-
5.10
.
110
-
rockchip
-
rk3588.tar.xz
$ sudo xz
-
d
/
usr
/
src
/
linux
-
rockchip
-
rk3588
-
legacy_5.
10.110_23
.
02.2_config
.xz
$ cp
/
usr
/
src
/
linux
-
rockchip
-
rk3588
-
legacy_5.
10.110_23
.
02.2_config
.config
$ make mrproper
$ nano .config
修改以下配置
1
2
3
4
5
CONFIG_IKHEADERS
=
y
CONFIG_ASHMEM
=
y
CONFIG_ANDROID_BINDERFS
=
y
CONFIG_KPROBES
=
y
CONFIG_KRETPROBES
=
y
开始编译
1
2
3
4
5
6
$ make
-
j8
$ sudo make modules_install
$ sudo make install
$ cd
/
boot
/
$ sudo mv Image Image.old
$ sudo ln
-
s vmlinuz
-
5.10
.
110
Image
最后重启即可
报错解决
如果出现warning错误而导致的error, forbidden warning kernel/scripts/gcc-wrapper.py
四、ebpf开发环境搭建
1. 切换docker的bridge网络模式为macvlan 创建macvlan注意修改网段及网卡名为自己的
1
$ docker network create
-
d macvlan
-
-
subnet
=
192.168
.
0.0
/
24
-
-
gateway
=
192.168
.
0.1
-
o parent
=
enP4p65s0
-
o macvlan_mode
=
bridge mymacvlan
重新分配ip并启动redroid
1
2
3
4
5
6
$ docker run
-
-
net
=
mymacvlan
-
-
ip
=
192.168
.
0.100
-
itd
-
-
rm
-
-
privileged \
-
v ~
/
data:
/
data \
redroid
/
redroid:
12.0
.
0
-
latest \
androidboot.redroid_width
=
1080
\
androidboot.redroid_height
=
1920
\
androidboot.redroid_dpi
=
480
2. 根据以下两篇文章完成bcc开发环境搭建 https://blog.seeflower.dev/archives/138/ https://blog.seeflower.dev/archives/111/ 修改配置不同处 3. 最后可以获取这样的效果
五、简单体验bcc
1. 执行execsnoop来查看rootbeer的检测点
2. 编写ebpf程序,并绕过root检测 简单看来直接在exec基础上修改系统调用的参数即可绕过检测
参考:
https://blog.seeflower.dev/category/eBPF/ https://ebpf.io/zh-cn/what-is-ebpf/ https://github.com/tiann/bcc/tree/master/tools
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)