
SunnyDayBPF: eBPF-basierte Post-Syscall-Benutzerpuffer-Telemetrie-Täuschungsforschung von Azizcan Daştan
SunnyDayBPF ist eine eBPF-basierte Post-Syscall-Benutzerpuffer-Telemetrie-Täuschungs-Forschungstechnik, die ursprünglich von Azizcan Dastan vorgeschlagen und erforscht wurde.
Die Technik untersucht, ob Daten, die von Benutzerraum-Sicherheits-, Protokollierungs- oder Telemetrie-Agenten beobachtet werden, nachdem ein leseartiger Systemaufruf abgeschlossen wurde, aber bevor der Agent diese Daten parst, analysiert oder an eine nachgelagerte Sicherheits-Pipeline weiterleitet, geändert werden können.
Die Kernidee ist:
Das Ereignis findet immer noch statt.
Der Überwachungsagent liest immer noch Daten.
Aber die vom Agenten beobachteten Daten können das ursprüngliche Ereignis nicht mehr vollständig repräsentieren.
SunnyDayBPF konzentriert sich auf die Lücke zwischen Grundwahrheit und beobachteter Telemetrie.
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
### Syscall-Abdeckung
| Syscall | Kernel-Hook | Argument-Extraktion | Abdeckung |
|---------|------------|----------------|----------|
| `read()` | `ksys_read` | `PT_REGS_PARM2` (direkt) | Dateilesen, Pipes, `/proc`, Logdateien |
| `pread64()` | `__x64_sys_pread64` | Verschachteltes `pt_regs` via `bpf_probe_read_kernel` (Offset 104/RSI) | Direktzugriff-Dateilesen, journald |
| `recvfrom()` | `__sys_recvfrom` | `PT_REGS_PARM2` (direkt) | Netzwerk-Sockets, syslog-Weiterleitung |
### BPF-Verifier-Einschränkungen
Der BPF-Verifier erzwingt eine Sprungsequenz-Grenze von 8.192 bedingten Verzweigungen pro Programm. SunnyDayBPF umgeht dies durch die Verwendung von:
- **BPF-Tail-Calls** (`BPF_PROG_ARRAY`): 31 Regeln verteilt auf 10 unabhängige Programme, jedes mit eigenem Verifier-Budget
- **Groß-/Kleinschreibungsoptimierung**: `(d[i]|32)==lower` reduziert Sprünge pro Byte von 2 auf 1 für alphabetische Zeichen
- **Dynamische Scan-Grenzen**: Das Scan-Fenster jeder Gruppe wird als `min(BUF_SIZE - max_pat, 7800 / jumps_per_iter)` berechnet, um innerhalb der Verifier-Grenzen zu bleiben
- **Per-CPU-Arrays**: `BPF_PERCPU_ARRAY` für Puffer und Scan-Status, gemeinsam genutzt über Tail-Call-Programme hinweg
---
## Übersicht
Moderne Linux-Sicherheitssysteme verlassen sich oft auf User-Space-Agenten, die Telemetriedaten von Dateien, Sockets, Pipes, APIs, Kernel-Schnittstellen oder Ereignisströmen sammeln.
Diese Agenten leiten Telemetriedaten möglicherweise weiter an:
- SIEM-Plattformen
- EDR/XDR-Backends
- Audit-Pipelines
- Log-Sammler
- Laufzeit-Sicherheits-Engines
- Detection-Engineering-Systeme
- Observability-Plattformen
Eine häufige Annahme ist:```text
actual system behavior == collected telemetry == observed security data
SunnyDayBPF stellt diese Annahme in Frage. Die Forschung untersucht ein Post-Syscall-Täuschungsmodell, bei dem ein Überwachungsprozess Daten normal empfängt, der Puffer mit diesen Daten jedoch modifiziert wird, bevor der Prozess sie konsumiert.```text actual system behavior != observed telemetry
## Technische Definition
SunnyDayBPF ist eine Post-Syscall-Telemetrie-Täuschungstechnik, die die Manipulation von Userspace-Puffern untersucht, die zu ausgewählten telemetriekonsumierenden Prozessen gehören.
Auf hoher Ebene folgt die Technik diesem Modell:```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
Dies erzeugt eine Diskrepanz zwischen:```text what happened on the system
und:```text
what the monitoring agent later observes, parses, and forwards
SunnyDayBPF identifiziert Zielprozesse durch Präfixvergleich des 5-stelligen Befehlsnamens.
| Agent | Präfix | Lesemethode | Wirksam? |
|---|---|---|---|
| Wazuh | wazuh | read() auf Logdateien, syslog, Audit-Logs | Ja |
| OSSEC | ossec | read() auf Logdateien | Ja |
| Splunk UF | splun | read() auf überwachten Dateien | Ja |
| Elastic Agent | elast | read() auf Logquellen | Ja |
| Datadog Agent | datad | read() auf Logs und Metriken | Ja |
| Cribl | cribl | read() für Log-Routing | Ja |
| Agent | Präfix | Lesemethode | Wirksam? |
|---|---|---|---|
| rsyslog | rsysl | read() / recvfrom() auf syslog | Ja |
| syslog-ng | syslo | read() / recvfrom() auf syslog | Ja |
| Filebeat | fileb | read() auf Logdateien | Ja |
| Fluent-bit | fluen | read() / recvfrom() auf Eingängen | Ja |
| Fluentd | fluen | read() / recvfrom() auf Eingängen | Ja |
| Logstash | logst | read() / recvfrom() auf Pipeline | Ja |
| Promtail | promt | read() auf Logdateien (Loki) | Ja |
| Vector | vecto | read() auf Logquellen | Ja |
| Agent | Präfix | Lesemethode | Wirksam? |
|---|---|---|---|
| Falco | falco | eBPF-Ereignisse gesammelt via read() auf Perf-Puffer | Ja |
| osquery | osque | read() auf /proc, Logdateien, Systemtabellen | Ja |
| Agent | Präfix | Lesemethode | Wirksam? |
|---|---|---|---|
| Snort | snort | recvfrom() auf Paketerfassung | Ja |
| Suricata | suric | recvfrom() auf Paketerfassung | Ja |
| Zeek | zeek_ | recvfrom() auf Paketerfassung | Ja |