Add typed host event egress rule

This commit is contained in:
Luna 2026-07-09 06:04:30 -07:00
parent 0b010df514
commit 3b037646d2
15 changed files with 360 additions and 31 deletions

View file

@ -117,13 +117,13 @@ enodia-sentinel rules docs
```
Inspects and tests event-driven detection rules without reading source code.
`rules list` includes built-in exec/syscall rules plus configured exec rules
from `exec_rules_file`. `rules show <sid>` prints the rule metadata and match
conditions. `rules test <event-json>` loads an exec or syscall event JSON file,
runs the matching rule engine, and prints any alerts that would fire. Use `-`
instead of a path to read the event JSON from stdin. `rules docs` emits Markdown
rule documentation from the active rule metadata; the built-in snapshot lives in
[RULES.md](RULES.md).
`rules list` includes built-in exec, syscall, and typed host-event rules plus
configured exec rules from `exec_rules_file`. `rules show <sid>` prints the rule
metadata and match conditions. `rules test <event-json>` loads an exec, syscall,
or host-event JSON file, runs the matching rule engine, and prints any alerts
that would fire. Use `-` instead of a path to read the event JSON from stdin.
`rules docs` emits Markdown rule documentation from the active rule metadata;
the built-in snapshot lives in [RULES.md](RULES.md).
Exec event JSON shape:
@ -151,6 +151,20 @@ Syscall event JSON shape:
}
```
Host event JSON shape:
```json
{
"event": "tcp_connect",
"pid": 42,
"ppid": 1,
"uid": 1000,
"comm": "python3",
"peer_ip": "8.8.8.8",
"peer_port": 4444
}
```
Exit code:
- `0`: list/show succeeded, or `rules test` matched at least one rule.

View file

@ -128,9 +128,12 @@ Exit criteria:
Purpose: reduce blind spots and connect related signals.
- Generalize the exec-rule engine into a typed host-event rule engine:
`exec`, `tcp_connect`, `bind`, `listen`, `accept`, `file_write`,
`chmod/chown`, `setuid/setgid`, `capset`, and module-load events.
- ✅ Add the first typed host-event rule family beside exec/syscall rules:
`rules test` accepts `tcp_connect` event JSON and ships SID `100067` for
interpreter egress to unusual public ports, with a replayable fixture.
- Continue generalizing the rule engine across more typed host events:
`bind`, `listen`, `accept`, `file_write`, `chmod/chown`, `setuid/setgid`,
`capset`, and module-load events.
- Keep rules declarative and Snort-like:
`sid`, `msg`, `severity`, `classtype`, `event`, and match fields such as
process name, parent process, argv regex, path prefix, peer IP/port, UID/GID,
@ -151,11 +154,10 @@ Purpose: reduce blind spots and connect related signals.
suspected trojaned binary with checksum cover-up.
- web/database service spawning shell + tool transfer (`curl|wget|sh`) →
CRITICAL likely RCE payload staging.
- Add high-signal living-off-the-land detections:
- Add additional high-signal living-off-the-land detections:
`curl|wget | sh`, Python/perl/bash reverse-shell argv variants,
`systemctl enable` from unusual ancestry, `chmod +s` outside package
transactions, interpreter egress to unusual public ports, and execution from
writable directories.
transactions, and execution from writable directories.
- Add first-seen and rarity tracking for local network behavior:
first public destination per process name, first listening port per binary,
interpreter connections to non-standard ports, and long-lived low-byte

View file

@ -1,6 +1,6 @@
# Enodia Sentinel Event Rule Reference
Generated from the active exec/syscall rule defaults plus any configured `exec_rules_file` entries.
Generated from the active exec/syscall/host-event rule defaults plus any configured `exec_rules_file` entries.
Use `enodia-sentinel rules list/show/test` to inspect rules and validate event fixtures locally.
@ -203,3 +203,23 @@ Expected false positives:
- Realtime or performance-sensitive services using `mlock` intentionally.
Drill or fixture: Use `rules test` with syscall `mlock`, `mlock2`, or `mlockall`.
## SID 100067: Interpreter connected to an unusual public port
- Event: `tcp_connect`
- Signature: `host_rule.suspicious-egress`
- Classtype: `suspicious-egress`
- Severity: `HIGH`
- Origin: `builtin`
Match fields:
- `events`: `tcp_connect`
- `comm`: `ash`, `bash`, `curl`, `dash`, `fetch`, `ksh`, `lua`, `nc`, `ncat`, `netcat`, `node`, `nodejs`, `perl`, `php`, `python`, `python2`, `python3`, `ruby`, `sh`, `socat`, `wget`, `zsh`
- `peer_public`: `True`
- `peer_port_exclude`: `22`, `53`, `80`, `123`, `443`, `853`
Expected false positives:
- Interactive admin scripts that intentionally connect to a non-standard public service.
- Developer tooling using interpreters for custom APIs on high ports.
Drill or fixture: Use `rules test` with a `tcp_connect` event whose `comm` is an interpreter and whose public `peer_port` is not a common service port.

View file

@ -70,7 +70,9 @@ Optional bcc eBPF monitors feed event rule engines. The `execve` stream closes
the polling gap for short-lived commands and supports custom TOML rules without
code changes. The syscall stream watches short-lived memory and anti-analysis
behavior: RWX `mprotect`/`mmap`, `memfd_create`, sensitive `ptrace`, seccomp,
cross-process memory access, and memory locking. Failure is fail-safe: if a
cross-process memory access, and memory locking. Typed host-event rules can be
tested from JSON fixtures before live sources exist; `tcp_connect` currently
covers interpreter egress to unusual public ports. Failure is fail-safe: if a
probe cannot load, polling continues.
### Integrity and Tamper-Evidence
@ -136,8 +138,8 @@ incident.
### Detect
- More event sources: `tcp_connect`, `bind`, `accept`, file-write events for
persistence paths, module loading, privilege transitions, and LSM hooks.
- More live event sources: `tcp_connect`, `bind`, `accept`, file-write events
for persistence paths, module loading, privilege transitions, and LSM hooks.
- Correlation across signals: "web service spawned shell" + "new listener" +
"persistence write" should become one incident, not three unrelated alerts.
- Optional YARA-style and Sigma-like local rules if they can stay dependency