Use when auditing or exploiting Linux eBPF verifier and JIT behavior, building CO-RE/libbpf research probes, exercising maps and ring buffers, attaching kprobe, fentry, LSM, cgroup, tc, or XDP programs, evaluating unprivileged BPF exposure, or enumerating and removing hidden BPF state.
Use this skill to research eBPF as two distinct surfaces: pre-privilege verifier/JIT/kernel attack surface, and controlled post-privilege instrumentation. Keep kernel exploitation claims separate from what a privileged BPF program can already do.
When to use
Use this skill when the task involves:
verifier acceptance, abstract-state confusion, helper lifetime, reference tracking, or state explosion;
JIT translation, constant blinding, native-code differential behavior, or architecture-specific lowering;
bpf() syscall commands, union bpf_attr, program/map/link types, helpers, kfuncs, or BTF;
libbpf, CO-RE relocations, skeleton generation, bpffs pins, or bpf_link lifetime;
eBPF persistence/rootkit research in a disposable lab and the corresponding visibility/cleanup tests;
enumeration of live programs, maps, links, attachments, JIT images, and pinned objects.
Route a resulting generic kernel read/write or control-flow primitive to linux-kernel-exploitation. Route broad corpus generation that is not BPF-specific to offensive-fuzzing.
Completion standard
A completed case pins kernel and BPF policy, preserves the exact instruction/object input, captures full verifier and JIT evidence, distinguishes required privilege from impact, reproduces across a controlled kernel matrix, and proves cleanup of every program, map, link, pin, and hook.
Preserve the exact kernel image, config, vmlinux, modules, BTF blob, symbols, libbpf commit/version, bpftool build, clang/LLVM version, architecture, and boot line. Hash generated BPF ELF objects and raw instruction streams.
Record relevant configuration: CONFIG_BPF, CONFIG_BPF_SYSCALL, CONFIG_BPF_JIT, CONFIG_BPF_JIT_ALWAYS_ON, CONFIG_BPF_UNPRIV_DEFAULT_OFF, CONFIG_DEBUG_INFO_BTF, CONFIG_DEBUG_INFO_BTF_MODULES, CONFIG_CGROUP_BPF, CONFIG_BPF_LSM, CONFIG_KPROBE_EVENTS, CONFIG_UPROBE_EVENTS, CONFIG_FTRACE, CONFIG_KASAN, and CONFIG_KCOV.
Capability rules vary by kernel and operation. Record effective/permitted/ambient capabilities, user and network namespaces, LSM policy, seccomp, container context, and whether the operation relies on CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN, or legacy CAP_SYS_ADMIN fallback.
2. Inventory the live BPF surface
Run privileged and unprivileged views separately when the case permits:
bpftool -j feature probe > feature.json
bpftool -j prog show > programs.before.json
bpftool -j map show > maps.before.json
bpftool -j link show > links.before.json
bpftool -j net show > net.before.json
bpftool -j cgroup tree > cgroups.before.json
find /sys/fs/bpf -xdev -printf '%y %m %u %g %p -> %l\n' > bpffs.before.txt 2>/dev/null
An empty unprivileged listing does not prove no BPF objects exist. Preserve permission errors and compare with an appropriately privileged view. Record bpffs mount namespace, tracefs/debugfs mounts, network namespace, cgroup hierarchy, and all pin paths.
For each program retain ID, tag, type, name, load time, UID, map IDs, BTF ID, JIT status/size, memlock, and attachment. For each map retain type, key/value sizes, maximum entries, flags, BTF key/value types, owner program, pins, and freeze state. For each link retain type, target, owning program, pin, and expected detach semantics.
3. Choose the research lane
State one lane before changing state:
Lane
Starting privilege
Question
Verifier/JIT vulnerability
Unprivileged or constrained caller
Can malformed bytecode violate verifier/JIT/kernel invariants?
Helper/kfunc lifetime
Type-specific load privilege
Can references, ownership, or sleepable context become inconsistent?
Hook instrumentation
Privileged operator
What can a valid program observe or alter at one hook?
Persistence/visibility
Privileged disposable lab
Which objects survive process exit or namespace changes, and who can enumerate them?
Defensive reconstruction
Read or dump access
What programs, maps, links, and attachments existed and what did they do?
Do not report privileged policy manipulation as a privilege escalation. Do not describe an unavailable unprivileged path as exposed merely because the kernel contains the program type.
4. Model verifier state precisely
The verifier reasons about instructions, not C source. Preserve the final instruction stream after compiler optimizations and relocations. Track:
registers R0 through R10, scalar bounds, signed/unsigned ranges, and tnum known bits;
pointer class, fixed/variable offset, object ID, nullability, and bounds;
stack slot initialization, spilled pointer type, and 512-byte stack constraints;
reference acquisition/release, dynptr/ring-buffer ownership, and callback boundaries;
control-flow joins, state pruning, precision marks, loop bounds, subprogram calls, and tail calls;
32-bit versus 64-bit ALU semantics and sign/zero extension;
helper/kfunc prototypes, BTF types, allowed program types, sleepable context, and RCU rules.
Capture the complete verifier log at a level sufficient to show the decisive state transition. Keep accepted and rejected controls that differ by one intentional property. A verifier rejection string alone does not explain root cause.
When reducing a case, preserve:
the same kernel outcome;
the same decisive verifier state;
the same privilege and program type;
the same JIT/interpreter setting;
one nearby negative control.
5. Build a minimal libbpf/CO-RE harness
Compile with debug and BTF information, then inspect before loading:
Pin the target architecture macro to the actual build. Preserve .BTF, .BTF.ext, maps, license, program sections, relocations, and libbpf loader logs.
CO-RE relocations depend on target BTF and field/type existence. Record each relocation outcome and distinguish a compile-time source assumption from a load-time CO-RE adaptation. Treat bpf_core_field_exists and flavor matching as explicit compatibility branches, not silent portability.
For verifier research, support a raw BPF_PROG_LOAD path that supplies exact struct bpf_insn bytes, program type, expected attach type, license, flags, log buffer, BTF IDs, and attach BTF ID. The ELF/libbpf path and raw-instruction path answer different questions.
6. Compare verifier, interpreter, and JIT outcomes
Where the kernel supports controlled toggling, preserve the original sysctl values and restore them after testing. Reboot when BPF_JIT_ALWAYS_ON or policy makes toggling invalid.
For a loaded program capture translated and native forms:
bpftool prog dump xlated id "$PROG_ID" opcodes linum > xlated.txt
bpftool prog dump jited id "$PROG_ID" opcodes linum > jited.txt
Compare:
accepted/rejected result and verifier log;
BPF_PROG_TEST_RUN output and context mutation where supported;
interpreter versus JIT result on identical inputs;
architecture-specific branch ranges, immediate materialization, and exception behavior.
Do not infer exploitable native code from a textual disassembly mismatch. Prove a semantic divergence, reachable memory-safety effect, or kernel invariant violation with a minimized input and control.
7. Investigate helper, map, and lifetime boundaries
For each helper or kfunc record:
exact prototype and BTF type;
permitted program/attach types and GPL restriction;
pointer ownership before and after the call;
null/error behavior and scalar bounds;
RCU, lock, preemption, and sleepability context;
reference release required on every exit path;
kernel objects reached from map values, dynptrs, sockets, tasks, or local storage.
Map behavior is type-specific. Account for per-CPU values, LRU eviction, preallocation, mmap support, spin locks, timers, bloom filters, queues/stacks, ring buffers, map-in-map lifetime, object pinning, and freeze semantics.
For ring buffers, handle reservation failure, exact-size submission/discard, wakeup policy, consumer position, and lost-data accounting. A userspace consumer that cannot keep up is part of the experiment, not noise.
Prefer bpf_link-based attachment because ownership and teardown are explicit. Document whether closing the link detaches, whether the link is pinned, and whether a legacy attach survives the loader process.
Before attaching, subscribe to the exact expected event or test signal. Trigger one controlled operation, collect one correlated record, then run a negative control. Avoid broad always-on hooks while developing the schema.
9. Separate post-root capability from stealth claims
In a disposable post-root lab, evaluate observation or policy behavior as a measured hook experiment:
process/file/network event source and blind spots;
map or ring-buffer command/state channel semantics;
link and pin persistence across loader exit, namespace exit, service restart, and reboot;
visibility from bpftool, procfs/sysfs, tracefs, audit, EDR, and memory acquisition;
exact detach and object-release behavior.
Do not assume a renamed program, unpinned object, or absent bpftool output is hidden. IDs, tags, JIT memory, references, attachments, map contents, audit records, and kernel-memory artifacts may remain observable.
10. Fuzz and minimize deterministically
A verifier/JIT campaign records generator seed, instruction count, program type, flags, privilege, kernel hash, CPU, JIT mode, and timeout. Keep generation type-aware enough to reach deep verifier states, while retaining raw mutation for parser and boundary cases.
Useful harness paths include:
syzkaller descriptions for bpf() commands and related object lifetimes;
BPF_PROG_LOAD instruction generators with verifier-log capture;
differential runs across adjacent kernel commits or architectures;
BPF_PROG_TEST_RUN for repeatable context/data inputs;
KASAN/KMSAN/KCOV kernels for diagnosis, followed by production-like confirmation.
Minimize on the earliest stable signal: verifier divergence, warning, KASAN report, lockdep report, JIT/interpreter mismatch, or deterministic wrong result. Preserve a bounded timeout tied to process completion or a kernel event; do not use arbitrary polling sleeps.
11. Verify cleanup and residual state
Inventory after every case with the same privileged namespace view used for the baseline:
bpftool -j prog show > programs.after.json
bpftool -j map show > maps.after.json
bpftool -j link show > links.after.json
bpftool -j net show > net.after.json
bpftool -j cgroup tree > cgroups.after.json
find /sys/fs/bpf -xdev -printf '%y %m %u %g %p -> %l\n' > bpffs.after.txt 2>/dev/null
Close loader FDs, destroy links, detach legacy hooks, remove owned pins, stop consumers, remove tc/XDP attachments, and unmount only mounts created by the case. Compare before/after IDs, tags, targets, and pins. Account for ID reuse by matching more than the numeric ID.
Restore sysctls, resource limits, network namespace/device state, cgroup attachments, qdiscs, and debug mounts. If a verifier/JIT case may have corrupted kernel state, restore the VM snapshot rather than trusting in-place cleanup.
Key structures & interfaces
struct bpf_insn: opcode, destination/source registers, signed offset, and immediate; wide immediates occupy two instruction slots.
union bpf_attr: command-specific syscall contract for program, map, BTF, link, test-run, and ID operations.
bpf_prog, bpf_prog_aux, bpf_verifier_env, bpf_verifier_state, and register state: verifier and loaded-program ownership.
bpf_map and map-type implementations: key/value geometry, refcounts, memory accounting, callbacks, and pin ownership.
bpf_link and legacy attachment APIs: durable relationship between program and target.
BTF type graph plus .BTF.ext: function/line info and CO-RE relocation records.
bpf_object, bpf_program, bpf_map, and bpf_link in libbpf: userspace ownership and error paths.
perf event array and BPF ring buffer: output ordering, backpressure, loss, and consumer lifecycle.
helpers, kfuncs, dynptrs, local storage, timers, and refcounted kernel pointers: type-specific lifetime boundaries.
bpffs pins, program/map/link IDs, tags, and JIT images: live-state and forensic identities.
target.md kernel/config/BTF/toolchain/policy/capabilities and hashes
surface.before/ programs, maps, links, hooks, cgroups, pins, mount namespaces
case/ source, ELF, raw instructions, schemas, seed, verifier log
jit/ translated/native dumps, settings, inputs, differential result
runs.jsonl kernel, privilege, JIT mode, expected/observed outcome, timing
surface.after/ matching inventory plus cleanup diff and residual explanation
Keep verifier logs and object files together; compiler source without final instructions is not a reproducible verifier case.
Pitfalls & OPSEC
Do not confuse privileged BPF policy control with a pre-privilege kernel exploit.
Do not claim exposure without proving program type, attach type, capabilities, namespaces, sysctls, seccomp, lockdown, and LSM permit the path.
Do not compare C source when verifier behavior depends on optimized instructions and relocations.
Do not change JIT sysctls on a shared host; preserve prior values and use disposable kernels for unsafe cases.
Do not assume verifier acceptance means safe runtime behavior or verifier rejection means no JIT/parser exposure.
Do not trust empty unprivileged bpftool output as a complete inventory.
Do not leak pointer-bearing verifier logs, map contents, BTF internals, or host identifiers into public artifacts.
Avoid trace recursion, unbounded event output, and consumers that silently drop ring-buffer records.
Pins and legacy attachments can outlive the loader; process exit is not cleanup proof.
Program IDs can be reused; compare tags, type, load time, maps, BTF, and targets.
Instrumented kernels change timing and layout; reproduce on a production-like target before impact claims.
Snapshot rollback is mandatory after suspected JIT or kernel-memory corruption.
Routing
Route a proven generic kernel corruption, read/write, page-table, credential, or ROP primitive to batch-B sibling linux-kernel-exploitation.
Route post-root Linux host enumeration, credential provenance, persistence assessment, or pivots to batch-B sibling linux-host-post-exploitation.
Route custom agent use of eBPF telemetry or modules to batch-B sibling c2-implant-engineering.
Route COFF/BOF modules to batch-A sibling bof-coff-development.
Route Windows RPC, COM, DCOM, NDR, and ALPC trust boundaries to batch-A sibling windows-rpc-com-attack.
Route Windows provider engineering and ETW/WPP/TraceLogging measurement to batch-A sibling windows-telemetry-etw.
Route Hyper-V partitions, hypercalls, VMBus, VSP/VSC, and worker processes to batch-A sibling hyper-v-offensive.
Route broad fuzzing infrastructure to offensive-fuzzing; route detection and artifact searches to threat-hunting or memory-forensics.
Final gate
Exact kernel, config, BTF, toolchain, BPF policy, capabilities, and namespaces are recorded.
Raw instructions, ELF object, verifier log, program type, flags, and privilege reproduce the result.
Verifier, interpreter, JIT, helper, and attachment claims are kept distinct.
Positive and negative controls differ by one intentional property.
Fuzzing and race tests use exact signals and bounded waits, not timing luck.
Before/after inventories prove every program, map, link, pin, and hook was removed.
Generic kernel impact is handed off only after the BPF-specific root cause is established.
1---2name: ebpf-offensive3description: Use when auditing or exploiting Linux eBPF verifier and JIT behavior, building CO-RE/libbpf research probes, exercising maps and ring buffers, attaching kprobe, fentry, LSM, cgroup, tc, or XDP programs, evaluating unprivileged BPF exposure, or enumerating and removing hidden BPF state.4license: MIT5---6# eBPF offensive research78Use this skill to research eBPF as two distinct surfaces: pre-privilege verifier/JIT/kernel attack surface, and controlled post-privilege instrumentation. Keep kernel exploitation claims separate from what a privileged BPF program can already do.910## When to use1112Use this skill when the task involves:1314- verifier acceptance, abstract-state confusion, helper lifetime, reference tracking, or state explosion;15- JIT translation, constant blinding, native-code differential behavior, or architecture-specific lowering;16- `bpf()` syscall commands, `union bpf_attr`, program/map/link types, helpers, kfuncs, or BTF;17- libbpf, CO-RE relocations, skeleton generation, bpffs pins, or `bpf_link` lifetime;18- kprobe/uprobe, tracepoint, fentry/fexit, LSM, cgroup, tc, XDP, iterator, or socket hooks;19- eBPF persistence/rootkit research in a disposable lab and the corresponding visibility/cleanup tests;20- enumeration of live programs, maps, links, attachments, JIT images, and pinned objects.2122Route a resulting generic kernel read/write or control-flow primitive to `linux-kernel-exploitation`. Route broad corpus generation that is not BPF-specific to `offensive-fuzzing`.2324## Completion standard2526A completed case pins kernel and BPF policy, preserves the exact instruction/object input, captures full verifier and JIT evidence, distinguishes required privilege from impact, reproduces across a controlled kernel matrix, and proves cleanup of every program, map, link, pin, and hook.2728## Core workflow2930### 1. Freeze kernel, policy, and toolchain identity3132Capture facts before loading a program:3334```bash35uname -a36cat /etc/os-release37cat /proc/cmdline38bpftool version39clang --version40llc --version 2>/dev/null41cat /proc/sys/kernel/unprivileged_bpf_disabled 2>/dev/null42cat /proc/sys/net/core/bpf_jit_enable 2>/dev/null43cat /proc/sys/net/core/bpf_jit_harden 2>/dev/null44cat /proc/sys/net/core/bpf_jit_kallsyms 2>/dev/null45cat /sys/kernel/security/lockdown 2>/dev/null46```4748Preserve the exact kernel image, config, `vmlinux`, modules, BTF blob, symbols, libbpf commit/version, bpftool build, clang/LLVM version, architecture, and boot line. Hash generated BPF ELF objects and raw instruction streams.4950Record relevant configuration: `CONFIG_BPF`, `CONFIG_BPF_SYSCALL`, `CONFIG_BPF_JIT`, `CONFIG_BPF_JIT_ALWAYS_ON`, `CONFIG_BPF_UNPRIV_DEFAULT_OFF`, `CONFIG_DEBUG_INFO_BTF`, `CONFIG_DEBUG_INFO_BTF_MODULES`, `CONFIG_CGROUP_BPF`, `CONFIG_BPF_LSM`, `CONFIG_KPROBE_EVENTS`, `CONFIG_UPROBE_EVENTS`, `CONFIG_FTRACE`, `CONFIG_KASAN`, and `CONFIG_KCOV`.5152Capability rules vary by kernel and operation. Record effective/permitted/ambient capabilities, user and network namespaces, LSM policy, seccomp, container context, and whether the operation relies on `CAP_BPF`, `CAP_PERFMON`, `CAP_NET_ADMIN`, or legacy `CAP_SYS_ADMIN` fallback.5354### 2. Inventory the live BPF surface5556Run privileged and unprivileged views separately when the case permits:5758```bash59bpftool -j feature probe > feature.json60bpftool -j prog show > programs.before.json61bpftool -j map show > maps.before.json62bpftool -j link show > links.before.json63bpftool -j net show > net.before.json64bpftool -j cgroup tree > cgroups.before.json65find /sys/fs/bpf -xdev -printf '%y %m %u %g %p -> %l\n' > bpffs.before.txt 2>/dev/null66```6768An empty unprivileged listing does not prove no BPF objects exist. Preserve permission errors and compare with an appropriately privileged view. Record bpffs mount namespace, tracefs/debugfs mounts, network namespace, cgroup hierarchy, and all pin paths.6970For each program retain ID, tag, type, name, load time, UID, map IDs, BTF ID, JIT status/size, memlock, and attachment. For each map retain type, key/value sizes, maximum entries, flags, BTF key/value types, owner program, pins, and freeze state. For each link retain type, target, owning program, pin, and expected detach semantics.7172### 3. Choose the research lane7374State one lane before changing state:7576| Lane | Starting privilege | Question |77| --- | --- | --- |78| Verifier/JIT vulnerability | Unprivileged or constrained caller | Can malformed bytecode violate verifier/JIT/kernel invariants? |79| Helper/kfunc lifetime | Type-specific load privilege | Can references, ownership, or sleepable context become inconsistent? |80| Hook instrumentation | Privileged operator | What can a valid program observe or alter at one hook? |81| Persistence/visibility | Privileged disposable lab | Which objects survive process exit or namespace changes, and who can enumerate them? |82| Defensive reconstruction | Read or dump access | What programs, maps, links, and attachments existed and what did they do? |8384Do not report privileged policy manipulation as a privilege escalation. Do not describe an unavailable unprivileged path as exposed merely because the kernel contains the program type.8586### 4. Model verifier state precisely8788The verifier reasons about instructions, not C source. Preserve the final instruction stream after compiler optimizations and relocations. Track:8990- registers `R0` through `R10`, scalar bounds, signed/unsigned ranges, and `tnum` known bits;91- pointer class, fixed/variable offset, object ID, nullability, and bounds;92- stack slot initialization, spilled pointer type, and 512-byte stack constraints;93- reference acquisition/release, dynptr/ring-buffer ownership, and callback boundaries;94- control-flow joins, state pruning, precision marks, loop bounds, subprogram calls, and tail calls;95- 32-bit versus 64-bit ALU semantics and sign/zero extension;96- helper/kfunc prototypes, BTF types, allowed program types, sleepable context, and RCU rules.9798Capture the complete verifier log at a level sufficient to show the decisive state transition. Keep accepted and rejected controls that differ by one intentional property. A verifier rejection string alone does not explain root cause.99100When reducing a case, preserve:1011021. the same kernel outcome;1032. the same decisive verifier state;1043. the same privilege and program type;1054. the same JIT/interpreter setting;1065. one nearby negative control.107108### 5. Build a minimal libbpf/CO-RE harness109110Compile with debug and BTF information, then inspect before loading:111112```bash113mkdir -p build114clang -O2 -g -target bpf -D__TARGET_ARCH_x86 \115 -c src/probe.bpf.c -o build/probe.bpf.o116llvm-objdump -S -r build/probe.bpf.o > build/probe.disasm.txt117bpftool btf dump file build/probe.bpf.o format raw > build/probe.btf.txt118bpftool gen skeleton build/probe.bpf.o > build/probe.skel.h119```120121Pin the target architecture macro to the actual build. Preserve `.BTF`, `.BTF.ext`, maps, license, program sections, relocations, and libbpf loader logs.122123CO-RE relocations depend on target BTF and field/type existence. Record each relocation outcome and distinguish a compile-time source assumption from a load-time CO-RE adaptation. Treat `bpf_core_field_exists` and flavor matching as explicit compatibility branches, not silent portability.124125For verifier research, support a raw `BPF_PROG_LOAD` path that supplies exact `struct bpf_insn` bytes, program type, expected attach type, license, flags, log buffer, BTF IDs, and attach BTF ID. The ELF/libbpf path and raw-instruction path answer different questions.126127### 6. Compare verifier, interpreter, and JIT outcomes128129Where the kernel supports controlled toggling, preserve the original sysctl values and restore them after testing. Reboot when `BPF_JIT_ALWAYS_ON` or policy makes toggling invalid.130131For a loaded program capture translated and native forms:132133```bash134bpftool prog dump xlated id "$PROG_ID" opcodes linum > xlated.txt135bpftool prog dump jited id "$PROG_ID" opcodes linum > jited.txt136```137138Compare:139140- accepted/rejected result and verifier log;141- `BPF_PROG_TEST_RUN` output and context mutation where supported;142- interpreter versus JIT result on identical inputs;143- constant blinding and JIT hardening modes;144- emitted native bounds checks, speculation barriers, calls, tail calls, and exits;145- architecture-specific branch ranges, immediate materialization, and exception behavior.146147Do not infer exploitable native code from a textual disassembly mismatch. Prove a semantic divergence, reachable memory-safety effect, or kernel invariant violation with a minimized input and control.148149### 7. Investigate helper, map, and lifetime boundaries150151For each helper or kfunc record:152153- exact prototype and BTF type;154- permitted program/attach types and GPL restriction;155- pointer ownership before and after the call;156- null/error behavior and scalar bounds;157- RCU, lock, preemption, and sleepability context;158- reference release required on every exit path;159- kernel objects reached from map values, dynptrs, sockets, tasks, or local storage.160161Map behavior is type-specific. Account for per-CPU values, LRU eviction, preallocation, mmap support, spin locks, timers, bloom filters, queues/stacks, ring buffers, map-in-map lifetime, object pinning, and freeze semantics.162163For ring buffers, handle reservation failure, exact-size submission/discard, wakeup policy, consumer position, and lost-data accounting. A userspace consumer that cannot keep up is part of the experiment, not noise.164165### 8. Attach one hook with explicit ownership166167Select the narrowest hook matching the question:168169| Hook | Strength | Constraint |170| --- | --- | --- |171| tracepoint/raw tracepoint | Defined event schema or low-overhead raw context | Schema/build and context differences |172| kprobe/kretprobe | Broad dynamic coverage | Unstable symbols, inlining, recursion, missed returns |173| fentry/fexit/fmod_ret | BTF-typed function boundary | BTF availability and attach permissions |174| uprobe/uretprobe | Userspace function observation | Exact inode/build/offset and process mapping |175| LSM | Security decision visibility/enforcement | LSM ordering, return chaining, sleepable rules |176| cgroup | Per-cgroup socket/syscall policy points | Correct hierarchy, attach flags, multi-attach semantics |177| tc/XDP | Packet path at chosen layer | Namespace/device, headroom, MTU, offload, return action |178| iterator | Structured kernel-object traversal | Supported iterator target and teardown |179180Prefer `bpf_link`-based attachment because ownership and teardown are explicit. Document whether closing the link detaches, whether the link is pinned, and whether a legacy attach survives the loader process.181182Before attaching, subscribe to the exact expected event or test signal. Trigger one controlled operation, collect one correlated record, then run a negative control. Avoid broad always-on hooks while developing the schema.183184### 9. Separate post-root capability from stealth claims185186In a disposable post-root lab, evaluate observation or policy behavior as a measured hook experiment:187188- process/file/network event source and blind spots;189- map or ring-buffer command/state channel semantics;190- link and pin persistence across loader exit, namespace exit, service restart, and reboot;191- visibility from bpftool, procfs/sysfs, tracefs, audit, EDR, and memory acquisition;192- exact detach and object-release behavior.193194Do not assume a renamed program, unpinned object, or absent bpftool output is hidden. IDs, tags, JIT memory, references, attachments, map contents, audit records, and kernel-memory artifacts may remain observable.195196### 10. Fuzz and minimize deterministically197198A verifier/JIT campaign records generator seed, instruction count, program type, flags, privilege, kernel hash, CPU, JIT mode, and timeout. Keep generation type-aware enough to reach deep verifier states, while retaining raw mutation for parser and boundary cases.199200Useful harness paths include:201202- syzkaller descriptions for `bpf()` commands and related object lifetimes;203- `BPF_PROG_LOAD` instruction generators with verifier-log capture;204- differential runs across adjacent kernel commits or architectures;205- `BPF_PROG_TEST_RUN` for repeatable context/data inputs;206- KASAN/KMSAN/KCOV kernels for diagnosis, followed by production-like confirmation.207208Minimize on the earliest stable signal: verifier divergence, warning, KASAN report, lockdep report, JIT/interpreter mismatch, or deterministic wrong result. Preserve a bounded timeout tied to process completion or a kernel event; do not use arbitrary polling sleeps.209210### 11. Verify cleanup and residual state211212Inventory after every case with the same privileged namespace view used for the baseline:213214```bash215bpftool -j prog show > programs.after.json216bpftool -j map show > maps.after.json217bpftool -j link show > links.after.json218bpftool -j net show > net.after.json219bpftool -j cgroup tree > cgroups.after.json220find /sys/fs/bpf -xdev -printf '%y %m %u %g %p -> %l\n' > bpffs.after.txt 2>/dev/null221```222223Close loader FDs, destroy links, detach legacy hooks, remove owned pins, stop consumers, remove tc/XDP attachments, and unmount only mounts created by the case. Compare before/after IDs, tags, targets, and pins. Account for ID reuse by matching more than the numeric ID.224225Restore sysctls, resource limits, network namespace/device state, cgroup attachments, qdiscs, and debug mounts. If a verifier/JIT case may have corrupted kernel state, restore the VM snapshot rather than trusting in-place cleanup.226227## Key structures & interfaces228229- `struct bpf_insn`: opcode, destination/source registers, signed offset, and immediate; wide immediates occupy two instruction slots.230- `union bpf_attr`: command-specific syscall contract for program, map, BTF, link, test-run, and ID operations.231- `bpf_prog`, `bpf_prog_aux`, `bpf_verifier_env`, `bpf_verifier_state`, and register state: verifier and loaded-program ownership.232- `bpf_map` and map-type implementations: key/value geometry, refcounts, memory accounting, callbacks, and pin ownership.233- `bpf_link` and legacy attachment APIs: durable relationship between program and target.234- BTF type graph plus `.BTF.ext`: function/line info and CO-RE relocation records.235- `bpf_object`, `bpf_program`, `bpf_map`, and `bpf_link` in libbpf: userspace ownership and error paths.236- perf event array and BPF ring buffer: output ordering, backpressure, loss, and consumer lifecycle.237- helpers, kfuncs, dynptrs, local storage, timers, and refcounted kernel pointers: type-specific lifetime boundaries.238- bpffs pins, program/map/link IDs, tags, and JIT images: live-state and forensic identities.239240## Tooling241242| Need | Tools |243| --- | --- |244| Feature and object inventory | `bpftool feature/prog/map/link/net/cgroup`, bpffs, tracefs |245| Build and CO-RE | clang/LLVM, libbpf, `bpftool gen skeleton`, BTFHub when provenance is pinned |246| Bytecode inspection | `llvm-objdump`, `bpftool prog dump xlated`, raw instruction dumper |247| JIT inspection | `bpftool prog dump jited`, GDB/crash on a lab kernel, architecture disassembler |248| Runtime observation | libbpf logs, `bpftool prog tracelog`, perf, trace_pipe, controlled consumers |249| Discovery | syzkaller, KCOV, KASAN, KMSAN, lockdep, targeted instruction generators |250| Kernel diffing | exact source trees, `git bisect`, config/build manifests, semantic diffing |251| Defensive reconstruction | bpftool JSON, audit logs, memory images, `drgn`, crash, `memory-forensics` |252253## Evidence outputs254255```text256target.md kernel/config/BTF/toolchain/policy/capabilities and hashes257surface.before/ programs, maps, links, hooks, cgroups, pins, mount namespaces258case/ source, ELF, raw instructions, schemas, seed, verifier log259jit/ translated/native dumps, settings, inputs, differential result260runs.jsonl kernel, privilege, JIT mode, expected/observed outcome, timing261surface.after/ matching inventory plus cleanup diff and residual explanation262```263264Keep verifier logs and object files together; compiler source without final instructions is not a reproducible verifier case.265266## Pitfalls & OPSEC267268- Do not confuse privileged BPF policy control with a pre-privilege kernel exploit.269- Do not claim exposure without proving program type, attach type, capabilities, namespaces, sysctls, seccomp, lockdown, and LSM permit the path.270- Do not compare C source when verifier behavior depends on optimized instructions and relocations.271- Do not change JIT sysctls on a shared host; preserve prior values and use disposable kernels for unsafe cases.272- Do not assume verifier acceptance means safe runtime behavior or verifier rejection means no JIT/parser exposure.273- Do not trust empty unprivileged bpftool output as a complete inventory.274- Do not leak pointer-bearing verifier logs, map contents, BTF internals, or host identifiers into public artifacts.275- Avoid trace recursion, unbounded event output, and consumers that silently drop ring-buffer records.276- Pins and legacy attachments can outlive the loader; process exit is not cleanup proof.277- Program IDs can be reused; compare tags, type, load time, maps, BTF, and targets.278- Instrumented kernels change timing and layout; reproduce on a production-like target before impact claims.279- Snapshot rollback is mandatory after suspected JIT or kernel-memory corruption.280281## Routing282283- Route a proven generic kernel corruption, read/write, page-table, credential, or ROP primitive to batch-B sibling `linux-kernel-exploitation`.284- Route post-root Linux host enumeration, credential provenance, persistence assessment, or pivots to batch-B sibling `linux-host-post-exploitation`.285- Route custom agent use of eBPF telemetry or modules to batch-B sibling `c2-implant-engineering`.286- Route COFF/BOF modules to batch-A sibling `bof-coff-development`.287- Route Windows RPC, COM, DCOM, NDR, and ALPC trust boundaries to batch-A sibling `windows-rpc-com-attack`.288- Route Windows provider engineering and ETW/WPP/TraceLogging measurement to batch-A sibling `windows-telemetry-etw`.289- Route Hyper-V partitions, hypercalls, VMBus, VSP/VSC, and worker processes to batch-A sibling `hyper-v-offensive`.290- Route broad fuzzing infrastructure to `offensive-fuzzing`; route detection and artifact searches to `threat-hunting` or `memory-forensics`.291292## Final gate293294- [ ] Exact kernel, config, BTF, toolchain, BPF policy, capabilities, and namespaces are recorded.295- [ ] Raw instructions, ELF object, verifier log, program type, flags, and privilege reproduce the result.296- [ ] Verifier, interpreter, JIT, helper, and attachment claims are kept distinct.297- [ ] Positive and negative controls differ by one intentional property.298- [ ] Fuzzing and race tests use exact signals and bounded waits, not timing luck.299- [ ] Before/after inventories prove every program, map, link, pin, and hook was removed.300- [ ] Generic kernel impact is handed off only after the BPF-specific root cause is established.
Run npx skillmds@latest add netvar1337/ebpf-offensive in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Use when auditing or exploiting Linux eBPF verifier and JIT behavior, building CO-RE/libbpf research probes, exercising maps and ring buffers, attaching kprobe, fentry, LSM, cgroup, tc, or XDP programs, evaluating unprivileged BPF exposure, or enumerating and removing hidden BPF state. It is listed under Research & Search on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
netvar1337 (@netvar1337) published this skill. Their other Agent Skills are listed on their SkillMD profile.