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 为我个人创作,并有 自己的仓库。
下表描述了主要源代码文件和目录,以便于导航:
本研究项目已在以下环境中进行测试:
| 发行版 | 内核 | 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 上测试并正常工作)。
模块配置通过以下常量设置:
| 文件名 | 常量 | 说明 |
|---|---|---|
从攻击者机器接收反向 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 客户端程序远程控制后门:
| 客户端参数 | 操作描述 |
| ------------- | ------------- |
| ./injector -c \<受害者 IP\> | 通过执行劫持模块生成一个明文伪 shell |
| ./injector -e \<受害者 IP\> | 通过基于模式的触发器命令后门生成加密伪 shell |
| ./injector -s \<受害者 IP\> | 通过多包触发器(两种类型)命令后门生成加密伪 shell |
| ./injector -p \<受害者 IP\> | 通过基于模式的触发器命令后门生成幻影 shell |
| ./injector -a \<受害者 IP\> | 命令 rootkit 激活所有 eBPF 程序 |
| ./injector -u \<受害者 IP\> | 命令 rootkit 分离其所有 eBPF 程序 |
| ./injector -S \<受害者 IP\> | 展示后门如何隐藏内核中的消息(简单 PoC) |
| ./injector -h | 显示帮助 |
### 后门触发器
操作通过后门触发器发送给后门,触发器根据属性 **K3** 的值指示后门要执行的操作:
| K3 值 | 操作 |
| ------------- | ------------- |
| 0x1F29 | 请求启动加密伪 shell 连接 |
| 0x4E14 | 请求启动幻影 shell 连接 |
| 0x1D25 | 请求加载并附加所有 rootkit eBPF 程序 |
| 0x1D24 | 请求分离所有 rootkit eBPF 程序(后门的除外) |
#### 基于模式的触发器
该触发器隐藏命令和客户端信息,使其能够被后门识别,同时对外部网络监控者而言看似随机。它基于最近发现的 NSA rootkit [Bvp47](https://www.pangulab.cn/files/The_Bvp47_a_top-tier_backdoor_of_us_nsa_equation_group.en.pdf) 所使用的触发器。
<img src="https://assets.kitploit.com/production/public/readmes/5614/58cec7ee2dbd89b6c7d71d60c006a1a98d7b9165b20bdbe006467a82d5dc30ab.png" float="left">
#### 多包触发器
该触发器由多个 TCP 数据包组成,后门载荷隐藏在数据包头部。此设计基于 Vault 7 泄露中描述的 CIA [Hive](https://wikileaks.org/vault7/document/hive-DevelopersGuide/hive-DevelopersGuide.pdf) 植入程序。使用以下载荷:
<img src="https://assets.kitploit.com/production/public/readmes/5614/45a8348c3d366af4941d9cca845c281fc8c5a565353fc8fe3fb91350f39dd5f8.png" float="left">
然后对上述载荷计算滚动 XOR,并根据 rootkit 客户端选择的模式将其分成多个部分。TripleCross 支持隐藏在 TCP 序列号中的载荷:
<img src="https://assets.kitploit.com/production/public/readmes/5614/2b9d7fd46f7133e3eeda694e0b4791fbed2a51616b7d2f14e989a9e0e56af9e2.png" float="left">
以及隐藏在 TCP 源端口中的载荷:
<img src="https://assets.kitploit.com/production/public/readmes/5614/1a6ea6da628a9902eaf55cc3c1549a2ecf26cba211275acdce6bc5491b34140c.png" float="left">
### 后门伪 shell
客户端可以建立 rootkit 伪 shell,这是一种特殊的 rootkit 到 rootkit 客户端连接,模拟 shell 程序,使攻击者能够远程执行 Linux 命令并获取结果,如同直接在受害机上执行一样。我们的 rootkit 融入了多种伪 shell:
#### 明文伪 shell
该 shell 在执行劫持模块成功运行后生成,该模块将执行一个恶意文件,建立与 rootkit 客户端的连接,如下所示:
<img src="https://assets.kitploit.com/production/public/readmes/5614/6495b5b62c33ae136b8c965658d9c5f501e609029bde7fcefe7266966f8effbb.png" float="left">
<img src="https://assets.kitploit.com/production/public/readmes/5614/5301e208d9853760eabdc14772c57a3639f28d71d050ee82d151bff93a76cedf.png" float="right">
#### 加密伪 shell
rootkit 客户端可以随时请求加密伪 shell,它由 rootkit 与 rootkit 客户端之间的 TLS 连接组成。在加密连接内部,遵循传输协议来通信命令和信息,与明文伪 shell 类似。
生成加密伪 shell 需要后门监听触发器,可以接受基于模式的触发器或两种类型的多包触发器:
<img src="https://assets.kitploit.com/production/public/readmes/5614/d4929247af8895f78522f28c4ac8087e74d76b91320c67e0b37ea841cd8869d0.png" float="left">
<img src="https://assets.kitploit.com/production/public/readmes/5614/6e2a72d04028212a4917397b75b052a4bdf3c0529fb6c5e336b7fc0a06571728.png" float="right">
#### 幻影 shell
幻影 shell 使用 XDP 和 TC 程序的组合来克服 eBPF 在网络方面的限制,特别是它不能生成新数据包。为此,后门修改现有流量,用 C2 传输的数据覆盖载荷。原始数据包不会丢失,因为 TCP 重传会在短时间内再次发送原始(未经修改的)数据包。
以下协议说明了使用幻影 shell 执行命令期间的流量:
<img src="https://assets.kitploit.com/production/public/readmes/5614/0aafe6b672757e4e9d37402c72ce14893a8a7f198030b2f2386df631c345d16b.png" float="left">
幻影 shell 由 rootkit 客户端请求,该客户端发出要由后门执行的命令:
<img src="https://assets.kitploit.com/production/public/readmes/5614/e07dec48ff6a22e708b6d4b0d762473cc6483f065011cd6cdccdac49f12f916b.png" float="left">
受害机发送任何 TCP 数据包后,后门将其覆盖,客户端显示响应:
<img src="https://assets.kitploit.com/production/public/readmes/5614/19bea585b78a0bb1d52aa7c63ff05a0111551a0cc767732775491641e1dec021.png" float="left">
## 执行劫持模块
原则上,eBPF 程序不能自行启动程序的执行。此模块展示恶意 rootkit 如何利用良性程序在用户空间执行恶意代码。该模块实现两个目标:
* 借助其他程序的执行来启动恶意用户程序。
* 对用户空间透明,即如果我们劫持某个程序的执行以运行另一个程序,原程序也应尽快执行。
该模块通过劫持 sys_execve() 系统调用工作,修改其参数以便运行恶意程序(*src/helpers/execve_hijack.c*)。这种修改方式使得恶意程序随后可以执行原始程序及其原始参数,以避免在用户空间引起怀疑。下图总结了整体功能:
<img src="https://assets.kitploit.com/production/public/readmes/5614/601610696506e303f91a7957ec2a3d61f73f7d0e036430a9f67bd80a6f19b2d3.png" float="left">
原始 sys_execve() 调用的参数被修改,使得原始参数不会丢失(使用 argv[0]),以便在恶意程序之后可以执行原始程序:
<img src="https://assets.kitploit.com/production/public/readmes/5614/e483317a3bdac422cdfc49ca92acdcefe624ddceb5b2ed036ccec141c8d1e5e6.png" float="left">
我们融入了示例测试程序(*src/helpers/simple_execve.c*)用于测试执行劫持模块。该模块还可以劫持系统中的任何调用,具体取决于配置:
| 文件名 | 常量 | 描述 |
| ------------- | ------------- | ------------- |
| src/common/constants.h | PATH_EXECUTION_HIJACK_PROGRAM | 在成功执行 sys_execve 调用后要执行的恶意程序的位置 |
| src/common/constants.h | EXEC_HIJACK_ACTIVE | 停用 (0) 或激活 (1) 执行劫持模块 |
| src/common/constants.h | TASK_COMM_RESTRICT_HIJACK_ACTIVE | 劫持所有 sys_execve 调用 (0) 或仅劫持 TASK_COMM_NAME_RESTRICT_HIJACK 中指定的调用 (1) |
| src/common/constants.h | TASK_COMM_NAME_RESTRICT_HIJACK | 要从中劫持 sys_execve 调用的程序名称 |
成功劫持后,该模块将自行停止。恶意程序 *execve_hijack* 将监听来自 rootkit 客户端的明文伪 shell 请求。
## Rootkit 持久化
受害机重启后,所有 eBPF 程序将从内核中卸载,用户级 rootkit 程序将被终止。此外,即使 rootkit 可以自动重新运行,它也不再拥有再次附加 eBPF 程序所需的 root 权限。Rootkit 持久化模块旨在应对这两个挑战:
* 在机器重启事件后自动且无需用户交互地执行 rootkit。
* 一旦 rootkit 在机器上首次执行时获得 root 权限,必须保持该权限,即使重启后也是如此。
TripleCross 使用两个秘密文件,分别创建在 *cron.d* 和 *sudoers.d* 下,以实现此功能。这些条目确保 rootkit 在重启后自动加载并拥有完全权限。这些文件由 *deployer.sh* 脚本创建和管理:
<img src="https://assets.kitploit.com/production/public/readmes/5614/88500b779b9ad5ba771803900a8abfffd08f3a6be59518e690534779a4134cf8.png" float="left">
<img src="https://assets.kitploit.com/production/public/readmes/5614/5ae61ed98af6d7c8aa9448fed3de553712ffb5c63e95d98a6f4300ff407bce23.png" float="right">
该脚本包含两个常量,必须配置为要在目标系统上感染的用户:
| 脚本 | 常量 | 描述 |
| ------------- | ------------- | ------------- |
| src/helpers/deployer.sh | CRON_PERSIST | 重启后执行的 cron 作业 |
| src/helpers/deployer.sh | SUDO_PERSIST | 授予无密码权限的 sudo 条目 |
## Rootkit 隐蔽性
持久化模块基于创建额外的文件,但这些文件最终可能被系统所有者或某些软件工具发现,因此将它们留在系统中存在风险。此外,rootkit 文件需要存储在某个位置,它们可能会被发现。
考虑到以上情况,隐蔽性模块提供以下功能:
* 完全隐藏用户可见的目录(以便将所有 rootkit 文件隐藏其中)。
* 隐藏目录中的特定文件(我们需要隐藏持久化文件,但不能完全隐藏 *sudoers.d* 或 *cron.d* 目录,因为它们属于正常系统功能)。
rootkit 隐藏的文件和目录可以通过以下配置常量自定义:
| 文件名 | 常量 | 描述 |
| ------------- | ------------- | ------------- |
| src/common/constants.h | SECRET_DIRECTORY_NAME_HIDE | 要隐藏的目录名称 |
| src/common/constants.h | SECRET_FILE_PERSISTENCE_NAME | 要隐藏的文件名称 |
默认情况下,TripleCross 将隐藏所有名为 "*ebpfbackdoor*" 的文件和名为 "*SECRETDIR*" 的目录。此模块在 rootkit 安装后自动激活。
实现此功能的技术是篡改 sys_getdents() 系统调用的参数:
<img src="https://assets.kitploit.com/production/public/readmes/5614/7f928351c1c07e7b6a534846c5374788449e03455191cddf8c7f02af2c885852.png" float="left">
## 许可证
TripleCross rootkit 和 rootkit 客户端基于 GPLv3 许可证授权。参见 [LICENSE](https://github.com/h3xduck/TripleCross/blob/master/LICENSE)。
[RawTCP_Lib](https://github.com/h3xduck/RawTCP_Lib) 库基于 MIT 许可证授权。
原始论文文档和包含的插图基于 [Creative Commons BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/) 发布。
| 目录 | 说明 |
|---|
| docs | 原始论文文档 |
| src/client | 根工具包客户端的源代码 |
| src/client/lib | RawTCP_Lib 共享库 |
| src/common | 根工具包的常量和配置。还包括 eBPF 和用户空间侧根工具包公共元素的实现,如环形缓冲区 |
| src/ebpf | 根工具包使用的 eBPF 程序的源代码 |
| src/helpers | 包括用于测试多个根工具包模块功能的程序,以及执行劫持和库注入模块中使用的恶意程序和库 |
| src/libbpf | 集成到根工具包中的 libbpf 库 |
| src/user | 根工具包使用的用户空间程序的源代码 |
| src/vmlinux | 包含内核数据结构定义的头文件(这是使用 libbpf 时的推荐方法) |
| 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 地址和端口 |