ANTICHAT

ANTICHAT (https://forum.antichat.io/index.php)
-   Этичный хакинг или пентестинг (https://forum.antichat.io/forumdisplay.php?f=209)
-   -   Обход EDR Linux: syscall evasion, io_uring и eBPF-атаки для пентестеров (https://forum.antichat.io/showthread.php?t=592859)

Сергей Попов 27.04.2026 12:27

https://forum.antichat.xyz/attachmen...b117797f11.png

Когда на engagement'е попадается Linux-хост с EDR-агентом, первый рефлекс - понять, что именно этот зверь перехватывает. На Windows ответ давно каталогизирован: ntdll-хуки, ETW-провайдеры, kernel callbacks. На Linux картина другая. Агенты разных вендоров используют принципиально разные источники телеметрии - от auditd до eBPF-сенсоров и частных kernel-модулей (проприетарных). И у каждого подхода свои слепые зоны. Вот их-то мы и будем эксплуатировать.

По данным Kaspersky Incident Response, уязвимости в публично доступных приложениях стали первопричиной 39% состоявшихся инцидентов. При этом, согласно CrowdStrike 2025 Global Threat Report (данные цитирует Vectra AI), 82% детектов приходятся на malware-free активность - credential theft, living-off-the-land и identity-based атаки, которые Linux EDR особенно плохо отслеживает. Обход EDR Linux перестал быть прерогативой APT-групп: готовые EDR bypass-инструменты продаются на подпольных форумах от 300 долларов.

Разберём три фундаментальных вектора обхода EDR на Linux для пентестеров (общий арсенал и контекст - в руководстве по Linux для пентестера): прямые syscall'ы минуя glibc, злоупотребление io_uring и наступательное использование eBPF. Для каждого - конкретный механизм, почему он работает и что проверять на своих хостах.
Как Linux EDR собирает телеметрию и что именно хукается
Чтобы понять, как работают Linux EDR bypass методы, нужно сначала разобрать, что агент видит. Телеметрия на Linux собирается тремя способами, и у каждого характерные дыры.
Три уровня перехвата: auditd, eBPF и kernel modules
Auditd (Linux Auditing System) - самый старый и совместимый механизм. Агент подписывается на события аудита ядра: запуск процессов (
Код:

execve
), открытие файлов, сетевые подключения. Проблема в том, что auditd работает как очередь с ограниченным числом потребителей. Если на хосте уже крутится compliance-система, подписанная на audit events, EDR конкурирует за тот же поток. По данным Kaspersky, даже компании с развёрнутым EDR на серверах вынуждены прописывать широкие исключения в правилах мониторинга ради производительности. Результат - часть syscall'ов тупо не попадает в телеметрию.

https://forum.antichat.xyz/attachmen...7310522183.png

eBPF-сенсоры - современный подход, который используют Falco, Tracee и коммерческие решения вроде BI.ZONE EDR. Агент загружает eBPF-программы, которые цепляются к kprobes (точки входа в kernel-функции) и tracepoints (предопределённые точки трассировки). Например, kprobe на
Код:

__x64_sys_execve
перехватит запуск любого процесса, а tracepoint
Код:

sched:sched_process_exec
- событие планировщика. eBPF не так сильно бьёт по производительности, как auditd, но реализация различается между ядрами. По данным Cymulate, для работы BTF и CO-RE (Compile Once, Run Everywhere) целевое ядро должно быть собрано с
Код:

CONFIG_DEBUG_INFO_BTF=y
- а это есть далеко не на всех серверах. Лично я на engagement'ах регулярно встречаю RHEL 7 и CentOS 7, где BTF и не пахнет.

Проприетарные kernel-модули - отдельные вендоры идут дальше. Kaspersky внедрил технологию UKLM (Universal Linux Kernel Module), которая обрабатывает события через собственный драйвер уровня ядра и, по заявлению вендора, снижает влияние на производительность в 20 раз по сравнению с auditd. Такие модули дают максимальную видимость, но создают зависимость от конкретной версии ядра и дистрибутива.

Ключевой вывод: определите, какой механизм использует конкретный EDR-агент - от этого зависит, на каком уровне нужно работать, чтобы остаться невидимым.
Syscall hooking Linux evasion: прямые вызовы ядра минуя glibc
Большинство пользовательских программ вызывают syscall'ы не напрямую, а через обёртки glibc:
Код:

execve()

Код:

__libc_execve()
→ инструкция
Код:

syscall
. Часть EDR-агентов ставит uprobes именно на функции glibc или использует
Код:

LD_PRELOAD
для перехвата вызовов в userspace. Это первый и самый простой барьер, который можно обойти.

На Linux, в отличие от Windows, номера syscall'ов стабильны между версиями ядра одной архитектуры. Таблица определена в
Код:

arch/x86/entry/syscalls/syscall_64.tbl
и практически не меняется. Никакой SysWhispers не нужен - достаточно знать номер.

Минимальный пример вызова
Код:

execve
(syscall 59 на x86_64) напрямую, минуя glibc:

C:


Код:

#include
long
raw_execve
(
const
char
*
path
,
char
*
const
argv
[
]
,
char
*
const
envp
[
]
)
{
long
ret
;
__asm__
volatile
(
"syscall\n"
:
"=a"
(
ret
)
:
"0"
(
59
)
,
"D"
(
path
)
,
"S"
(
argv
)
,
"d"
(
envp
)
:
"rcx"
,
"r11"
,
"memory"
)
;
return
ret
;
}

Компилируйте с
Код:

gcc -nostdlib -nostartfiles -fno-stack-protector -static
(при этом нужно определить собственную точку входа
Код:

_start
, например:
Код:

void _start() { char *argv[]={"bin",NULL}; raw_execve("/bin/sh",argv,NULL); asm("mov $60,%rax; xor %rdi,%rdi; syscall"); }
) - итоговый бинарь не затронет ни одну функцию glibc. Если EDR ставил uprobe на glibc-обёртки (
Код:

__libc_execve
,
Код:

execvp
с PATH-resolution) - он этот вызов не увидит.

Что по-прежнему ловит прямой syscall: kprobes на kernel-стороне (
Код:

__x64_sys_execve
), tracepoints (
Код:

sys_enter_execve
), auditd с правилом
Код:

-a always,exit -F arch=b64 -S execve
, seccomp-BPF фильтры. Они перехватывают на уровне входа в ядро, до dispatch'а в конкретный handler.

Прямые syscall'ы - не серебряная пуля. Они обходят userspace-хуки, но не kernel-level мониторинг. Тем не менее на практике я регулярно встречаю агенты, которые полагаются исключительно на LD_PRELOAD или uprobe-перехват - для них этой техники за глаза.

Практический подход для пентеста Linux и обхода защиты: напишите свой лоадер на C или Go с прямыми syscall'ами для критических операций -
Код:

execve
,
Код:

openat
,
Код:

connect
,
Код:

mmap
,
Код:

mprotect
. Стандартные операции (чтение конфигов, вывод в stdout) оставьте через glibc - они не триггерят алерты.
io_uring - слепая зона для обхода EDR на Linux
Если прямые syscall'ы обходят userspace-хуки, но остаются видны ядерному мониторингу, то io_uring создаёт проблему другого масштаба: операции выполняются в ядре, но не через те syscall entry points, на которых стоят kprobes EDR-агента.

https://forum.antichat.xyz/attachmen...7310578911.png

io_uring - интерфейс асинхронного ввода-вывода, появившийся в ядре Linux 5.1 (2019). Работает через два кольцевых буфера в shared memory: Submission Queue (SQ), куда процесс помещает запросы, и Completion Queue (CQ), откуда забирает результаты. После начальной настройки через
Код:

io_uring_setup
дальнейшие операции не требуют отдельных syscall'ов - ядро забирает запросы из SQ автономно.

И вот тут-то начинается самое интересное для уклонения от обнаружения Linux-хостов. EDR-агенты, использующие kprobes на syscall entry points (
Код:

x64_sys_read


,
Код:


Код:

x64_sys_write
,
Код:

_x64_sys_connect


) или syscall tracepoints (
Код:

sys_enter
Код:

*
), не видят аналогичные операции через io_uring. Агенты, хукающие VFS-уровень (
Код:

vfs_read
,
Код:

vfs_write
) или использующие LSM-hooks, могут перехватить и io_uring-операции, потому что внутри ядра io_uring вызывает те же функции. Но таких агентов - меньшинство. По данным Vectra AI, большинство Linux EDR-решений не мониторят io_uring, что создаёт серьёзный пробел в детектировании для серверных окружений.
RingReaper: разбор техник по MITRE ATT&CK
RingReaper - пост-эксплуатационный агент, созданный как PoC для демонстрации этой слепой зоны. По данным Picus Security, он полностью заменяет стандартные утилиты разведки io_uring-аналогами:

ЗадачаОбычный подходRingReaper (io_uring)MITRE ATT&CKСписок процессов
Код:

ps aux
через /procАсинхронное чтение /proc через SQProcess Discovery (T1057)Сетевые подключения
Код:

netstat
/
Код:

ss
Запрос kernel network tablesSystem Network Connections Discovery (T1049)Активные сессии
Код:

who
/
Код:

w
Чтение /dev/pts через io_uringSystem Owner/User Discovery (T1033)Чтение /etc/passwd
Код:

cat /etc/passwd
Асинхронное чтение через SQData from Local System (T1005)Поиск SUID-бинарей
Код:

find / -perm -4000
Проверка через io_uringExploitation for Privilege Escalation (T1068)Самоудаление
Код:

rm -f
Асинхронный unlinkIndicator Removal: File Deletion (T1070.004)

Каждая из этих операций тривиальна по отдельности. Но когда они идут через io_uring, eBPF-based EDR с kprobes на
Код:

sys_read
,
Код:

sys_openat
,
Код:

sys_unlink
их просто не видит. При этом для базовых io_uring-операций чтения root не нужен -
Код:

io_uring_setup
доступен непривилегированным пользователям на хостах без явного запрета (sysctl
Код:

kernel.io_uring_disabled
появился только в ядре 6.6). Docker default seccomp profile блокирует
Код:

io_uring_setup
начиная с Docker 20.10.10 (октябрь 2021), так что в контейнерах этот фокус обычно не пройдёт.

На современных дистрибутивах (Ubuntu 23.04+, RHEL 9, Debian 12) проверьте
Код:

cat /proc/sys/kernel/io_uring_disabled
- значение 0 разрешает всем, 1 разрешает только процессам с CAP_SYS_ADMIN при создании ring, 2 полностью запрещает. Если 0 - вам повезло, io_uring один из самых практичных методов обхода EDR на Linux при пентесте.
eBPF evasion техники: мониторинг как оружие атакующего
eBPF позволяет динамически загружать программы в ядро Linux. По данным Cymulate, через kprobe/tracepoint/LSM hooks он даёт возможность наблюдать syscall'ы, точки входа и выхода функций ядра и userspace, сетевые события. Модификация поведения ограничена:
Код:

bpf_override_return
работает только для функций с
Код:

ALLOW_ERROR_INJECTION
. Но та же мощь делает eBPF идеальным инструментом для атакующего - и тут ирония: EDR-вендоры сами приучили ядро доверять eBPF-программам.

С 2023 года появилось несколько руткитов на eBPF:
Код:

ebpfkit
,
Код:

TripleCross
,
Код:

Pamspy
. Они перехватывают учётные данные, обходят файрволы и слепят EDR-агенты. Разберём три наступательных сценария syscall hijacking Linux через eBPF.

https://forum.antichat.xyz/attachmen...7310623888.png

Ослепление телеметрии - Indicator Blocking (T1562.006, Defense Evasion). Атакующий загружает eBPF-программу, которая цепляется к тем же kprobes, что и EDR, но с более высоким приоритетом. Она модифицирует данные, которые видит агент: скрывает процессы, фильтрует сетевые события, подменяет содержимое файлов. По анализу Red Canary (цитирует windshock.github.io), однажды загруженное eBPF-вредоносное ПО, может скрытно изменять результаты
Код:

bpftool
и
Код:

debugfs
, делая пост-компрометационное обнаружение крайне затруднительным. По сути, EDR смотрит на мир через линзу, которую контролирует атакующий.

Перехват учётных данных.
Код:

Pamspy
- eBPF-программа, ставящая uprobe на функции PAM (Pluggable Authentication Modules). Перехватывает пароли в момент аутентификации. Для EDR это выглядит как легитимная eBPF-программа, потому что eBPF и есть легитимная технология ядра. Красота.

Обход файрвола и скрытый C2.
Код:

BPFDoor
, использовавшийся в реальных APT-атаках, вставлял пакетный фильтр в ядро. Хост при этом выглядел так, словно не имеет открытых сетевых портов -
Код:

nmap
показывал чистый результат. По данным windshock.github.io (со ссылкой на Trend Micro), BPFDoor внедрял packet filters в ядро для обхода правил файрвола, маскируясь под отсутствие сетевых сервисов.

Почему обход антивируса Linux через eBPF так эффективен? eBPF-программы не лежат на диске в традиционном смысле. Они работают в kernel space, недоступном для userspace-сканеров. eBPF-руткит может манипулировать данными, которые видит сам антивирус. Традиционный файловый сканер попросту не имеет точки наблюдения для обнаружения eBPF rootkit - он слепой по определению.

По данным Cymulate, добавление
Код:

CAP_PERFMON
или
Код:

CAP_NET_ADMIN
расширяет возможности программы. Исключение -
Код:

BPF_PROG_TYPE_SOCKET_FILTER
, которую может загрузить непривилегированный пользователь, если
Код:

/proc/sys/kernel/unprivileged_bpf_disabled
не установлен в 1 или 2.

Для полноценного eBPF evasion атакующему нужен root. И тут в игру вступают уязвимости повышения привилегий. В sudo до версии 1.9.17p1 опция
Код:

--chroot
позволяет использовать
Код:

/etc/nsswitch.conf
из пользовательского каталога. Атакующий подготавливает вредоносный nsswitch.conf, указывающий на подконтрольную NSS-библиотеку, и выполняет произвольный код от root. Эксплуатация требует, чтобы в sudoers пользователю было разрешено выполнение команды с
Код:

--chroot
(или
Код:

CHROOT=*
в Defaults) - на дефолтных конфигурациях многих дистрибутивов это не так. CISA добавила CVE-2025-32463 в каталог KEV (актуально эксплуатируется в дикой среде, добавлена 2025-09-29). EPSS-оценка - 0.4446 (Top 5% по вероятности эксплуатации в ближайшие 30 дней). Публичные PoC доступны -
Код:

pr0v3rbs/CVE-2025-32463_chwoot
на GitHub (521 звезда).

Цепочка для пентестера: непривилегированный доступ (при наличии sudo с --chroot в sudoers) → эксплуатация CVE-2025-32463 → root → загрузка eBPF-программы для ослепления EDR → выполнение основной задачи.

Из актуального стоит отметить CVE-2025-31161 в CrushFTP (CVSS 9.8 CRITICAL, CWE-305) - authentication bypass через race condition в AWS4-HMAC авторизации, EPSS 0.8621 (Top 1%). CISA включила эту уязвимость в каталог KEV (актуально эксплуатируется в дикой среде, добавлена 2025-04-07) с пометкой об использовании в ransomware-кампаниях.
Практический сценарий: пентест Linux с обходом защиты хоста
Требования к окружению
  • Целевой хост: Linux kernel 5.1+ (для io_uring), дистрибутив с eBPF-поддержкой (ядро 4.4+ с BTF для CO-RE)
  • EDR-агент: Falco, Tracee, CrowdStrike Falcon for Linux, BI.ZONE EDR или аналог
  • Привилегии: для разведки - любой пользователь; для eBPF evasion - root или CAP_BPF
  • Инструменты атакующего: gcc/clang с
    Код:

    -static
    , библиотека liburing, bpftool
Пошаговый алгоритм
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше


Получить доступ просто — достаточно проявить активность на форуме


📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше


Получить доступ просто — достаточно проявить активность на форуме

Обнаружение eBPF rootkit и защита Linux-хостов
Этот раздел - для blue team и для пентестеров, которые пишут рекомендации по итогам engagement'а.

Первое, что нужно проверять - загруженные eBPF-программы и их привязки к сетевым интерфейсам:

Bash:


Код:

bpftool prog show
&&
bpftool map show
for
iface
in
$(ls /sys/class/net/)
;
do
ip
link
show dev
"$iface"
|
grep
-q
"xdp"
\
&&
echo
"[!] XDP attached: $iface"
done
for
iface
in
$(ls /sys/class/net/)
;
do
tc filter show dev
"$iface"
2>
/dev/null
done

Если
Код:

bpftool prog show
показывает программы с типами kprobe, tracepoint или xdp, не принадлежащие известному EDR или мониторингу - повод копать дальше. Но помните: если eBPF-руткит уже активен, он может подменять вывод самого
Код:

bpftool
. Курица и яйцо.

Именно поэтому одного мониторинга недостаточно. По данным windshock.github.io, наиболее эффективна комбинация двух инструментов. Tracee (Aqua Security) работает как камера наблюдения - записывает аномальные eBPF-события в реальном времени. Сам он основан на eBPF и отслеживает загрузку новых программ. LKRG (Linux Kernel Runtime Guard) работает как решётка на окне - активно мониторит целостность структур ядра и предотвращает модификации syscall table, подмену callback'ов и DKOM (Direct Kernel Object Manipulation, техника Rootkit - T1014, Defense Evasion по MITRE ATT&CK).

Tracee без LKRG - записывает, но не блокирует. LKRG без Tracee - блокирует, но не оставляет forensic-следа. Оба вместе дают и детектирование, и предотвращение.

Дополнительные меры для Linux endpoint detection evasion prevention:
  • Установите
    Код:

    sysctl kernel.unprivileged_bpf_disabled=1
    - запретите непривилегированным пользователям загрузку любых eBPF-программ
  • Обновите sudo до 1.9.17p1+ для закрытия CVE-2025-32463
  • Мониторьте процессы с удалёнными исполняемыми файлами, использующие BPF-сокеты: если
    Код:

    readlink /proc/PID/exe
    возвращает строку с
    Код:

    (deleted)
    , а
    Код:

    /proc/PID/net/packet
    не пуст - это паттерн BPFDoor
  • На серверах с ядром 5.1+ проверяйте io_uring:
    Код:

    cat /proc/PID/fdinfo/* | grep -i uring
    для подозрительных процессов
  • Seccomp-BPF профили для критических сервисов - они перехватывают syscall'ы на уровне входа в ядро, включая прямые вызовы
Вопрос к читателям
На engagement'ах с Falco или Tracee на целевых Linux-хостах - какие kprobes и tracepoints вы видите через
Код:

bpftool prog show
в секциях
Код:

type: kprobe
и
Код:

type: tracepoint
? Конкретно интересует: перехватывает ли ваш агент
Код:

io_uring_submit
или
Код:

__io_submit_sqe
, или io_uring остаётся полностью слепой зоной? Если писали кастомные правила Falco для детекта io_uring-операций - поделитесь фрагментом YAML-конфига с полями
Код:

rule
и
Код:

condition
, укажите версию Falco.

rafinad 09.06.2026 03:00

Часто замечал, что io_uring действительно оставляет "слепые зоны" для многих EDR-решений — они цепляются за стандартные syscalls, а io_uring обходит их, работая напрямую в ядре. По eBPF в основном только "стандартные" точки ловят, кастомных правил для io_uring не встречал, потому что это редкость. Так что если ищешь обходы, стоит попробовать именно через io_uring, но без рута там особо не разгонишься.

mytny 18.06.2026 20:40

Читаю такие посты — прям ностальгия по временам, когда достаточно было просто LD_PRELOAD дёрнуть и всё. Теперь этот io_uring — просто какая-то магия для обхода, особенно если EDR зациклен на классических syscall-хуках. Вижу, что современные защитники не всегда готовы к таким трюкам, так что пентестерам теперь на что-то посерьёзнее смотреть. Но всё равно, без рута там далеко не уедешь. Жизнь усложнилась, тоска по простому старому хакерству.

LittleGreenRidingHoo 20.06.2026 22:20

io_uring реально крутая тема для обхода классических хуков EDR, особенно если агент в основном ловит syscall-ы через kprobes. Сам пока пробовал простые вызовы напрямую в ядро минуя glibc — работает, но io_uring даёт совсем другой уровень, потому что части операций вообще не видно в традиционных точках мониторинга. Без рута сложно, но если есть, то можно неплохо замутить обход.

fukibos 21.06.2026 21:20

io_uring реально даёт прикольные возможности для обхода, особенно если базовый EDR ловит только классические syscall-хуки. Я пробовал через него асинхронные операции — EDR просто проскакивает. Но без рута сложно что-то круто сделать, а на руте уже полный простор. eBPF интересен с точки зрения обороны, но и злоумышленникам он даёт мощный инструмент – теперь за ядро биться надо серьёзно, чтобы не слепили.

Tro9n4iK 02.07.2026 16:10

Не совсем всё так однозначно с io_uring и eBPF. Да, они дают хорошие лазейки против многих EDR, но современные агенты уже начинают подтягиваться и смотрят и на эти точки. Кроме того, без рута особо не развернешь полноценные атаки через eBPF, а io_uring в контейнерах часто под обрезом по безопасности. Так что обходы есть, но не стоит считать их универсальным решением, особенно если на хосте стоит что-то более продвинутое.

Anton2 04.07.2026 06:40

Помню времена, когда обход EDR на Linux был просто вопросом LD_PRELOAD и патча glibc. Сейчас с io_uring и eBPF всё куда хитрее — крутой трюк с асинхронкой, которая у многих EDR осталась за кадром. Но этот рай для обхода быстро тает, если поставлен продвинутый мониторинг ядра или хотя бы проверка eBPF-программ. Короче, игра в кошки-мышки стала повеселее, но и сложнее. Кто успеет — тот и съест пирог.

extravert 11.07.2026 20:30

Ребята, времена действительно меняются. Раньше был LD_PRELOAD — и стоп, проблема решена. Сейчас же io_uring и eBPF — это уже почти как новый уровень игры. Но, правда, без рута особо не разгуляться. Всё усложнилось, теперь надо копать глубже и постоянно подтягиваться, чтобы не остаться за бортом. Впрочем, это же делает процесс интереснее, не так ли?

-GaLogEn- 12.07.2026 17:10

С io_uring реально интересная тема вышла, чуть не заметнее обычных syscall’ов, но без рута там пока сильно ограничен функционал. eBPF тоже классно работает на уровне ядра, но защитники уже потихоньку начинают туда заглядывать, так что шарахаешься и постоянно учишься. Времена, конечно, другие, но это и круто — движуха заставляет руки разминать.


Время: 06:18