Process DNA: how a SHA256 hash of /proc/<pid>/exe surprises an attacker
Classic EDR looks at behaviour. Process DNA looks at what a process IS — a hash of the binary on disk. How it works, what it detects and what it doesn't.
A classic intrusion-detection rule looks at behaviour: unusual network calls, abnormal CPU spikes, suspicious cron entries. That works — until an attacker replaces a binary that's already running. The service is still called nginx. The PID is the same. The alert never fires.
Process DNA fingerprinting tackles the problem differently: not what a process does, but what it is.
How the agent computes the hash
On every inventory cycle (60 seconds by default), the monsys agent iterates over every process in /proc:
for pid in /proc/[0-9]*/exe; do
sha256sum $(readlink -f "$pid") 2>/dev/null
done
In the Rust implementation this happens via std::fs::read_link + sha2::Sha256. The hash is computed over the actual binary on disk — not over the memory of the running process, because that would be far too easy for an attacker to manipulate.
The result per top process (anything with RSS above a configurable threshold, 50 MB by default):
{
"pid": 1842,
"name": "nginx",
"exe_path": "/usr/sbin/nginx",
"exe_sha256": "a3f2c1...",
"observed_at": "2026-05-25T09:14:02Z"
}
TOFU: Trust on First Use
The first time the agent sees a binary, the hub stores its hash as the baseline. That's the TOFU model (Trust on First Use): we trust whatever is already running at install time, and alert on any deviation afterwards.
Upside: no whitelist to maintain. Downside: if the agent is installed after an attacker has already replaced a binary, the malicious hash is in the baseline. This is a deliberately accepted trade-off — deploy the agent early, ideally in your provisioning pipeline.
The false-positive problem: auto-updates
Suppose nginx is upgraded via apt upgrade. The binary on disk changes. The hash no longer matches the baseline. Without extra logic: a Critical alert on every package-manager update.
monsys solves this with the manifest-aware rebaseline. The hub maintains a release manifest per package/binary. When a new hash arrives:
- Hub checks whether the hash appears in the manifest for the current package version on that agent.
- If yes: silent rebaseline, no alert.
- If no: Critical alert — binary changed without a known package update.
The manifest is populated from two sources:
- The package inventory the agent already sends (
dpkg -l,rpm -qa) - Optionally, a pre-signed manifest you inject yourself for in-house software
# package-inventory event triggers manifest lookup
apt_package: nginx 1.25.4-1
→ hub: fetch known_hashes for nginx@1.25.4-1 from manifest_store
→ match found: rebaseline silently
What Process DNA detects that EDR misses
Standard EDR tools run as a user-space daemon or kernel module on the host. They see process events via netlink or eBPF. But in a hypervisor-isolated VM — like Claude Cowork or any cloud sandbox — those tools are blind to what happens inside the VM boundary.
The monsys agent runs inside the VM. The hash computation happens locally on the host. Only the aggregated signal (hash + metadata) goes upstream to the hub — no raw binary content, no log lines.
Attack scenarios Process DNA detects:
Supply-chain compromise — An npm package is published with a malicious postinstall that overwrites a system binary. The binary name is the same, but the SHA256 is new and isn't in the manifest. Alert within the next inventory cycle (max 60 seconds).
Living-off-the-land — An attacker replaces /usr/bin/curl with a patched version that exfiltrates credentials but otherwise works normally. Process DNA traps it the moment the new binary first shows up as a top process.
Fileless with disk component — Pure in-memory attacks aren't visible to Process DNA (honeypots are the complementary layer there). But the moment a payload writes anything to disk and executes it, it's on the record.
The lateral-movement correlation
Process DNA events combine with the rest of the SMART correlation pipeline. The most striking example: a suspicious binary change on server A, followed by a successful SSH login from server A to server B within five minutes.
The LateralMovementWorker (cadence: 60s) JOINs:
SELECT
pd.agent_id AS source_agent,
pd.exe_path,
pd.exe_sha256,
ae.target_agent_id,
ae.auth_user,
ae.observed_at AS ssh_at
FROM process_dna_alerts pd
JOIN auth_events ae
ON ae.src_ip = (SELECT ip FROM agents WHERE id = pd.agent_id)
AND ae.observed_at BETWEEN pd.observed_at - INTERVAL '5 min'
AND pd.observed_at + INTERVAL '5 min'
AND ae.success = true
WHERE pd.baseline_match = false
AND pd.tenant_id = $1
Result: a single detection event with MITRE tags T1078 (Valid Accounts) + T1036 (Masquerading), with a direct link between the binary swap and the lateral movement.
Operationally: what you see in the dashboard
When Process DNA detects a deviation, a Critical alert appears with:
exe_path: the path of the suspect binarybaseline_hash: the known-good hashobserved_hash: the new, unknown hashfirst_seen_pid: the process IDmanifest_checked: true/false (was a package update expected?)
The AI Explain button (local llama3.1:8b) gives you a readable summary:
"Binary /usr/sbin/sshd has an unknown SHA256. No matching package update found in the inventory. This could indicate a compromised OpenSSH installation. Recommended action: compare the hash with sha256sum /usr/sbin/sshd on the server, check package provenance with dpkg -V openssh-server, and consider IsolateNetwork via Emergency Actions."
Limitations — stated plainly
Process DNA does not work on:
- In-memory-only payloads without a disk component (shellcode injection, reflective DLL loading)
- Scripted attacks via Python/Bash/PowerShell — the interpreter binary doesn't change, only the script content
- Processes under the RSS threshold — small processes (< 50 MB by default) aren't fingerprinted to limit overhead; this is configurable
For the first two categories, honeypot canaries are the complementary detection layer: an attacker that reads a canary path in memory still triggers an alert.
Summary
| Traditional EDR (external) | Process DNA (monsys) | |
|---|---|---|
| Visibility in VM sandbox | ✗ (hypervisor boundary) | ✓ (runs inside the VM) |
| Binary-swap detection | Behaviour-based (slow) | Hash compare (< 60s) |
| False positives on updates | n/a | Suppressed via manifest |
| Lateral-movement correlation | Silo | Integrated (LateralMovementWorker) |
| Overhead | Kernel module / agent | ~5 MB Rust binary, < 1% CPU |
Process DNA is not a replacement for a full EDR stack at organisations with a dedicated SOC. It's a layer that works where EDR is blind — inside the VM boundary — and correlates with the rest of the pipeline without you needing a separate platform.
Want to test it yourself? Install the agent on a server, wait for the first inventory cycle, then replace a binary manually. The alert appears within 60 seconds. First five servers are free: monsys.ai/en/signup.