In this section

0.5 What Rules Cannot Do

Module 0

What a match is

A YARA match is one sentence: the bytes described by this rule are present in this file.

That is all. Everything else a match seems to say is something you supplied, and the gap between the sentence and the reading is where most YARA mistakes live.

One sentence, and four readings that are not in it A MATCH ESTABLISHES the described bytes are in this file somebody's rule considers this a member of a family the file is worth looking at a pointer, not a verdict IT DOES NOT ESTABLISH that the file is malicious that it ever executed that the rule name is accurate that no match means clean the last one is the expensive one Everything in the right-hand column is something the reader supplied, not something the tool said

A match is a statement about bytes. Every other reading is inference.

It does not mean malicious

The rule matched because the bytes were there. Whether their presence means the file is harmful depends entirely on how good the rule is, and the rule is a hypothesis written by a person from one sample.

This matters most with rules you did not write. Public rule sets are enormously useful and vary wildly in quality. A hit from a rule named APT_Loader_Generic tells you that a rule with that name matched, which is a fact about the rule's author's opinion and not about the file in front of you.

Prove it to yourself in one minute

Write a rule that describes genuine capability, aim it at a directory of software you trust completely, and count.

rule Dual_Use_Networking
{
    strings:
        $a = "socket"
        $b = "connect"
        $c = "send"
    condition:
        all of them
}
yr scan dual_use.yar /usr/bin/
#
# or with the Python bindings from Section 0.3
python3 scan.py dual_use.yar /usr/bin/

Predict the number before you reveal it. How many of roughly a thousand system binaries contain all three of those strings?

scanned 1066 files in /usr/bin
matched 74
   /usr/bin/Xvfb
   /usr/bin/aleph
   /usr/bin/amstex
   /usr/bin/bash
   /usr/bin/busctl
   /usr/bin/curl

Seventy-four hits, and among them bash and curl.

Every one of those is a true positive against the rule as written. The rule asked whether the file contains all three strings; the files contain all three strings. Nothing malfunctioned. What failed is the inference somebody would draw from a console showing seventy-four hits on a rule about network capability.

That is the gap this section is about, and it is not fixable by writing the rule more carefully. Network capability is not a property that distinguishes malicious software from curl, because curl is a network tool. Module 2 is about finding properties that do distinguish, and Module 5 is about measuring whether you succeeded.

The habit worth building now: when a rule fires, read the rule. Not the rule name, the rule. What patterns did it actually require, and are they the kind of thing that could appear in something legitimate? That takes thirty seconds and it prevents a whole class of confident wrong escalation.

It cuts the other way as well. Reading the rule sometimes tells you the hit is stronger than it looks: a rule requiring three independent patterns, two of them structural, is a much better piece of evidence than a rule requiring one common string, and both arrive in your console looking identical.

It does not mean the file ran

A file matching a rule for a credential stealer sitting in a download directory has not stolen anything. It might never have been opened.

YARA reads bytes at rest. Execution is a completely different evidence source, and the distinction is exactly the one FOR203 draws between what a file is equipped to do and what it did. A YARA match is on the first side of that line, always.

This is the inference most likely to escape into an incident report, because the language slips easily. "We found the stealer on twelve hosts" and "twelve hosts have a file matching our stealer rule" describe the same evidence and imply very different things.

The second phrasing costs four extra words and it is the one that survives review. It is also the one that keeps the next question answerable: if somebody asks whether those twelve hosts are compromised, the first phrasing has already answered yes on your behalf.

It does not confirm the family

Rule names carry attribution and attribution is frequently wrong.

Family naming across the industry is inconsistent, tooling reuses code, and a rule keyed on a shared packer or a common builder will fire across families that have nothing to do with each other. A hit from a rule called Emotet_Dropper is a hit from a rule somebody named that.

Where the family matters, the rule's own basis is what you check, not its name.

This matters more than it used to. A great deal of tooling is shared between groups now, some of it bought and some of it public, so a rule keyed on the tool identifies the tool rather than whoever was holding it. That can still be useful intelligence, provided the write-up says which of the two it is.

An absence establishes least of all

This is the important one, and it is the direct descendant of Section 0.1's silent failure.

No match means no match. It does not mean the file is clean. It means the bytes this particular rule describes were not found in this particular file by this particular engine, which leaves a great deal of room.

The rule may be keyed on something the actor changed. The scan may not have reached the file, because it was locked, encrypted, inside an archive the engine does not unpack, or on a host that was powered off. The engine may have skipped it on a size limit you set and forgot. Any of those produce a clean result identical to genuine absence.

Before a negative result becomes a finding, prove the check could have returned something. Run the rule against a file you know matches. If the control fires and the estate does not, the zero means something; if you never ran the control, it does not.

The control costs about ten seconds and it removes an entire class of silent failure. It is the same idea Section 0.1 raised about testing a rule against the sample it came from, turned around: there, a test that cannot fail proves nothing when it passes; here, a test that cannot succeed proves nothing when it returns empty.

What YARA cannot see at all

Worth stating plainly so you do not go looking.

Behavior. What a process did, what it connected to, what it wrote. That is telemetry, and it is Sigma's half of the problem.

Context of arrival. Who sent the file, to whom, and whether they opened it. A rule sees the file, not its provenance.

Anything requiring execution. Packed payloads that only exist in memory after unpacking are invisible on disk. Module 3 covers what structure survives packing, which is the partial answer, and Module 5 says where the partial answer runs out.

Intent. Software is not malicious in its bytes. A remote administration tool and a remote access trojan can be the same binary used differently, and no rule resolves that.

That one is a genuine limit rather than a gap to be engineered around. Plenty of dual-use software is flagged by public rule sets for exactly this reason, and the resulting hits are correct about the bytes and wrong about the situation.

Where this hands off

The honest position, and the same one FOR203 takes about triage.

When a match needs behavioral confirmation, that is detonation or endpoint telemetry. When it needs the file's history, that is triage and provenance. When the question is about activity rather than artifacts, that is Sigma and the SIEM. When the answer requires understanding what the code does rather than what it contains, that is reverse engineering, and this course stops there deliberately rather than pretending a clever rule substitutes for it.

Knowing where a technique stops is what makes the technique usable. A rule that claims only what it establishes is worth more than one that claims more and is right most of the time, because the first one can be relied on and the second one has to be checked.

Section 0.6 gets you the specimens, and then Module 1 starts on the language itself.