Expand rootkit monitoring and Claude docs

This commit is contained in:
Luna 2026-06-12 04:57:11 -07:00
parent a7129e5666
commit 3e5f8fc3f7
16 changed files with 524 additions and 32 deletions

View file

@ -76,7 +76,11 @@ Runs anti-rootkit cross-view checks once:
- PIDs alive via `kill(pid, 0)` but missing from `/proc`.
- Live modules in `/sys/module` but missing from `/proc/modules`.
- Listening TCP ports in `/proc/net/tcp*` but missing from `ss`.
- UDP ports in `/proc/net/udp*` but missing from `ss -u`.
- Network interfaces in promiscuous mode.
- Known rootkit module names.
- Tainted loaded modules (`/sys/module/*/taint`) and global kernel taint
(`/proc/sys/kernel/tainted`).
Exit code:
@ -261,6 +265,10 @@ HTTPS is mandatory. If `web_tls_cert` / `web_tls_key` are not configured,
Sentinel creates a self-signed pair under `log_dir`; add a browser exception for
that certificate or replace it with a private/local CA certificate.
The console exposes incidents, alert snapshots, posture findings, event tail,
and dry-run response plans. It remains read-only; response commands are displayed
for review but not executed from the browser.
Expected use: `enodia-sentinel-web.service`.
### `triage`

View file

@ -66,11 +66,15 @@ Expected healthy output:
acknowledged.
- `pkgdb-check`: package DB consistent with anchor.
- `pkgdb-verify`: sampled files match signed cache packages.
- `rootcheck`: no hidden processes, modules, ports, or sniffers.
- `rootcheck`: no hidden processes/modules/ports, sniffers, known rootkit
modules, or unexplained kernel/module taint.
- `posture check`: no SSH/sudo/PATH/permission/signature hygiene findings, or
only ones you have consciously accepted (e.g. password auth on a host that
needs it).
The HTTPS dashboard shows the same posture findings under the Posture tab for
quick remote review.
## Alert Workflow
When Sentinel fires:
@ -125,7 +129,7 @@ When Sentinel fires:
| `fim_modified` | Verify package ownership, package checksum, and whether the change followed an upgrade. |
| `pkgdb_tamper` | Treat as high-confidence tampering until a legitimate package transaction explains it. |
| `pkg_signature_mismatch` | Treat as a potentially trojaned package-owned file. |
| `hidden_*` rootcheck alerts | Compare live tools, preserve evidence, and consider offline analysis. |
| `rootkit_*` / `kernel_tainted` alerts | Compare live tools, review module provenance, preserve evidence, and consider offline analysis. |
## Baseline Hygiene

View file

@ -95,6 +95,13 @@ 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.
- 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,
package ownership, and lineage.
- Add eBPF event sources:
`tcp_connect`, `bind`, `accept`, module load, privilege transitions, and
writes to watched persistence paths.
@ -102,13 +109,60 @@ Purpose: reduce blind spots and connect related signals.
- Correlate multi-stage behavior:
web service spawns shell, shell downloads payload, payload adds persistence,
listener appears, and FIM changes.
- Add configurable correlation windows and severity escalation rules.
- Add configurable correlation windows and severity escalation rules, including:
- `exec_rule.web-rce` + suspicious egress + persistence within 10 minutes →
CRITICAL multi-stage intrusion.
- `new_listener` + `new_suid` in the same lineage/window → CRITICAL backdoor
with privilege-escalation artifact.
- `fim_modified` or `pkg_signature_mismatch` + `pkgdb_tamper` → CRITICAL
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:
`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.
- 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
connections when socket sampling can support it.
- Keep polling as the oracle and fallback.
Exit criteria:
- Short-lived network and persistence actions are visible.
- Related alerts collapse into one incident with a readable timeline.
- Multi-stage correlation raises one higher-confidence incident without hiding
the underlying raw alerts.
## v1.1.1: IDS Quality and Rule Operations
Purpose: make detection coverage easier to audit, tune, and extend without
turning Sentinel into a noisy rules dump.
- Add `enodia-sentinel rules list` and `rules show <sid>` for built-in and
configured rules.
- Add `enodia-sentinel rules test <event-json>` so operators can validate custom
event rules against captured or fixture events.
- Generate rule documentation from source defaults: SID, signature, classtype,
event type, match fields, expected false positives, and drill coverage.
- Require a fixture or safe red-team drill for every built-in SID, including
event-only and correlation SIDs.
- Add compatibility tests for rule JSON/event schema evolution.
- Extend triage so false-positive suggestions are tied to SID/classtype and can
emit TOML snippets for allowlists, correlation windows, or severity overrides.
- Add post-alert enrichment consistently across detections:
package owner, executable hash, parent/ancestor chain, remote IP
classification, file mode/owner, recent writes by same lineage, and current
FIM/package/rootcheck status.
Exit criteria:
- Operators can inspect, test, document, and tune detection rules without
reading Python source.
- Every shipped IDS rule has reproducible fixture/drill coverage and stable
operator documentation.
## v1.2: Fleet Mode

View file

@ -165,7 +165,9 @@ the transaction completes; a persistent mismatch is the real finding.
## Runbook 4 — Hidden listener / rootkit
**Triggers:** `rootkit_hidden_process` (100022), `rootkit_hidden_module` (100023),
`rootkit_hidden_port` (100024), `promiscuous_interface` (100025), and
`rootkit_hidden_port` (100024), `promiscuous_interface` (100025),
`rootkit_known_module` (100028), `rootkit_tainted_module` (100029),
`kernel_tainted` (100030), `rootkit_hidden_udp_port` (100031), and
`new_listener` (100013) for an unexplained open port.
These come from cross-view checks: the same question asked two ways, answered
@ -182,8 +184,16 @@ differently, because something is hiding.
- `new_listener`: identify the owning process and whether its binary is
package-owned. A hidden port that `rootcheck` sees but `ss` does not is far more
serious than a forgotten service.
- `rootkit_hidden_udp_port`: check whether a legitimate UDP service owns the
port; a port present in `/proc/net/udp*` but absent from `ss -u` suggests tool
output may be hooked.
- A `rootkit_hidden_module` names a live kernel module absent from
`/proc/modules` — strong evidence of an LKM rootkit.
- A `rootkit_known_module` finding names a module associated with public LKM
rootkits; treat it as a high-confidence compromise until proven otherwise.
- A `rootkit_tainted_module` or `kernel_tainted` finding may be legitimate
vendor/DKMS software, but unsigned/out-of-tree or force-loaded modules should
be explained and allowlisted only after review.
**Contain**
@ -197,8 +207,10 @@ differently, because something is hiding.
reliably clean a host whose kernel is hooked. Preserve the disk image first.
**False positives:** PID exit races (Sentinel re-verifies hidden PIDs to reduce
these) and a legitimately promiscuous interface (a sniffer/monitoring tool you
run). Confirm the owning process before escalating.
these), a legitimately promiscuous interface (a sniffer/monitoring tool you
run), and expected tainted vendor/DKMS modules. Confirm the owning process or
module provenance before escalating; use `rootcheck_module_allow` only for
modules you intentionally trust.
---

View file

@ -76,7 +76,7 @@ Sentinel includes several integrity layers:
| Package DB anchor | Detects out-of-band edits to `/var/lib/pacman/local`. |
| Signed-package anchor | Compares on-disk files to `.MTREE` hashes from cached signed packages. |
| Heartbeat | Writes daemon liveness for local dashboard and external watchdog use. |
| Rootcheck | Cross-view checks for hidden processes, hidden modules, hidden ports, and promiscuous interfaces. |
| Rootcheck | Cross-view checks for hidden processes, hidden modules, hidden TCP/UDP ports, promiscuous interfaces, known rootkit modules, and kernel/module taint. |
### Evidence Capture

View file

@ -27,7 +27,7 @@ Sentinel is designed to help against:
| Local privilege escalation | New SUID helper, dropped setuid shell, writable path abuse | Detect new SUID/SGID and critical writable-directory placement. |
| Fileless or short-lived execution | Deleted executable, memfd payload, fast `curl|sh` | Detect deleted executables and eBPF exec rules where available. |
| Package/file tampering | Trojaned binary, rewritten package DB checksums | Detect FIM drift, package DB tamper, and signed-package mismatches. |
| Common rootkit hiding | LD_PRELOAD tricks, `/proc` hiding, module-list hiding, hidden listener | Detect LD_PRELOAD and cross-view inconsistencies. |
| Common rootkit hiding | LD_PRELOAD tricks, `/proc` hiding, module-list hiding, hidden TCP/UDP sockets, tainted modules | Detect LD_PRELOAD, cross-view inconsistencies, known LKM names, and kernel/module taint. |
| Sensor tampering | Stop daemon, edit config, remove hook, modify baseline | Detect self-integrity changes and stale heartbeat via external watchdog. |
## Trust Boundaries