聊一聊基于“ebpf xdp“的rootkit

本文探讨了XDP(eXpress Data Path)后门相较于BPF后门的优势,如更隐蔽,无法通过tcpdump捕获流量。作者分享了一个XDP UDP后门的实现Demo,并介绍了遇到的加载错误及其解决方案。此外,还讨论了如何检测XDP后门,并提到了使用bpftool进行程序和地图信息检查。最后,文章提及了一个名为TripleCross的完善XDP后门实例。

声明

以下内容,来自先知社区的leveryd作者原创,由于传播,利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人负责,长白山攻防实验室以及文章作者不承担任何责任。

背景

在《全流量入侵检测系统的性能分析》中提到"包解析需要高性能"这个需求场景,和 pf_ring、dpdk 类似,xdp也是一种经常被讨论的高性能包处理技术。

在《lkm和ebpf rootkit分析的简要记录》中提到一个基于ebpf实现的rootkit boopkit。这个后门通信部分当前是基于libpcap,还有一个未公开的xdp实现。

因此我感觉xdp在网络编程、网络安全上都能应用上,值得研究。于是我从实现"xdp ebpf后门"来学习xdp。

本文主要记录以下内容,希望对主机安全有兴趣的读者有点帮助。内容包括:

  • xdp ebpf后门相比于 bpf 后门的优点

  • xdp后门demo

  • demo编写时的关键点

  • 检测角度来看,xdp后门的特征

关于ebpf和xdp的背景知识你可以参考《Linux网络新技术基石 |eBPF and XDP》

xdp ebpf后门和bpf后门对比

已经有了bpf后门,为什么还有人要研究xdp ebpf后门呢?

在实现后门时,xdp ebpf和bpf技术都是为了获取数据包,可以做到不需要监听端口、客户端可以向服务端做单向通信。它俩的区别在于,xdp ebpf后门比bpf后门更加隐蔽,在主机上用tcpdump可以抓取bpf后门流量,但无法抓取xdp ebpf后门流量。

为什么会这样呢?

bpfdoor 、 boopkit 等bpf后门都是基于af_packet抓包、bpf filter过滤包,它工作在链路层。

关于bpfdoor的分析可以参考 BPFDoor - An Evasive Linux Backdoor Technical Analysis

xdp有三种工作模式,不论哪一种模式,在接收数据包时都比bpf后门要早。

tcpdump这种抓包工具的原理和bpf后门是一样的,也是工作在链路层。所以网卡接收到数据包后,会先经过xdp ebpf后门,然后分别经过bpf后门和tcpdump。

如果xdp ebpf后门在接收到恶意指令后把数据包丢掉,tcpdump就抓不到数据包。

xdp后门demo

demo的源码我放到了github上:

https://github.com/leveryd/ebpf-app/tree/master/xdp_udp_backdoor

最终实现了的后门demo效果如下, 控制端通过udp协议和被控端单向通信,被控端从通信流量中提取出payload后执行命令。

图片

  • 通信数据格式是:| eth header | ip header | udp header | MAGIC_START command MAGIC_END |

  • 被控端(xdp程序)提取udp数据后,通过BPF_MAP_TYPE_ARRAY类型的map将udp数据传给用户态程序

  • 用户态程序执行system(command)执行系统命令后,清理map数据

关于xdp编程的基本概念,我就不复述网络上已有的内容了。如果你和我一样是ebpf xdp新手,我推荐你看 Get started with XDP 这篇入门文章。另外代码注释中的参考文章也不错。

在实现demo、加载xdp程序时,我遇到过两个报错。如果你也遇到,就可以参考我的解决办法。

第一个报错如下

root@08363214ec12:/mnt# ip link set eth0 xdpgeneric obj xdp_udp_backdoor_bpf.o sec xdp_backdoor
BTF debug data section '.BTF' rejected: Invalid argument (22)!
 - Length:       741
Verifier analysis:
...

这个报错的原因是某些ip命令不支持btf。如果你想要解决这个报错,有两种方式,一是centos系统上可以用xdp-loader工具替代ip命令加载xdp程序,二是基于libbpf库的bpf_set_link_xdp_fd接口编程实现加载xdp程序,就像demo中那样。

第二个报错如下,提示 BPF程序指令过多,超过1000000条的限制。

[root@instance-h9w7mlyv xdp_backdoor]# make load
[root@instance-h9w7mlyv xdp_backdoor]# make load
clang -O2 -g -Wall -target bpf -c xdp_udp_backdoor.bpf.c -o xdp_udp_backdoor_bpf.o
ip link set eth0 xdpgeneric off
ip link set eth0 xdpgeneric obj xdp_udp_backdoor_bpf.o sec xdp_backdoor
...
BPF program is too large. Processed 1000001 insn
processed 1000001 insns (limit 1000000) max_states_per_insn 18 total_states 18267 peak_states 4070 mark_read 5
libbpf: -- END LOG --
libbpf: failed to load program 'xdp_func'
libbpf: failed to load object 'xdp_udp_backdoor_bpf.o'

这个报错的原因是在加载ebpf程序时,会经过内核中ebpf Verification的校验,其中它会检查是否有ebpf程序是否可能出现死循环。

下面代码编译后的ebpf程序就会检查失败,出现上面的报错信息

void mystrncpy(char *dest, const char *src, size_t count)
{
      char *tmp = dest;
      // #pragma clang loop unroll(full)
      while (count) {
              if ((*tmp = *src) != 0)
                      src++;
              tmp++;
              count--;
      }
}

可以尝试使用#pragma clang loop unroll(full)告诉编译器编译时对循环做展开,来解决这个报错问题。

这个解决办法是在 https://rexrock.github.io/post/ebpf1/ 文中看到的

检测:xdp后门的特征

bpftool prog能看到xdp程序信息、bpftool map能看到xdp程序和应用程序通信用到的map信息

图片

应用程序文件描述符中也有map id信息

图片

应用程序想要执行命令时也会有一些特征,比如demo中使用system执行系统命令时,会有fork系统调用。

应用程序如果想要将命令结果回传、或者反弹shell,主机上也能抓到这一部分流量。

总结

xdp概念、xdp编程的知识都在参考链接中,本文非常粗浅地分析一点xdp后门的优点和检测方式,希望能对你有点帮助。

在搞完这个demo后,我才发现有一个看起来很完善的xdp后门TripleCross。

在研究ebpf和主机安全过程中,参考了美团师傅博客上的几篇文章,博客链接是 https://www.cnxct.com/

### 三级标题:XDP 技术概述 XDP(Express Data Path)是种用于快速数据包处理的技术,它允许在数据包到达网络堆栈的最早阶段进行处理。这意味着,在数据包进入操作系统协议栈之前,eBPF 程序就可以对其进行过滤、丢弃、转发或重定向[^2]。 ### 三级标题:eBPFXDP 模式下的优势 eBPF 的高性能网络处理能力使其成为 DDoS 防御的理想选择,尤其是在 XDP 模式下。通过直接访问数据包的DMA缓冲区,从网络驱动程序运行特定类型的 BPF 程序,可以实现对数据包的高效处理[^3]。 ### 三级标题:应用实例 #### SYN Flood 防御 在 XDP 层对传入的 SYN 包进行分析,如果发现大量的无效 SYN 包或来自同源 IP 的大量 SYN 包,可以直接丢弃这些包,而不必让它们占用内核资源,从而有效缓解 SYN Flood 攻击[^2]。 #### UDP Flood 防御 对于 UDP Flood 攻击,eBPF 可以在 XDP 层识别并丢弃大量伪造源 IP 的 UDP 包[^2]。 #### IP 黑白名单 直接在 XDP 层实现 IP 黑白名单过滤,将恶意 IP 的流量在早期阶段就阻断,保护后端服务[^2]。 #### 协议解析与流量分类 eBPF 程序可以解析数据包头部,识别协议类型(TCP、UDP、ICMP、HTTP 等),并根据流量特征进行分类,将恶意流量与合法流量分离[^2]。 #### Rate Limiting(速率限制) 对特定源 IP、目的端口或协议的流量进行速率限制。当某个 IP 地址的请求速率超过阈值时,eBPF 程序可以临时丢弃或延迟来自该 IP 的数据包,防止其耗尽服务器资源[^2]。 #### Bypassing Kernel Stack 对于需要快速响应的 DDoS 攻击,传统方法需要数据包遍历整个内核网络堆栈,效率较低。XDP eBPF 直接在数据链路层操作,绕过了大部分内核网络堆栈,大大提高了处理速度和吞吐量[^2]。 ### 代码示例 下面是个简单的 eBPF 程序示例,展示了如何编写个基本的 XDP 程序: ```c #include <vmlinux.h> #include <bpf/bpf_helpers.h> SEC("xdp") int xdp_prog_simple(struct xdp_md *ctx) { void *data = (void *)(long)ctx->data; void *data_end = (void *)(long)ctx->data_end; struct ethhdr *eth = data; if (eth + 1 > data_end) return XDP_DROP; /* Example: Drop all packets */ return XDP_DROP; } char _license[] SEC("license") = "GPL"; ``` ### 三级标题:总结 随着网络带宽的不断增加,大型网站的不断出现,导致大规模的并发不断出现,从而使得数据量以无法想象的速度快速增长。通用型的设计在面对这些场景时往往力不从心。XDP 技术就是为了解决这个问题而设计的,它利用 eBPF 的可编程特性,实现了在网络堆栈中最先处理数据包的能力,从而显著提升了性能[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值