How to APT EP. 3: Owning Thread Execution with sched_ext Hashmaps
sched_ext lets custom BPF programs replace the core Linux CPU dispatcher. But when the entire attack surface of a rootkit is a 16-byte write to an already-trusted BPF hashmap, no EDR hook-monitor will ever see it coming. Here is how a custom scheduler becomes the ultimate process inventory and targeted starvation weapon.
How to APT EP.2: Lying to the whole netns through BPF_PROG_TYPE_FLOW_DISSECTOR
Flowdiss explores how BPF_PROG_TYPE_FLOW_DISSECTOR can be abused to forge the Linux kernel's notion of packet flow identity without modifying packet contents. By manipulating the flow_keys used to derive skb->hash, a privileged eBPF program can influence downstream consumers such as RPS, GRO, ECMP, and other eBPF programs that rely on the cached flow hash. The article presents a proof of concept, validates its effects and limitations, and demonstrates how a separate BPF LSM program can conceal the attack from standard bpftool enumeration, illustrating both an underexplored attack surface and the limits of relying on user-space BPF tooling on a compromised system.
How to APT EP.1: Bypassing XDP and TC: Stealthy Connection Interception via BPF SK_LOOKUP
While most offensive eBPF techniques rely on XDP or TC to intercept raw network packets, Linux 5.6+ introduced BPF_PROG_TYPE_SK_LOOKUP, a hook operating at the socket dispatch layer. By attaching a 28-line BPF program directly to a network namespace, an attacker can silently redirect incoming TCP SYN requests to a backdoor socket without modifying packets, recalculating checksums, altering iptables rules, or leaving wire-level artifacts. This post breaks down how the technique works, common implementation traps, why it evades conventional EDR checks, and how defenders can audit for it.
Cacheghost: Executing code from the kernel page cache
A file-backed executable mapping where the page content diverges from the backing file.
I Spent a Week Fuzzing the BPF Verifier's New Circular Number System
I spent the better part of a week reverse-engineering Meta's ~3500 line refactoring of the BPF verifier's bounds tracking, the "circular number" (or cnum) rework that landed in Linux 7.0. I built a fuzzer, ran a quarter million random tests, traced through the linked register propagation by hand, disassembled my running kernel's vmlinux to check for backports, and generally went deeper into `kernel/bpf/verifier.c` than any sane person should.
