
SunnyDayBPF: investigación de engaño en telemetría de búfer de usuario post-syscall basada en eBPF por Azizcan Daştan
SunnyDayBPF es una técnica de investigación basada en eBPF denominada post-syscall user-buffer telemetry deception, propuesta y estudiada originalmente por Azizcan Dastan.
La técnica investiga si los datos observados por agentes de seguridad, registro o telemetría en espacio de usuario pueden alterarse después de que se haya completado una syscall tipo lectura, pero antes de que el agente analice, procese o reenvíe esos datos a un pipeline de seguridad posterior.
La idea central es:
El evento sigue ocurriendo.
El agente de monitoreo sigue leyendo los datos.
Pero los datos observados por el agente pueden dejar de representar plenamente el evento original.
SunnyDayBPF se centra en la brecha entre ground truth y telemetría observada.
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
### Cobertura de Syscalls
| Syscall | Kernel Hook | Arg Extraction | Coverage |
|---------|------------|----------------|----------|
| `read()` | `ksys_read` | `PT_REGS_PARM2` (direct) | Lecturas de archivos, pipes, `/proc`, archivos de registro |
| `pread64()` | `__x64_sys_pread64` | Nested `pt_regs` via `bpf_probe_read_kernel` (offset 104/RSI) | Lecturas de archivos de acceso aleatorio, journald |
| `recvfrom()` | `__sys_recvfrom` | `PT_REGS_PARM2` (direct) | Sockets de red, reenvío de syslog |
### Restricciones del Verificador BPF
El verificador de BPF impone un límite de secuencia de saltos de 8,192 ramas condicionales por programa. SunnyDayBPF lo soluciona mediante:
- **Colas de llamadas BPF** (`BPF_PROG_ARRAY`): 31 reglas distribuidas en 10 programas independientes, cada uno con su propio presupuesto del verificador
- **Optimización insensible a mayúsculas/minúsculas**: `(d[i]|32)==lower` reduce los saltos por byte de 2 a 1 para caracteres alfabéticos
- **Límites de escaneo dinámicos**: La ventana de escaneo de cada grupo se calcula como `min(BUF_SIZE - max_pat, 7800 / jumps_per_iter)` para mantenerse dentro de los límites del verificador
- **Matrices por CPU**: `BPF_PERCPU_ARRAY` para el búfer temporal y el estado de escaneo, compartida entre los programas llamados por cola
---
## Visión general
Los sistemas de seguridad Linux modernos suelen depender de agentes de espacio de usuario que recopilan telemetría de archivos, sockets, pipes, APIs, interfaces del kernel o flujos de eventos.
Estos agentes pueden reenviar la telemetría a:
- plataformas SIEM
- backends EDR/XDR
- pipelines de auditoría
- recopiladores de registros
- motores de seguridad en tiempo de ejecución
- sistemas de ingeniería de detección
- plataformas de observabilidad
Una suposición común es:```text
actual system behavior == collected telemetry == observed security data
SunnyDayBPF cuestiona esa suposición.
La investigación explora un modelo de engaño posterior a la syscall en el que un proceso de monitorización recibe datos con normalidad, pero el búfer que contiene esos datos se modifica antes de que el proceso los consuma.```text actual system behavior != observed telemetry
---
## Definición Técnica
SunnyDayBPF es una técnica de decepción de telemetría post-syscall que estudia la manipulación de los buffers de espacio de usuario pertenecientes a procesos seleccionados que consumen telemetría.
A alto nivel, la técnica sigue este modelo:```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
Esto crea un desajuste entre:```text what happened on the system
y:```text
what the monitoring agent later observes, parses, and forwards
SunnyDayBPF identifica los procesos objetivo mediante la coincidencia de prefijos de 5 caracteres en el nombre del comando.
| Agente | Prefijo | Método de lectura | ¿Efectivo? |
|---|---|---|---|
| Wazuh | wazuh | read() en archivos de registro, syslog, registros de auditoría | Sí |
| OSSEC | ossec | read() en archivos de registro | Sí |
| Splunk UF | splun | read() en archivos monitoreados | Sí |
| Elastic Agent | elast | read() en fuentes de registro | Sí |
| Datadog Agent | datad | read() en registros y métricas | Sí |
| Cribl | cribl | read() para enrutamiento de registros | Sí |
| Agente | Prefijo | Método de lectura | ¿Efectivo? |
|---|---|---|---|
| rsyslog | rsysl | read() / recvfrom() en syslog | Sí |
| syslog-ng | syslo | read() / recvfrom() en syslog | Sí |
| Filebeat | fileb | read() en archivos de registro | Sí |
| Fluent-bit | fluen | read() / recvfrom() en entradas | Sí |
| Fluentd | fluen | read() / recvfrom() en entradas | Sí |
| Logstash | logst | read() / recvfrom() en el pipeline | Sí |
| Promtail | promt | read() en archivos de registro (Loki) | Sí |
| Vector | vecto | read() en fuentes de registro | Sí |
| Agente | Prefijo | Método de lectura | ¿Efectivo? |
|---|---|---|---|
| Falco | falco | eventos eBPF recopilados mediante read() en el buffer perf | Sí |
| osquery | osque | read() en /proc, archivos de registro, tablas del sistema | Sí |