elastic / elastic/detection-rules
[New Rule] On-Host eBPF Bytecode Compilation
- Dominant language
- Python
- Stars
- 2.7k
- Forks
- 696
- Avg merge
- 4d 17h
- Merged PRs (30d)
- 87
Description
**Description**
Detects on-host compilation of eBPF bytecode via `clang` targeting the `bpf` backend (`-target bpf`, `--target=bpf`, or `-target=bpf`), a step commonly required by eBPF-based rootkits and reconnaissance tooling that compile their kernel-side component directly on the victim host rather than delivering a prebuilt object file.
Endpoint coverage in this repo is otherwise mature (~360 Linux rules), so this is a narrow, confirmed slice rather than a missing category. The existing eBPF-related rules detect *loading* an already-compiled program (`bpftool` load/pin) or *discovery* activity (kprobe/tracefs enumeration), but nothing covers the compile step in between.
Built and validated against real compilation activity, not synthetic documents: ran the real Auditbeat binary against this host's actual kernel audit subsystem (`--cap-add=AUDIT_CONTROL --cap-add=AUDIT_READ --pid host --user root`, confirmed via the startup log actually accepting the audit rules) with an `execve`-watching audit rule, then compiled a small benign toy eBPF program with the real attack pattern (`clang -O2 -g -target bpf -c toy.bpf.c -o toy.bpf.o`), plus benign non-BPF compiles with both `gcc` and plain `clang` as the false-positive baseline. Also tested whether `clang` accepts the single-token `--target=bpf`/`-target=bpf` forms in addition to the two-token `-target bpf` form. It does, and a rule checking only the two-token form would have missed them, so the query was broadened to cover both, a finding from testing rather than an assumption. Shipped the real captured `execve` events through the actual installed `auditd_manager` ingest pipeline. Verified the exact final query against the real processed data: 3/3 true positives (all three real `-target bpf` argument-form variants), 0 false positives against real `gcc`/plain-`clang` compiles and clang's own internal `-cc1` sub-invocation.
**Target Ruleset**: linux
**Target Rule Type**: Custom (KQL or Lucene)
**Tested ECS Version**: 9.4.0
**Query**
```sql
event.category: "process" and event.action: "executed"
and process.executable: "*clang*"
and (
(process.args: "-target" and process.args: "bpf")
or process.args: ("*target*bpf*" or "*target*bpfel*" or "*target*bpfeb*")
)
```
**New fields required in ECS/data sources for this rule?**
None. Uses only standard ECS process fields (`event.category`, `event.action`, `process.executable`, `process.args`) already populated by the `auditd_manager` integration (or classic Auditbeat).
**Related issues or PRs**
None found. This rule complements existing `bpftool` load/pin and kprobe/tracefs-discovery rules by covering the compile step between delivery and loading.
**References**
- https://clang.llvm.org/docs/CommandGuide/clang.html
- https://ebpf.io/what-is-ebpf/
- https://attack.mitre.org/techniques/T1027/004/
**Redacted Example Data**
Real `execve` event captured during testing (home directory path replaced with `~`):
```json
{"process": {"executable": "/usr/bin/clang-22", "name": "clang", "args": ["clang", "-O2", "-g", "-target", "bpf", "-c", "toy.bpf.c", "-o", "toy.bpf.o"], "working_directory": "~/detection-engineering-lab/endpoint/testdata"}, "event": {"action": "executed", "category": ["process"], "type": ["start"], "outcome": "success"}}
```
Contributor guide
Research direction
Start with the linux custom ruleset and compare the existing eBPF-related loading and discovery rules. Validate the supplied KQL against auditd_manager-processed execve events, confirming the three target argument forms match while gcc, plain clang, and clang’s internal -cc1 invocation do not. Done means the rule covers the documented forms without those false positives.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux
- Domain
- security
- Issue type
- Feature
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 70/100