
SunnyDayBPF: eBPF-based post-syscall user-buffer telemetry deception research by Azizcan Daştan
SunnyDayBPF is an eBPF-based post-syscall user-buffer telemetry deception research technique originally proposed and researched by Azizcan Dastan.
The technique investigates whether data observed by user-space security, logging, or telemetry agents can be altered after a read-like syscall has completed, but before the agent parses, analyzes, or forwards that data to a downstream security pipeline.
The core idea is:
The event still happens.
The monitoring agent still reads data.
But the data observed by the agent may no longer fully represent the original event.
SunnyDayBPF focuses on the gap between ground truth and observed telemetry.
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
The BPF verifier enforces a jump sequence limit of 8,192 conditional branches per program. SunnyDayBPF works around this using:
BPF_PROG_ARRAY): 31 rules split across 10 independent programs, each with its own verifier budget(d[i]|32)==lower reduces jumps per byte from 2 to 1 for alphabetic charactersmin(BUF_SIZE - max_pat, 7800 / jumps_per_iter) to stay within verifier limitsBPF_PERCPU_ARRAY for scratch buffer and scan state, shared across tail-called programsModern Linux security systems often rely on user-space agents that collect telemetry from files, sockets, pipes, APIs, kernel interfaces, or event streams.
These agents may forward telemetry to:
A common assumption is:
actual system behavior == collected telemetry == observed security data
SunnyDayBPF challenges that assumption.
The research explores a post-syscall deception model where a monitoring process receives data normally, but the buffer containing that data is modified before the process consumes it.
actual system behavior != observed telemetry
SunnyDayBPF is a post-syscall telemetry deception technique that studies the manipulation of user-space buffers belonging to selected telemetry-consuming processes.
At a high level, the technique follows this model:
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
This creates a mismatch between:
what happened on the system
and:
what the monitoring agent later observes, parses, and forwards
SunnyDayBPF identifies target processes by 5-character command name prefix matching.
Falco uses eBPF probes to capture kernel events, but the decision-making (rule matching, alerting) happens in user-space. The Falco process reads events from a perf/ring buffer via read(). SunnyDayBPF modifies the data in that buffer after the read completes but before Falco parses it.
Kernel: Falco eBPF probe captures syscall event
|
v
perf buffer (kernel memory)
|
v
User: falco process calls read() on perf fd
|
v <-- SunnyDayBPF modifies buffer here
|
falco parses modified event
|
rule matching on altered data
|
no alert (or wrong alert)
| Pattern | Replacement | Effect |
|---|---|---|
config_change | sunny_day | Masks configuration changes |
milenium | SUNNYDAY | Research marker |
Tested on Linux 6.8.0-111-generic with BCC 0.29.1.
Test: All 31 rules at offset 0
Result: 31/31 PASS (100%)
Verification: 127 writes, 127 verified, 0 failures (100%)
Each rule group scans a portion of the 256-byte buffer. Patterns within the scan window are redacted; patterns beyond it are not.
Input: "exploit detected: critical error from /etc/shadow password=leaked"
Output: "nominal detected: debug debug from /etc/sunshn SUNNYDAY=leaked"
5 patterns redacted simultaneously in a single buffer: PASS
Payload: "rootkit found at /bin/bash with password leak"
read(): toolkit found at /bin/dash with SUNNYDAY leak PASS
pread64(): toolkit found at /bin/dash with SUNNYDAY leak PASS
recvfrom(): toolkit found at /bin/dash with SUNNYDAY leak PASS
Normal telemetry flow:
System activity
|
Telemetry source
|
Monitoring agent reads data
|
Agent parses original data
|
Detection logic receives original telemetry
|
SIEM / EDR / audit backend
SunnyDayBPF research flow:
System activity
|
Telemetry source
|
Monitoring agent reads data
|
Post-syscall user-buffer manipulation
|
Agent parses altered data
|
Detection logic receives modified telemetry
|
SIEM / EDR / audit backend observes misleading data
The key point is that the original event is not blocked, prevented, or hidden at the source. Instead, SunnyDayBPF studies how the observation path can be influenced after data has entered the monitoring process.
SunnyDayBPF investigates the following question:
Can an eBPF-based post-syscall manipulation layer alter the data observed
by security agents without preventing the original event from occurring?
A secondary question:
How much do modern telemetry pipelines trust data after it has entered
user-space collectors?
SunnyDayBPF is a research technique focused on:
SunnyDayBPF is not presented as a generic malware framework, persistence mechanism, rootkit project, or unauthorized bypass tool.
Its purpose is to examine a specific telemetry integrity problem:
What happens when the event is real, but the observer sees altered data?
SunnyDayBPF is not intended to be:
This repository is intended for authorized research, controlled lab experimentation, defensive security analysis, and detection engineering.
Many security systems make decisions based on telemetry produced or forwarded by user-space agents.
If that telemetry can be changed after collection but before processing, then downstream systems may receive a misleading view of the system.
This can impact assumptions used by:
SunnyDayBPF highlights that defenders should not only ask:
Did the event happen?
They should also ask:
Can I trust the path through which I observed the event?
SunnyDayBPF is best understood as an observation-layer deception technique.
Traditional evasion often focuses on preventing visibility:
prevent the event from being seen
hide the event
disable the sensor
avoid triggering detection
SunnyDayBPF explores a different model:
allow the event to occur
allow the monitoring process to read data
alter the observation before processing
cause downstream systems to trust modified telemetry
The distinction:
Traditional evasion:
hide or prevent the event
SunnyDayBPF-style deception:
allow the event, but alter what the observer receives
SunnyDayBPF assumes a controlled and authorized research environment.
The technique is relevant to environments where:
Out of scope:
SunnyDayBPF focuses on the trust boundary between:
kernel-provided or source-provided data
and:
user-space security agent interpretation
The research scope includes:
# Run the redactor
sudo python3 SunnyDayBPF.py
# Dump generated BPF C source
sudo python3 SunnyDayBPF.py --dump-bpf
# List all redaction rules
python3 SunnyDayBPF.py --list-rules
# List all target agents
python3 SunnyDayBPF.py --list-agents
+=====================================================================+
| SunnyDayBPF v2.1 -- Universal Post-Syscall Telemetry Redactor |
| Milenium Security Research | Azizcan Dastan |
+=====================================================================+
Hedef Agentlar: 28 telemetry agent
Redaction Kurallari: 31 aktif kural
Scan Gruplari: 10 tail-call group
Buffer: 256 byte
[+] read -> ksys_read
[+] pread64 -> __x64_sys_pread64
[+] recvfrom -> __sys_recvfrom
[+] VERIFIER PASSED -- 31 kural, 3 syscall hook, 10 chain group
ZAMAN PID AGENT SYSCALL KATEGORI VER
===========================================================================
15:23:28.222 PID:1234 audit_test READ SECURITY V "exploit" -> "nominal"
15:23:28.298 PID:1235 wazuh-agentd READ SEVERITY V "critical" -> "debug "
15:23:28.322 PID:1236 filebeat PREAD PATH V "/etc/shadow" -> "/etc/sunshn"
15:23:28.357 PID:1237 rsyslogd RECV AUTH V "password" -> "SUNNYDAY"
SunnyDayBPF is a research technique and has practical limitations:
readv(), recvmsg(), mmap()-based readsThis research should not be interpreted as a universal bypass of all Linux security monitoring.
Potential defensive approaches include:
bpf() syscall auditingCAP_BPF, CAP_SYS_ADMIN)bpf_probe_write_user helper (the key helper enabling this technique)The goals of SunnyDayBPF are:
SunnyDayBPF highlights several defensive concerns:
bpf_probe_write_user usage should be audited and restrictedSunnyDayBPF is published for authorized security research, defensive analysis, telemetry integrity research, and detection engineering.
This repository does not encourage unauthorized deployment, stealth persistence, production abuse, or malicious use of eBPF.
All experiments should be performed only in systems you own or are explicitly authorized to test.
SunnyDayBPF was originally proposed and researched by:
Azizcan Dastan
Research metadata:
Technique Name: SunnyDayBPF
Researcher: Azizcan Dastan
LinkedIn: https://www.linkedin.com/in/azqzazq
GitHub: https://github.com/azqzazq1
Category: eBPF Security Research
Focus Area: Post-Syscall User-Buffer Telemetry Deception
Initial Public Release: 2026
Suggested citation:
Dastan, Azizcan. "SunnyDayBPF: Post-Syscall User-Buffer Telemetry Deception with eBPF." 2026.
SunnyDayBPF was discovered and proposed by Azizcan Dastan as part of research into eBPF-based telemetry manipulation and observation-layer deception.
SunnyDayBPF is an eBPF-based post-syscall user-buffer telemetry deception technique. It investigates whether data observed by user-space security or logging agents can be altered after read-like syscall completion.
No. SunnyDayBPF is framed as a telemetry integrity research technique. It is not presented as a persistence mechanism, malware framework, or unauthorized system compromise method.
No. The original event still occurs. The research focuses on whether the observation of that event can be changed before the telemetry is processed by the monitoring agent.
SunnyDayBPF targets the observation path between syscall completion and user-space telemetry processing.
Because many detection systems trust data after it is collected by user-space agents. SunnyDayBPF shows that defenders should validate not only event sources, but also the integrity of the collection and forwarding path.
This repository is positioned as defensive research and telemetry integrity analysis. It documents a security-relevant technique so that defenders can understand, detect, and mitigate this class of risk.
Wazuh is a fully user-space SIEM agent that reads telemetry via read() syscalls. SunnyDayBPF can modify the data Wazuh reads before Wazuh processes it. Default Wazuh installations have no mechanism to detect this type of buffer manipulation.
Falco captures events via kernel eBPF probes, but processes them in user-space via read() on a perf buffer. SunnyDayBPF can modify the buffer contents after the read completes. Falco's user-space rule engine then processes altered data.
Tools that make enforcement decisions inside the kernel, such as Cilium Tetragon and Aqua Tracee. These tools evaluate policies in kernel eBPF programs before data reaches user-space.
Research status: Active public research
Technique status: v2.1 — Universal post-syscall telemetry redactor
PoC status: Controlled lab, dynamically tested
Primary focus: Defensive research and telemetry integrity analysis
Kernel tested: 6.8.0-111-generic
BCC version: 0.29.1
Azizcan Dastan
Security researcher focused on offensive security, vulnerability research, Linux security, telemetry manipulation, eBPF research, and detection engineering.
If you reference this research, please cite it as:
Dastan, Azizcan. "SunnyDayBPF: Post-Syscall User-Buffer Telemetry Deception with eBPF." 2026.
BibTeX-style citation:
@misc{dastan2026sunnydaybpf,
author = {Azizcan Dastan},
title = {SunnyDayBPF: Post-Syscall User-Buffer Telemetry Deception with eBPF},
year = {2026},
note = {eBPF-based post-syscall telemetry deception research technique},
howpublished = {\url{https://github.com/azqzazq1/SunnyDayBPF}}
}
This research repository is released for educational and defensive security research purposes.
See LICENSE for details.
| Syscall | Kernel Hook | Arg Extraction | Coverage |
|---|
read() | ksys_read | PT_REGS_PARM2 (direct) | File reads, pipes, /proc, log files |
pread64() | __x64_sys_pread64 | Nested pt_regs via bpf_probe_read_kernel (offset 104/RSI) | Random-access file reads, journald |
recvfrom() | __sys_recvfrom | PT_REGS_PARM2 (direct) | Network sockets, syslog forwarding |
| Agent | Prefix | Read Method | Effective? |
|---|
| Wazuh | wazuh | read() on log files, syslog, audit logs | Yes |
| OSSEC | ossec | read() on log files | Yes |
| Splunk UF | splun | read() on monitored files | Yes |
| Elastic Agent | elast | read() on log sources | Yes |
| Datadog Agent | datad | read() on logs and metrics | Yes |
| Cribl | cribl | read() for log routing | Yes |
| Agent | Prefix | Read Method | Effective? |
|---|
| rsyslog | rsysl | read() / recvfrom() on syslog | Yes |
| syslog-ng | syslo | read() / recvfrom() on syslog | Yes |
| Filebeat | fileb | read() on log files | Yes |
| Fluent-bit | fluen | read() / recvfrom() on inputs | Yes |
| Fluentd | fluen | read() / recvfrom() on inputs | Yes |
| Logstash | logst | read() / recvfrom() on pipeline | Yes |
| Promtail | promt | read() on log files (Loki) | Yes |
| Vector | vecto | read() on log sources | Yes |
| Agent | Prefix | Read Method | Effective? |
|---|
| Falco | falco | eBPF events collected via read() on perf buffer | Yes |
| osquery | osque | read() on /proc, log files, system tables | Yes |
| Agent | Prefix | Read Method | Effective? |
|---|
| Snort | snort | recvfrom() on packet capture | Yes |
| Suricata | suric | recvfrom() on packet capture | Yes |
| Zeek | zeek_ | recvfrom() on packet capture | Yes |
| Agent | Prefix | Read Method | Effective? |
|---|
| auditd | audit | read() on audit netlink socket | Yes |
| audisp | audisp | read() on audit dispatch | Yes |
| journalctl | journ | read() / pread() on journal files | Yes |
| Telegraf | teleg | read() on metric sources | Yes |
| collectd | colle | read() on system metrics | Yes |
| Metricbeat | metrc | read() on system metrics | Yes |
| Packetbeat | packe | recvfrom() on network | Yes |
| Winlogbeat | winlo | read() on event logs | Yes |
| Heartbeat | hbeat | read() / recvfrom() on uptime checks | Yes |
| Tool | Why | Explanation |
|---|
| Cilium Tetragon | Kernel-space enforcement | Policy decisions and kill/deny actions happen inside the eBPF program, before data reaches user-space |
| Tracee (Aqua) | Kernel-space detection | Event filtering and some detection logic runs in kernel eBPF programs |
| Kernel audit module | Kernel-space logging | Audit records are generated in kernel; though auditd daemon reads them via read() (vulnerable at that stage) |
| Pattern | Replacement | Case-Insensitive | Effect |
|---|
exploit | nominal | Yes | Masks exploitation alerts |
malware | cleaner | Yes | Masks malware detections |
backdoor | maindoor | Yes | Masks backdoor references |
rootkit | toolkit | Yes | Masks rootkit detections |
trojan | module | Yes | Masks trojan alerts |
overflow | dataflow | Yes | Masks buffer overflow events |
payload | dataset | Yes | Masks payload delivery |
shellcode | usercode | Yes | Masks shellcode execution |
| Pattern | Replacement | Effect |
|---|
critical | debug | SIEM sees debug instead of critical |
emergency | debug | Emergency events become debug |
alert | info | Alert level becomes informational |
warning | notice | Warning downgraded to notice |
error | debug | Error events become debug |
| Pattern | Replacement | Effect |
|---|
/etc/shadow | /etc/sunshn | Hides shadow file access |
/etc/passwd | /etc/sunshn | Hides passwd file access |
/etc/sudoers | /etc/sudhelp | Hides sudoers access |
/proc/self | /proc/init | Hides process self-inspection |
| Pattern | Replacement | Effect |
|---|
password | SUNNYDAY | Masks password references |
passwd | sunshn | Masks passwd references |
secret | public | Masks secret/token data |
token= | clean= | Masks token parameters |
api_key | app_cfg | Masks API key references |
| Pattern | Replacement | Effect |
|---|
0.0.0.0 | 1.2.3.4 | Masks bind-all addresses |
reverse | forward | Masks reverse shell/connection references |
C2 | UP | Masks C2 communication indicators |
| Pattern | Replacement | Effect |
|---|
/bin/sh | /bin/ls | Masks shell execution |
/bin/bash | /bin/dash | Masks bash execution |
chmod 777 | chmod 644 | Masks permission changes |
wget | curl | Masks download tool usage |
| Syscall | Hook | Status | Tested |
|---|
read() | ksys_read | Working | 31/31 rules pass |
pread64() | __x64_sys_pread64 | Working | 5/5 rules pass |
recvfrom() | __sys_recvfrom | Working | 5/5 rules pass |
| Group | Category | Rules | Scan Window | Coverage |
|---|
| g0 | SECURITY | exploit, malware, backdoor, rootkit | 177 / 256 bytes | 69% |
| g1 | SECURITY | trojan, overflow, payload, shellcode | 173 / 256 bytes | 67% |
| g2 | SEVERITY | critical, emergency, alert, warning | 177 / 256 bytes | 69% |
| g3 | SEVERITY | error | 251 / 256 bytes | 98% |
| g4 | PATH | /etc/shadow, /etc/passwd, /etc/sudoers, /proc/self | 132 / 256 bytes | 51% |
| g5 | AUTH | password, passwd, secret, token= | 190 / 256 bytes | 74% |
| g6 | AUTH | api_key | 249 / 256 bytes | 97% |
| g7 | NETWORK | 0.0.0.0, reverse, C2 | 249 / 256 bytes | 97% |
| g8 | PROCESS | /bin/sh, /bin/bash, chmod 777, wget | 173 / 256 bytes | 67% |
| g9 | CUSTOM | config_change, milenium | 243 / 256 bytes | 94% |
| Metric | v2.0 | v2.1 | Improvement |
|---|
| Syscall hooks | 1 (read only) | 3 (read + pread + recv) | 3x |
| pread64 | Broken | Working | Fixed |
| recvfrom | Missing | Working | New |
| Buffer size | 192 bytes | 256 bytes | +33% |
| SECURITY scan | 53 bytes | 177 bytes | 3.3x |
| SEVERITY scan | ~90 bytes | 177 bytes | 2x |
| NETWORK scan | 185 bytes | 249 bytes | 1.3x |
| Tail-call groups | 7 | 10 | Better distribution |
| CI jumps/byte | 2 | 1 | 2x optimization |
| Verification rate | 100% | 100% | Maintained |