👋 Приветствую в мире цифровой безопасности!
Расскажу про eBPF с точки зрения безопасности - не просто трейсинг, а как технология меняет и атаку и защиту.
⏺Почему eBPF интересен в контексте ИБ: программы выполняются прямо в ядре с минимальными накладными расходами, видят всё что происходит в системе до того как это попадает в логи, и при этом не требуют написания kernel module. Это одновременно делает eBPF мощным инструментом защиты и потенциально опасным вектором атаки.
⏺Установка инструментов:
apt install bpfcc-tools bpftrace linux-headers-$(uname -r)
⏺Детект reverse shell в реальном времени - ловим процессы которые перенаправляют stdin/stdout в сокет:
# detect_revshell.py через bpfcc from bcc import BPF
prog = """ #include <uapi/linux/ptrace.h> #include <linux/sched.h>
BPF_PERF_OUTPUT(events);
struct data_t { u32 pid; char comm[16]; int fd; };
int trace_dup2(struct pt_regs *ctx, int oldfd, int newfd) { if (newfd <= 2) { struct data_t data = {}; data.pid = bpf_get_current_pid_tgid() >> 32; bpf_get_current_comm(&data.comm, sizeof(data.comm)); data.fd = oldfd; events.perf_submit(ctx, &data, sizeof(data)); } return 0; } """
b = BPF(text=prog) b.attach_kprobe(event="__x64_sys_dup2", fn_name="trace_dup2")
dup2 вызывается когда процесс перенаправляет файловые дескрипторы - именно это делает каждый reverse shell.
⏺Мониторинг execve с аргументами - ловим запуск подозрительных команд:
bpftrace -e ' tracepoint:syscalls:sys_enter_execve { printf("pid=%d comm=%s file=%s\n", pid, comm, str(args->filename)); }'
⏺Детект privilege escalation - ловим момент когда процесс получает uid=0:
bpftrace -e ' kprobe:commit_creds { $cred = (struct cred *)arg0; if ($cred->uid.val == 0 && uid != 0) { printf("ALERT: %s (pid=%d) escalated to root\n", comm, pid); } }'
Срабатывает в момент изменения credentials - до того как процесс успеет что-то сделать с новыми правами.
⏺XDP для блокировки трафика на скорости wire speed - дропаем пакеты до того как они попадут в сетевой стек:
#include <linux/bpf.h> #include <linux/if_ether.h> #include <linux/ip.h> #include <linux/tcp.h>
SEC("xdp") int block_scanner(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 + 1) > data_end) return XDP_PASS;
struct iphdr *ip = (void *)(eth + 1); if ((void *)(ip + 1) > data_end) return XDP_PASS;
struct tcphdr *tcp = (void *)(ip + 1); if ((void *)(tcp + 1) > data_end) return XDP_PASS;
// Блокируем SYN-сканирование — пакеты с только SYN флагом if (tcp->syn && !tcp->ack && !tcp->fin && !tcp->rst) { // Здесь можно добавить логику rate limiting по src IP // через BPF_MAP_TYPE_LRU_HASH } return XDP_PASS; }
⏺Обратная сторона eBPF, как инструмента атаки: исследователи демонстрировали rootkit на eBPF который перехватывает системные вызовы и скрывает файлы и процессы - всё это без kernel module и без записи на диск. Инструмент ebpfkit показал что можно реализовать полноценный backdoor полностью в eBPF который крайне сложно обнаружить стандартными средствами.
⏺Защита от вредоносного использования eBPF: ограничение через Linux capabilities (CAP_BPF требуется для загрузки программ), kernel.unprivileged_bpf_disabled=1 запрещает непривилегированным пользователям загружать eBPF программы, мониторинг загрузки BPF-программ через аудит:
sysctl -w kernel.unprivileged_bpf_disabled=1 auditctl -a always,exit -F arch=b64 -S bpf -k ebpf_load
ZeroDay | Белый Хакер | #eBPF