← All posts

What File Integrity Monitoring Actually Catches on Linux

Aswad Gul · 2026-07-26 · 6 min read

File integrity monitoring is a simple idea: record a cryptographic hash of every file you care about, re-check periodically, alert when a hash changes unexpectedly. Almost every compliance framework asks for it. Far fewer teams run it well.

Key Takeaways

  • FIM catches the artefacts attackers leave on disk: webshells, backdoored binaries, and the config changes that establish persistence.
  • It is blind to anything that never touches the filesystem, which makes it one layer rather than a strategy.
  • Every real FIM tool is a scheduled, efficient version of hash, compare, alert. The tooling is not the hard part.
  • Deployments fail for one reason: too many alerts. Scope narrowly, baseline per server, and distinguish expected change from unexplained change.
  • A baseline taken on an already-compromised server records the intrusion as normal. Baseline from a known-good state.

Table of Contents

What it catches

Webshells. An attacker drops a script into your web root. No new process, no new port, nothing in auth logs, but a new file exists, and FIM sees it.

Backdoored binaries. A replaced ls or ps that hides the attacker's activity. Rootkits do this routinely, and the modified binary hashes differently.

Config tampering. Changes to sshd_config, sudoers, cron, or systemd units, the exact drift a hardening pass can't catch once it's done. Persistence usually requires touching one of these.

Silent drift. Not every finding is an attack. Sometimes a deploy script overwrote a config nobody meant to change. That is still worth knowing.

The paths that earn their place

Some locations are worth watching because they are genuinely static on a healthy server, which gives them a naturally high signal rate:

  • /etc/sudoers and /etc/sudoers.d/, a dropped file here is a common escalation and persistence step, and the main sudoers file stays untouched, so it is easy to miss
  • ~/.ssh/authorized_keys for every user, the most durable persistence there is, since it survives password rotation entirely
  • /etc/cron.d/, /etc/cron.*/, and the systemd unit and timer directories
  • /etc/ld.so.preload, rare enough that its mere existence on most systems is a finding, since a library listed there is injected into every dynamically linked process That last one is worth singling out. If an attacker preloads a library, the output of ps, ls, and find becomes unreliable, which means the tools you would use to investigate are compromised. The wider set of artefacts is in detecting privilege escalation on a Linux server.

What it misses

FIM is blind to anything that does not touch the filesystem: in-memory attacks, credential theft, data exfiltration over an existing connection, or abuse of legitimate credentials. It is one layer, not a strategy.

Two further gaps worth naming. A throttled cryptominer running from a file it deleted after execution leaves nothing on disk to hash. And FIM alerting to a local log file accomplishes nothing against an attacker with root, who can edit that log, which is the argument for sending findings off the host as they are generated rather than storing them locally.

A minimal baseline, by hand

Before reaching for a dedicated tool, this is what FIM actually does under the hood:

# Baseline
find /etc /usr/bin /usr/sbin /root -type f -exec sha256sum {} \; > baseline.sha256

# Re-check later
sha256sum -c baseline.sha256 --quiet

Every real FIM tool (AIDE, Tripwire, osquery, Wazuh's syscheck) is a more efficient, scheduled version of that loop. Two caveats if you run it this way. Store the baseline off the server, or an attacker with root simply regenerates it. And take it immediately after provisioning, a baseline captured on a server that is already compromised records the attacker's files as legitimate, which is the failure mode that quietly defeats the whole control.

Why most FIM deployments fail

The failure mode is always the same: too many alerts. Monitor /var naively and every log rotation, cache write, and package update fires a change event. Within a week nobody reads the alerts. Three things fix this:

Scope deliberately. Monitor /etc, /usr/bin, /usr/sbin, /root, and your web root. Do not monitor log directories, caches, or temp.

Baseline per server. A web server and a database server have different normal. A shared baseline generates noise on both.

Distinguish expected change. A file changing during a deploy window is different from the same file changing at 3am. Timing and context matter as much as the hash. This is not a discipline problem. Any detection producing more findings than a person will read has an effective true positive rate of zero, however good its logic is, the same arithmetic examined in why manual server monitoring fails at 3am.

Self-healing baselines

The practical problem is that legitimate change happens constantly. If every package update requires manually re-approving hundreds of hashes, the system gets switched off.

A better approach: recognise package-manager-driven change as expected, update the baseline automatically, and reserve alerts for changes that have no legitimate explanation.

The distinction that makes this safe is provenance. A binary in /usr/bin whose hash changed at the same moment the package manager recorded an upgrade of the package owning it has an explanation. The same binary changing with no corresponding package transaction does not, and that is the alert worth waking someone for.

That is how SecAI runs FIM - scoped defaults, per-server baselining, and an AI validation pass that suppresses expected change before it reaches a human, so the compliance checkbox actually reflects something being watched. See it alongside the rest of the detection stack. Where this fits with everything else is covered in the guide to Linux server security software.

Frequently Asked Questions

How often should file integrity checks run? Continuously where the platform supports it, or hourly at minimum on the paths listed above. A daily scan gives an attacker a day of working room.

Does FIM slow the server down? Hashing every file across the whole filesystem is expensive. Hashing a scoped set of static directories is not. Cost follows scope, which is another reason to scope deliberately.

What is the difference between FIM and antivirus? Antivirus looks for known-bad content. FIM looks for unexpected change regardless of content, which is why it catches custom and modified payloads that no signature describes.

Do compliance frameworks require FIM specifically? Most ask for integrity monitoring of critical system files in some form. What an auditor actually wants is evidence it was running on specific servers during a specific period, as covered in server security requirements for UAE NESA and PDPL compliance.

My baseline is full of expected changes. How do I clean it up? Narrow the scope first rather than tuning exclusions one by one. Most noise comes from monitoring directories that were never good candidates, logs, caches, and application data that changes at runtime.

File integrity is one of six signals worth watching together. The rest are covered under Linux server security monitoring.

SecAI runs this continuously across the persistence paths described above: Linux file integrity monitoring.

SecAI monitors Linux servers for exactly these threats automatically.