# rules

YARA rules

WPSniffer does not ship a secret signature database. Every detection comes from YARA rules you can read: thousands of community rules collected by YARA Forge, plus any rules you write yourself. This page explains how to pick a package, pin it, add your own rules and deal with noisy ones.

How YARA detection works

YARA is the standard pattern-matching language of the malware research community. A rule names a set of strings, byte sequences or regular expressions and a condition that says how many of them must appear, and where, for a file to match. Because the rule is plain text, you can see exactly why a file was flagged, which is not true of most WordPress security plugins.

WordPress malware is overwhelmingly PHP: webshells dropped into wp-content/uploads, backdoors appended to theme files, obfuscated loaders using eval(base64_decode(...)), SEO spam injectors, credit card skimmers and redirect scripts. Rules for these families are well represented in YARA Forge's PHP webshell collections, and WPSniffer scans every file whole so that rules with filesize conditions behave as their authors intended.

YARA Forge packages

YARA Forge collects public rules from many authors, tests them against large clean and malicious corpora, scores them, and publishes three packages that trade detection breadth against false positives. WPSniffer downloads the package you select with --yara-forge, caches it, and refreshes the cache daily.

PackageContentsFalse positivesUse it when
core defaultAbout 5,000 high-quality rules, including the PHP webshell rules that matter most for WordPress.FewestRoutine and scheduled scans. Start here.
extendedEverything in core plus rules with a lower score or a higher false-positive rate.More noiseYou already found something and want to look for siblings, or you are investigating a compromised server.
fullEverything YARA Forge publishes.Most noiseForensic sweeps where you will review every hit by hand.
noneNo download. Only the rules you pass with --rules.Depends on your rulesAir-gapped servers, CI, or scanning with a curated in-house rule set.
$ wpsniffer malware-scan --yara-forge core /var/www/html
$ wpsniffer malware-scan --yara-forge extended --match-all /var/www/html

Pinning a release

By default WPSniffer picks up the latest YARA Forge release when it refreshes the cache. That is what you want for a nightly scan. For reproducible scans, such as comparing two servers or re-running a scan during an incident, pin a specific YARA Forge release so every run uses exactly the same rules. The pinning option is listed under wpsniffer malware-scan --help; YARA Forge releases are tagged by date on the YARA Forge releases page.

Custom rules

Pass a .yar or .yara file, or a directory containing them, with --rules. You can combine your rules with a YARA Forge package or run them alone with --yara-forge none.

$ wpsniffer malware-scan --rules /etc/wpsniffer/rules --yara-forge core /var/www/html
$ wpsniffer malware-scan --rules /etc/wpsniffer/rules --yara-forge none /var/www/html

Each rule file is compiled into its own namespace. Two files can both define a rule named webshell_generic without conflicting, and a rule you copy from a blog post will not collide with one in YARA Forge. WPSniffer caches compiled rules, so a large custom set costs compile time once, not on every run.

Good sources of WordPress-specific rules to start from are the Pressidium YARA rules and the PHP rules inside signature-base, both of which YARA Forge already draws on.

Writing a rule

A YARA rule has three parts: optional meta, the strings to look for, and a condition. This example flags PHP files that decode and execute base64 payloads and are small enough to be a dropped loader rather than a real plugin file.

rule php_base64_eval_loader
{
    meta:
        description = "Small PHP file that evals a base64-decoded payload"
        author      = "your name"
        reference   = "https://example.com/writeup"
        score       = 60

    strings:
        $php  = "<?php"
        $eval = /eval\s*\(\s*(base64_decode|gzinflate|str_rot13)\s*\(/ nocase

    condition:
        $php at 0 and $eval and filesize < 20KB
}

Keep rules narrow. A rule that matches only base64_decode will fire on half the plugins in the WordPress directory; a rule that requires the decode to be fed straight into eval in a small file is far more precise. Fill in description, author, reference and score, because WPSniffer surfaces those fields as report columns.

Test a new rule against a clean WordPress install plus your real sites before relying on it. The YARA-X rule-writing guide covers the full syntax, including hex strings, regular expressions, modules and rule sets.

Handling false positives

Some rules are deliberately broad, and minified or obfuscated code in legitimate plugins can look like malware. When a rule keeps matching files you have confirmed are clean:

  • Stay on core for scheduled scans. It has the fewest false positives by design.
  • Exclude the rule with -e RULE_NAME. The name is the signature_id column in your report. Repeat -e for several rules.
  • Narrow the target. Scan wp-content/uploads and recently changed files with the broad packages, and the whole site with core.
  • Review before deleting. Read the matched_text and rule_reference columns; a match on a vendored JavaScript library or a well-known caching plugin is almost always noise.
  • Report upstream. If a YARA Forge rule fires on a popular plugin, open an issue with the rule author, linked from rule_reference, so the rule improves for everyone.
$ wpsniffer malware-scan -e NOISY_RULE_ONE -e NOISY_RULE_TWO /var/www/html

The YARA-X engine

WPSniffer scans with YARA-X, VirusTotal's Rust rewrite of YARA. It is faster than classic YARA on large rule sets, stricter about rule syntax, and safer to run on untrusted input. Compiled rules are cached between runs, files are scanned whole up to 50 MiB by default, and each file has a timeout so a single pathological input cannot stall the scan.

Credit and licensing

Rules are written by many researchers and published under their own licenses; YARA Forge collects them and WPSniffer credits the author of every rule in its report through the rule_author and rule_reference columns. WPSniffer itself is GPLv3. See the license and NOTICE page for details.