Completes Phase 5. Half of a Linux compromise is not a file on disk, it is a line added to a startup file — a curl in a shell profile, a systemd unit with a dull name, one extra key in authorized_keys. The payload is often unremarkable; what makes it an incident is that it survives a reboot and nobody reads those files from one year to the next. So this is not a scanner but an inventory with a memory. It records systemd units (system and per-user), cron in all its locations, autostart entries, shell profiles, authorized_keys and ld.so.preload, then reports what CHANGED. Three decisions, all of which are the difference between a report people read and one they turn off: * Content is hashed, not stat'd. An mtime can be set backwards with one touch, and someone editing a startup file is exactly the person who would. Verified: a backdated edit is still caught. * A first run reports no changes and says so. Everything would be a change, and a first-run report full of alarms is one nobody reads. What a first run can honestly say is how many entries no package claims — 97 of 1,026 on this machine — because that is true regardless of history. * Writing the baseline is an explicit act (`--accept`, or update_baseline on the wire). A plain check must never quietly record whatever is currently installed as normal; that is how a compromise becomes the new baseline. Package ownership decides what is ordinary: a unit that arrived with a package is the system working, the same unit unowned is somebody's decision. Reuses the merged-/usr-aware index from the rootkit rewrite, with a test asserting most units resolve to a package — if that ratio collapses, ownership lookup has broken and the whole report is noise. Exercised end to end against this machine: baseline of 1,026 items, a planted user unit caught as ADDED, an in-place edit with a backdated mtime caught as CHANGED, and its deletion caught as REMOVED. The test artifact was removed afterwards. Cross-distro verification of the rootkit rewrite is now MET. Henry ran the suite on the Ubuntu box (26.04, glibc 2.43): 20/20, including both unowned_setuid_does_not_fire_on_a_healthy_system and no_false_positives_on_system_binaries. 214 tests pass across the workspace. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
27 lines
592 B
TOML
27 lines
592 B
TOML
[workspace]
|
|
resolver = "2"
|
|
members = ["crates/*"]
|
|
|
|
[workspace.package]
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
license = "MIT"
|
|
repository = "https://git.joelovestech.com/Hound/Antivirus.git"
|
|
|
|
[workspace.dependencies]
|
|
hound-supply = { path = "crates/hound-supply" }
|
|
anyhow = "1"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
clap = { version = "4", features = ["derive"] }
|
|
colored = "2"
|
|
time = { version = "0.3", features = ["serde", "std", "formatting"] }
|
|
inotify = "0.10"
|
|
yara-x = "1.19"
|
|
libc = "0.2"
|
|
sha2 = "0.10"
|
|
|
|
[profile.release]
|
|
lto = true
|
|
strip = true
|
|
codegen-units = 1
|