TripleCross 是一个 Linux eBPF 根工具包,展示了 eBPF 技术的攻击性能力。
TripleCross 的灵感来源于先前该领域的植入设计,特别是 Jeff Dileo 在 DEFCON 271、Pat Hogan 在 DEFCON 292、Guillaume Fournier 和 Sylvain Afchain 也在 DEFCON 293 的工作,以及 Kris Nóva 的 Boopkit4。我们复用并扩展了这些先前对 eBPF 技术攻击性能力的探索中开创的一些技术。
此根工具包是为我在 UC3M 的学士学位论文创建的。其设计细节在 论文文档 中提供。
此根工具包 纯粹用于教育和学术目的。该软件按“原样”提供,作者不对使用过程中可能发生的任何损害或问题负责。
请勿尝试使用 TripleCross 违反法律。滥用所提供的软件和信息可能导致刑事指控。
下图展示了 TripleCross 及其模块的架构。
用于根工具包传输的原始套接字库 RawTCP_Lib 为我个人创作,并有 自己的仓库。
下表描述了主要源代码文件和目录,以便于导航:
| 目录 | 说明 |
|---|---|
| docs | 原始论文文档 |
| src/client | 根工具包客户端的源代码 |
| src/client/lib | RawTCP_Lib 共享库 |
| src/common | 根工具包的常量和配置。还包括 eBPF 和用户空间侧根工具包公共元素的实现,如环形缓冲区 |
| src/ebpf | 根工具包使用的 eBPF 程序的源代码 |
| src/helpers | 包括用于测试多个根工具包模块功能的程序,以及执行劫持和库注入模块中使用的恶意程序和库 |
| src/libbpf | 集成到根工具包中的 libbpf 库 |
| src/user | 根工具包使用的用户空间程序的源代码 |
| src/vmlinux | 包含内核数据结构定义的头文件(这是使用 libbpf 时的推荐方法) |
本研究项目已在以下环境中进行测试:
| 发行版 | 内核 | GCC | CLANG | GLIBC | |
|---|---|---|---|---|---|
| 版本 | Ubuntu 21.04 | 5.11.0 | 10.3.0 | 12.0.0 | 2.33 |
我们建议使用 Ubuntu 21.04,它默认将包含此处所示的软件版本。否则,您可能会遇到的某些问题描述在 这里。
根工具包源代码使用两个 Makefile 编译。```
cd src make all
cd client make
以下表格详细描述了每个Makefile的用途:
| MAKEFILE | COMMAND | 描述 | 生成的文件 |
| ------------- | ------------- | ------------- | ------------- |
| src/client/Makefile | make | 编译rootkit客户端 | src/client/injector |
| src/Makefile | make help | 编译用于测试rootkit功能的程序,以及执行劫持和库注入模块的恶意程序与库 | src/helpers/simple_timer, src/helpers/simple_open, src/helpers/simple_execve, src/helpers/lib_injection.so, src/helpers/execve_hijack |
| src/Makefile | make kit | 使用libbpf库编译rootkit | src/bin/kit |
| src/Makefile | make tckit | 编译rootkit的TC出口程序 | src/bin/tc.o |
### 安装
一旦rootkit文件在src/bin/下生成,必须按顺序加载*tc.o*和*kit*程序。以下示例中,rootkit后门将在网络接口*enp0s3*上运行:```
// TC egress program
sudo tc qdisc add dev enp0s3 clsact
sudo tc filter add dev enp0s3 egress bpf direct-action obj bin/tc.o sec classifier/egress
// Libbpf-powered rootkit
sudo ./bin/kit -t enp0s3
提供了两个脚本,packager.sh 和 deployer.sh,用于自动编译和安装 rootkit,就像攻击者在真实攻击场景中所做的那样。
这两个脚本首先需要配置以下参数,以确保持久化模块正常运行:
| 脚本 | 常量 | 说明 |
|---|---|---|
| src/helpers/deployer.sh | CRON_PERSIST | 重启后执行的 Cron 任务 |
| src/helpers/deployer.sh | SUDO_PERSIST | 授予无密码权限的 Sudo 条目 |
该 rootkit 能够劫持调用 sys_timerfd_settime 或 sys_openat 系统调用的进程的执行流程。这是通过覆写调用进程虚拟内存中的全局偏移表(GOT)节区来实现的。这会导致一个恶意库(src/helpers/injection_lib.c)被执行。该库会向攻击者机器反弹一个 shell,然后将执行流程返回给原始函数,而不会使进程崩溃。
TripleCross 能够绕过常见的 ELF 加固技术,包括:
它还兼容 Intel CET 技术。
该模块的功能可以通过两个测试程序 src/helpers/simple_timer.c 和 src/helpers/simple_open.c 来验证。或者你也可以尝试劫持任何系统进程(已在 systemd 上测试并正常工作)。
模块配置通过以下常量设置:
| 文件名 | 常量 | 说明 |
|---|---|---|
| src/common/constants.h | TASK_COMM_NAME_INJECTION_ TARGET_TIMERFD_SETTIME | 在 syscall sys_timerfd_settime 处劫持的进程名称 |
| src/common/constants.h | TASK_COMM_NAME_INJECTION_ TARGET_OPEN | 在 syscall sys_openat 处劫持的进程名称 |
| src/helpers/injection_lib.c | ATTACKER_IP & ATTACKER_PORT | 攻击者机器的 IP 地址和端口 |
从攻击者机器接收反向 shell 可以使用 netcat:``` nc -nlvp <ATTACKER_PORT>
### 通过 GOT 劫持技术进行库注入
TripleCross 中采用的技术包含 5 个阶段:
#### 定位 GOT 与返回地址
Rootkit 通过 tracepoint 程序挂钩系统调用。由此,它定位到 GOT 段中 PLT 存根用于调用发起系统调用的 glibc 函数的地址。
为了到达 GOT 段,eBPF 程序利用栈中存储的返回地址。注意:
* .text 对 .plt 进行 *call*,因此 *rip* 作为 *ret* 保存在栈中。
* .plt 通过 .got 对 glibc 进行 *jump*,因此不保存其他 *rip*,也不修改或保存 *rbp* 的值。
* Glibc 发起 *syscall*,不会在栈中保存 *rip*,而是保存在 *rcx* 中。
<img src="https://assets.kitploit.com/production/public/readmes/5614/d216fa5b7b656bb52587027db28f3e3902fa8389d0b2944a1f7e870d6d2e6bee.jpg" float="left">
因此,为了从 eBPF 检查栈中某个地址是否为能引导我们到达正确 GOT 的返回地址,我们必须检查它是否为 PLT 存根的返回地址,该存根使用的 GOT 地址跳转到发起我们从 eBPF 挂钩的系统调用的 glibc 函数。
已融入两种查找返回地址的技术:
* 对于 sys_timerfd_settime,eBPF 程序利用系统调用参数向前扫描。
* 对于 sys_openat,eBPF 程序利用 tracepoints 的 *pt_regs* 结构体中的数据进行返回地址的扫描。
<img src="https://assets.kitploit.com/production/public/readmes/5614/61217fb3fd84bec65cbbee906dd27860e5e1c211912cfe450ea4cf9051fa480b.png" float="left">
#### 定位 shellcode 的关键函数
Shellcode 必须动态生成,以绕过 ASLR 和 PIE,它们会在每次程序执行时改变 dlopen() 等函数的地址。
<img src="https://assets.kitploit.com/production/public/readmes/5614/6cbb620495d8cb9711e499fd5b1ae9ea845c03d0c33019cf008b456a95d5ddd6.png" float="left">
#### 在代码洞穴中注入 shellcode
如果 ASLR 和 PIE 关闭,可以通过逆向工程 ELF 找到代码洞穴,但通常情况并非如此。eBPF 程序向用户空间 rootkit 程序发出请求,该程序利用 /proc 文件系统在 .text(可执行)段中的代码洞穴内定位并写入内容。
<img src="https://assets.kitploit.com/production/public/readmes/5614/c7daea0eed684437b5c7d971d0f69f5aac9138861d44da36c5368be9f97666d1.png" float="left">
#### 覆盖 GOT 段
根据可执行文件启用了部分 RELRO 还是完全 RELRO,eBPF 程序直接覆盖 GOT 段,或者通过 /proc 文件系统进行覆盖。
<img src="https://assets.kitploit.com/production/public/readmes/5614/7e69ec2982ee8c77c39b42f364ab25e52c40d96890f7413b3afe04dde1b825c3.png" float="left">
#### 等待下一次系统调用
当被劫持的程序发起下一次系统调用时,PLT 段使用修改后的 GOT 段,劫持执行流程使其重定向到代码洞穴中的 shellcode。Shellcode 已准备好防止程序崩溃,并调用恶意库(*src/helpers/lib_injection.so*)。该库执行 fork() 并生成与攻击机之间的反向 shell。之后执行流程被恢复。
<img src="https://assets.kitploit.com/production/public/readmes/5614/4e780cbcba855fe11a55f6a34709d83d855a4235960b15b69470233147f04318.png" float="left">
## 后门与 C2
后门无需任何配置即可开箱即用。可以使用 rootkit 客户端程序远程控制后门: