
SunnyDayBPF: исследование обмана телеметрии пользовательского буфера после системного вызова на основе eBPF от Азизджана Даштана
SunnyDayBPF — это исследовательская техника обмана телеметрии пользовательского буфера после системного вызова на основе eBPF, первоначально предложенная и исследованная Азизджаном Дастаном.
Методика исследует, могут ли данные, наблюдаемые агентами безопасности, журналирования или телеметрии в пользовательском пространстве, быть изменены после завершения системного вызова типа read, но до того, как агент разберет, проанализирует или перешлет эти данные в нижестоящий конвейер безопасности.
Основная идея:
Событие по-прежнему происходит.
Агент мониторинга по-прежнему считывает данные.
Но данные, наблюдаемые агентом, могут больше не полностью отражать исходное событие.
SunnyDayBPF фокусируется на разрыве между истинной картиной и наблюдаемой телеметрией.
SunnyDayBPF Hook Points
========================
Telemetry Agent Process +---------------------------------------------------------+ | | | read() pread64() recvfrom() | | | | | | +-----|----------------|------------------|---------------+ | | | ======|================|==================|======= KERNEL BOUNDARY | | | kprobe:ksys_read kprobe:_x64_sys kprobe:_sys (save buf ptr) pread64 recvfrom | (nested pt_regs) (save buf ptr) | (save buf ptr) | v v v [syscall executes — data enters user buffer] | | | kretprobe kretprobe kretprobe | | | +--------+-------+---------+--------+ | | read buffer into initialize BPF scratch space scan_state | v +------------------+ | TAIL CALL CHAIN | | | | scan_g0: SECURITY (4 rules, scan=177 bytes) | scan_g1: SECURITY (4 rules, scan=173 bytes) | scan_g2: SEVERITY (4 rules, scan=177 bytes) | scan_g3: SEVERITY (1 rule, scan=251 bytes) | scan_g4: PATH (4 rules, scan=132 bytes) | scan_g5: AUTH (4 rules, scan=190 bytes) | scan_g6: AUTH (1 rule, scan=249 bytes) | scan_g7: NETWORK (3 rules, scan=249 bytes) | scan_g8: PROCESS (4 rules, scan=173 bytes) | scan_g9: CUSTOM (2 rules, scan=243 bytes) | | | emit_event: | | perf event | | + stats | +------------------+ | v bpf_probe_write_user() (modify agent's buffer) | v read-back verification (confirm write succeeded) | v Agent continues with modified data
### Охват системных вызовов
| Системный вызов | Хук ядра | Извлечение аргументов | Охват |
|---------|------------|----------------|----------|
| `read()` | `ksys_read` | `PT_REGS_PARM2` (прямое) | Чтение файлов, каналы, `/proc`, файлы журналов |
| `pread64()` | `__x64_sys_pread64` | Вложенные `pt_regs` через `bpf_probe_read_kernel` (смещение 104/RSI) | Произвольное чтение файлов, journald |
| `recvfrom()` | `__sys_recvfrom` | `PT_REGS_PARM2` (прямое) | Сетевые сокеты, перенаправление syslog |
### Ограничения верификатора BPF
Верификатор BPF накладывает ограничение на последовательность переходов: не более 8 192 условных веток на программу. SunnyDayBPF обходит это с помощью:
- **Хвостовые вызовы BPF** (`BPF_PROG_ARRAY`): 31 правило, распределённые по 10 независимым программам, каждая со своим бюджетом верификатора
- **Оптимизация без учёта регистра**: `(d[i]|32)==lower` уменьшает количество переходов на байт с 2 до 1 для буквенных символов
- **Динамические пределы сканирования**: окно сканирования каждой группы вычисляется как `min(BUF_SIZE - max_pat, 7800 / jumps_per_iter)` для соблюдения ограничений верификатора
- **Массивы на ядро ЦП**: `BPF_PERCPU_ARRAY` для промежуточного буфера и состояния сканирования, разделяемые между программами, вызываемыми хвостовым способом
---
## Обзор
Современные системы безопасности Linux часто полагаются на агенты пользовательского пространства, которые собирают телеметрию из файлов, сокетов, каналов, API, интерфейсов ядра или потоков событий.
Эти агенты могут пересылать телеметрию в:
- платформы SIEM
- бэкенды EDR/XDR
- конвейеры аудита
- сборщики журналов
- движки безопасности времени выполнения
- системы разработки обнаружений
- платформы наблюдаемости
Распространённое предположение:```text
actual system behavior == collected telemetry == observed security data
SunnyDayBPF бросает вызов этому предположению.
В исследовании рассматривается модель обмана после системного вызова, при которой мониторинговый процесс получает данные в обычном режиме, но буфер, содержащий эти данные, изменяется до того, как процесс их потребляет.```text actual system behavior != observed telemetry
## Technical Definition
SunnyDayBPF - это техника обмана телеметрии после системного вызова, изучающая манипуляцию буферами пространства пользователя, принадлежащими выбранным процессам, потребляющим телеметрию.
На высоком уровне техника следует этой модели:```text
sys_enter_*:
identify a target telemetry-consuming process
record the user-space buffer pointer involved in the read-like operation
sys_exit_*:
verify that the read-like operation completed successfully
inspect the returned user-space buffer
selectively alter telemetry-relevant content
verify write success via read-back
allow the target process to continue execution normally
Это создает несоответствие между:```text what happened on the system
и:```text
what the monitoring agent later observes, parses, and forwards
SunnyDayBPF идентифицирует целевые процессы по совпадению первых 5 символов имени команды.
| Агент | Префикс | Метод чтения | Эффективен? |
|---|---|---|---|
| Wazuh | wazuh | read() для файлов логов, syslog, audit logs | Да |
| OSSEC | ossec | read() для файлов логов | Да |
| Splunk UF | splun | read() для отслеживаемых файлов | Да |
| Elastic Agent | elast | read() для источников логов | Да |
| Datadog Agent | datad | read() для логов и метрик | Да |
| Cribl | cribl | read() для маршрутизации логов | Да |
| Агент | Префикс | Метод чтения | Эффективен? |
|---|---|---|---|
| rsyslog | rsysl | read() / recvfrom() на syslog | Да |
| syslog-ng | syslo | read() / recvfrom() на syslog | Да |
| Filebeat | fileb | read() для файлов логов | Да |
| Fluent-bit | fluen | read() / recvfrom() на входы | Да |
| Fluentd | fluen | read() / recvfrom() на входы | Да |
| Logstash | logst | read() / recvfrom() на конвейер | Да |
| Promtail | promt | read() для файлов логов (Loki) | Да |
| Vector | vecto | read() для источников логов | Да |
| Агент | Префикс | Метод чтения | Эффективен? |
|---|---|---|---|
| Falco | falco | События eBPF собираются через read() на буфере perf | Да |
| osquery | osque | read() на /proc, файлы логов, системные таблицы | Да |