Comparisons
ClamAV alone is not enough for webshells
ClamAV says so itself. What the engine covers, where PHP webshell detection actually comes from, and what a layered stack on a hosting server looks like.
“We run ClamAV” is the most common answer to “what scans your customers’ files”, and it is a reasonable starting point. It is a poor finishing point, and the clearest statement of why comes from the ClamAV project itself.
ClamAV’s own framing
From the ClamAV documentation , verbatim:
ClamAV is not a traditional anti-virus or endpoint security suite.
It is a scanning engine plus a general malware signature feed, built for mail gateways and file scanning. There is no official claim of PHP webshell coverage anywhere on clamav.net or docs.clamav.net, checked on 4 September 2026. That is not a shortcoming; it is a scope statement, and it should be read as one.
So where does webshell coverage come from?
From third-party signature feeds — which means the real question is never “does ClamAV catch webshells” but “which feed did you load, and when did it last change”.
The free answer most self-built stacks use is the rfxn feed behind Linux Malware Detect. Measured on 4 September 2026, rfxn.yara
carried Last-Modified: Sun, 24 May 2026 14:33:02 GMT and maldet.sigs.ver
read 2026052490478 — the same date, 90,478 signatures. The CDN serves normally and no end-of-life notice is published, so this is a maintenance gap rather than a shutdown, and a single push would change it. A paid ClamAV signature feed in the same category — Malware Expert
, €50 per month for unlimited servers — had been updated on 3 September 2026 when we measured it in the same pass, so the staleness is specific to that free feed, not a property of signature feeds.
Check yours rather than inheriting our date:
curl -sI https://cdn.rfxn.com/downloads/rfxn.yara | grep -i last-modified
freshclam --version
ls -l --time-style=long-iso /var/lib/clamav/*.c[vl]d
The wider point — that a feed which quietly stops looks exactly like a feed that is working — is the subject of signed signature feeds explained .
Why signatures alone lose to this particular threat class
The bytes are supposed to vary. Webshell droppers are routinely obfuscated with eval, base64_decode, gzinflate, str_rot13 and multi-stage loading. A signature matches bytes; obfuscation changes bytes per sample at negligible cost to the attacker. This is why bartblaze/PHP-backdoors
splits its corpus into obfuscated and deobfuscated directories — and why any detection-rate number quoted without saying which half it was measured against is close to meaningless.
The malicious file is not always the payload. Captured exploit traffic includes uploaded .htaccess files that map a harmless extension to the PHP handler. The dangerous object there is three lines of configuration, not a shell. No content signature for a PHP backdoor will match it.
The strongest signal is context, not content. MITRE’s Linux detection analytic for web shells, AN1109 , is about where a file appeared:
File creation of unauthorized script (e.g., .php, .sh) in /var/www/html followed by execution of unexpected system utilities (e.g., curl, bash, nc) by apache/nginx
A pure content scanner cannot express “there should never be a .php file in this uploads directory”. That rule needs to know the path, the site and the directory’s purpose — which is a property of the scanning system, not of the signature database.
And more heuristics is not a free upgrade. The NSA’s repository says of its own extended rule set, verbatim , that rules detecting obfuscation and encoding “are likely to produce a significant number of false positive results”. Coverage bought with noise gets switched off by the support team within a month.
What a layered stack looks like
The order matters, because each layer should be cheaper and more certain than the next:
- Known-good allow-lists. Checksums of WordPress core and other known files, so the biggest source of noise never reaches a heuristic.
- Hash sets. Exact, cheap, unambiguous — the same shell dropped on 40 accounts is one hash.
- Signatures. ClamAV databases plus YARA rules, matching known families and their variants.
- Heuristics, gated. Entropy, escape density, dynamic evaluation, variable function calls — scored together, never individually decisive, and kept in report mode until you trust them on your own fleet.
- Context rules. Path-aware policy: a
.phpunderuploads/, an.htaccesswith a handler directive.
Shelltrap’s Full profile runs ClamAV, YARA, hash sets and heuristics together in an unprivileged worker isolated with namespaces and Landlock. Where clamd is unreachable by the worker or the host has too little memory for the reload spike, the installer selects the Lite profile and says so — scanner.enable_clamd = false in the configuration — because reduced coverage should be a visible decision rather than a silent one. A result that could not be produced is unscanned or degraded; it is never converted into clean.
That layering also maps onto German baseline guidance. BSI IT-Grundschutz OPS.1.1.4 recommends, at elevated protection levels, automated analysis of suspicious files in sandboxes (A10) and scanners with multiple alternative scan engines for high-value systems (A11) (IT-Grundschutz OPS.1.1.4 ). That is our mapping of the requirements onto the architecture, not a BSI certification of anything.
Getting more out of the ClamAV you already run
- Run
clamd, notclamscanper file. Process startup dominates otherwise. - Make the socket reachable by the scanning user. A socket only root can open is not usable by an unprivileged worker, and that single detail decides whether ClamAV participates at all.
- Budget for the reload spike. A database reload roughly doubles resident memory for a moment; on a busy hosting node that is the difference between a reload and an OOM kill. Shelltrap measures the available memory after that reserve before it selects the Full profile.
- Watch for sandbox interactions. On our own host,
clamdrefused file descriptors passed viaFILDESfrom a systemd mount sandbox under AppArmor; the fix was an automaticINSTREAMfallback. If your integration passes descriptors, test it under your LSM policy rather than in a permissive shell. - Keep limits explicit (
--max-filesize,--max-scansize) and treat “skipped because too large” as its own verdict, not as clean.
What this means for CyberPanel operators
- Write down which signature feed feeds your ClamAV, and monitor its age. That is your actual coverage, and it is the thing nobody instruments.
- Do not let a single engine’s clean verdict end an investigation; the manual cross-checks are in find webshells on a CyberPanel server manually .
- Add path-context rules — PHP under uploads, handler directives in
.htaccess— because they catch what content signatures structurally cannot. - If you are weighing the free stack against a commercial one, the honest comparison is in maldet versus Shelltrap , and the profile requirements are in the installation docs .
Shelltrap runs ClamAV as one engine of four, states which profile it selected, and never turns “could not scan” into “clean”. See what it does .
Frequently asked
Does ClamAV detect PHP webshells?
That depends entirely on which signature database you loaded. There is no official claim of PHP webshell coverage on clamav.net, checked 4 September 2026, and the official databases are a general malware feed. Webshell coverage comes from third-party feeds.
Is ClamAV worth running at all?
Yes, as one engine among several. It is fast, free, well maintained and catches the known. The mistake is treating it as the whole detection layer rather than as one signal.
Why not just use more YARA rules?
Because broad obfuscation rules produce, in the NSA’s own words about its extended rule set, a significant number of false positive results. More heuristics without gating and allow-lists buys coverage with noise your support team pays for.
Sources
Every number, date and vendor claim in this article links to one of these.
- ClamAV documentation — accessed 2026-09-04
- Linux Malware Detect signature feed, rfxn.yara (measured with curl -I) — accessed 2026-09-04
- Linux Malware Detect signature version file, maldet.sigs.ver — accessed 2026-09-04
- bartblaze/PHP-backdoors — obfuscated and deobfuscated sample corpus — accessed 2026-09-04
- nsacyber/Mitigating-Web-Shells (NSA repository) — accessed 2026-09-04
- MITRE ATT&CK T1505.003 — Server Software Component: Web Shell — accessed 2026-09-04
- BSI IT-Grundschutz-Kompendium 2023 — OPS.1.1.4 Schutz vor Schadprogrammen (PDF) — accessed 2026-09-04
- Malware Expert — ClamAV signature subscription (paid feed) — accessed 2026-09-04
More from the research desk
False positives on WordPress core, and what to do
Which WordPress files trip generic malware heuristics, why entropy alone is a bad signal, and how to tune a host-level …
GuidesFind webshells on a CyberPanel server manually
A root-level triage playbook with find, grep, YARA and clamscan for CyberPanel hosts, including the honest limits of …
ComparisonsLinux Malware Detect (maldet) vs Shelltrap
maldet is free, GPL-2.0 and still shipping releases. The real question is the signature feed behind it — measured, with …
Shelltrap watches the files this article is about
Real-time detection, an upload gate in front of your PHP, explainable verdicts, and nothing leaving your server.