Technical deep-dive · 2026-05-25

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:

  1. Hub checks whether the hash appears in the manifest for the current package version on that agent.
  2. If yes: silent rebaseline, no alert.
  3. If no: Critical alert — binary changed without a known package update.

The manifest is populated from two sources:

# 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:

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:

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 detectionBehaviour-based (slow)Hash compare (< 60s)
False positives on updatesn/aSuppressed via manifest
Lateral-movement correlationSiloIntegrated (LateralMovementWorker)
OverheadKernel 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.

Back to blog