0x01 研究细节
这里粗略提一下使用EBPF技术做恶意利用时候的优点:
-
稳定,EBPF程序出错时不会影响内核运行。
-
更不易被感知,即使是内核模块方式实现的HIDS。
一、恶意利用
1. 网络层
a. 依赖库BCC
BCC库安装参考:https://github.com/iovisor/bcc/blob/master/INSTALL.md
b. 代码文件:
-
用户层XDP Loader
#!/usr/bin/env python3
from bcc import BPF
import time
device = "lo"
b = BPF(src_file = "filter.c")
fn = b.load_func("udpfilter", BPF.XDP)
b.attach_xdp(device, fn, 0)
try:
b.trace_print()
except KeyboardInterrupt:
pass
b.remove_xdp(device, 0)
-
XDP程序
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/udp.h>
#define KBUILD_MODNAME "filter"
int udpfilter(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if((void*)eth + sizeof(*eth) <= data_end) {
struct iphdr *ip = data + sizeof(*eth);
if((void*)ip + sizeof(*ip) <= data_end) {
if(ip->protocol == IPPROTO_UDP) {
struct udphdr *udp = (void*)ip + sizeof(*ip);
if ((void*)udp + sizeof(*udp) <= data_end) {
if (udp->dest == ntohs(9999)) {
bpf_trace_printk("UDP Port 9999n");
udp->dest = ntohs(9998);
}
}
}
}
}
return XDP_PASS;
}
c. 测试
2. Linxu系统运行时
该项目提供了好几个易懂但是有效的BPF基于probe、tracepoint的恶意利用方式。
a. Build
安装方式:https://github.com/pathtofile/bad-bpf#Build
b. 代码文件
该项目主要就是基于之前提到的libbpf+CO-RE结构。
其中Sudo-Add:
-
用户层Loader文件为src/sudoadd.c。
-
BPF程序为src/sudoadd.bpf.c。
程序在sys_exit_read这个处理系统调用read返回动作的时候,对“/etc/sudoers”文件进行了修改。添加了目标用户到该文件中。
-
BPF程序为src/pidhide.bpf.c。
程序Hook了getdents64系统调用,该调用会在执行“ps”命令时候触发。这个时候,会将目标pid成进程链表上取下来。
c. 测试一
d. 测试二
0x02 防御
一、运行时
EBPF程序说白了还是需要通过bpf这个系统调用才能运行,那么通过上面这个针对bpf系统调用的探针,就可以对EBPF程序的运行进行监控。
这里提供相关EBPF程序:
truct _sys_enter_bpf
{
__u64 unused;
int syscall_nr;
unsigned long cmd;
unsigned long bpf_attr_addr;
unsigned long size;
};
// TODO: ptrace的hook还有个pid_tree要加,已加
/* bpf */
SEC("tracepoint/syscalls/sys_enter_bpf")
int sys_enter_bpf(struct _sys_enter_bpf *ctx)
{
event_data_t data = {};
if (!init_event_data(&data, ctx))
return 0;
data.context.type = TRACEPOINT_SYSCALLS_BPF;
unsigned long cmd;
bpf_probe_read(&cmd, sizeof(unsigned long), &ctx->cmd);
save_to_submit_buf(&data, &ctx->cmd, sizeof(unsigned long), 0);
events_perf_submit(&data);
return 0;
}
a. 直接运行EBPF程序
b. 命令行执行EBPF程序
#include <linux/bpf.h>
#ifndef __section
#define __section(NAME)
__attribute__((section(NAME), used))
#endif
__section("prog")
int xdp_drop(struct xdp_md *ctx) {
return XDP_DROP;
}
char __license[] __section("license") = "GPL";
CC=/usr/bin/clang-11 CXX=/usr/bin/clang++-11 clang -O2 -g -Wall -target bpf -c ip_xdp.bpf.c -o ip_xdp.bpf.o
二、运行后
ip命令也可以查看和它自己相关的EBPF程序。
0x03 总结
参考链接:
-
https://defcon.org/html/defcon-29/dc-29-speakers.html#path 【相关的参考资料】
-
https://github.com/pathtofile/bad-bpf 【相关的参考资料】
-
https://github.com/iovisor/bcc 【相关的参考资料】
-
https://duo.com/labs/tech-notes/writing-an-xdp-network-filter-with-ebpf 【相关的参考资料】
银河实验室
往期回顾
技术
技术
技术
技术
长按识别二维码关注我们
微信号:PSRC_Team
球分享
球点赞
球在看
原文始发于微信公众号(平安集团安全应急响应中心):EBPF恶意利用及防御