Tools · Forensics tools · 14 / 25
YARA: describe a portable executable without quoting a payload
The PE module lets a rule talk about imports, sections, and an import hash. Use it to describe a binary you already have, and keep the hit as a cluster to review.
Import the module you mean to use
YARA modules add facts about a file format. import "pe" makes PE fields available in the condition. import "hash" makes hash functions available if you need to pin an entire file you already hashed in Autopsy. You import only what the condition uses. A rule that imports pe and never mentions pe is noise for the next reader.
pe.is_pe is the basic gate. filesize still belongs beside it. From there you can require a section name, an import, or an imphash. These are descriptions of structure. They are the right tool when the bytes that matter are the shape of a program, and the wrong tool when the bytes that matter are the workbook name. The payroll file is not a PE. The stock powershell.exe is. Decide which exhibit the rule is about before you import anything.
An import is a name in a table
pe.imports can test whether a module and a function name appear in the import table. That is a static declaration in the file, and it is not a trace that the function ran. A binary that imports a network API and a process API is common, including in administrative tools Northline actually uses. A rule that fires on a single common import will fire on a large part of System32. Pair an import with something case-specific, or use it as one of several facts in a count, and expect to review the hits.
If you do not yet have a case-specific structural fact, do not invent one by listing every sensitive-sounding API. Take the binary you already extracted, look at its imports with a viewer you trust, and encode the combination you observed. The rule then means “this shape, which we saw on this file,” and the test list has a must-hit file you can point at.
An imphash groups files that share an import list
pe.imphash is a hash of the import table. Files built the same way share it, including files that share a compiler’s runtime and nothing else about your case. An imphash match is a cluster. You open one member, you compare it to the hash Autopsy already computed for the whole file, and you see whether you have one program or a family of cousins. Quoting an imphash in the report is useful when you have at least two files and you are explaining why you treated them together.
Pin a full-file hash with the hash module when you need the rule to find that exact specimen again in a noisy folder. That rule is a lookup, and it will not find a variant. Say so in meta: “exact SHA-256 of the Temp binary extracted on 15 April” or “imphash cluster, review required.” Those are different claims. Mixing them in one condition without a sentence in meta is how a lookup pretends to be a behavior rule.
import "pe"
rule NL_Lab_Imphash_Cluster
{
meta:
case = "NL-2026-041"
description = "Cluster tag for a binary whose import hash was recorded from the image. Review, do not assume purpose."
condition:
pe.is_pe and filesize < 20MB and
pe.imphash() == "0123456789abcdef0123456789abcdef"
// Example value of the right length. Use the imphash you computed.
}A structural hit still gets a label
Triage does not change because the condition looks technical. A PE hit is still content or needs-review. System32 files that share an imphash with a compiler runtime are expected once you have seen two of them. A Temp path with the same imphash as a System32 tool is the interesting member of the cluster, and the disk path is what makes it interesting, not the imphash alone. Write the path next to the hit.
Leave executable payloads out of the rule. You do not paste a confidential spreadsheet into a string to make a match. If the identifying fact is a hash, use the hash. If it is a path fragment you already published inside the case, use the text. The rule file is easy to forward by accident. Write it as if the SOC will.
Worked case: powershell.exe is a lookup, not a cluster of one
You already have the SHA-256 of the image’s powershell.exe from Autopsy, and it matched NSRL. A YARA rule that repeats that hash would only find the same bytes again. You do not need it for the case. You do write a tiny pe.is_pe rule in the lab to confirm the module loads, aimed at a copy of that binary, and the hit lands. The imphash printed by a one-off condition is recorded in the note as a description of that stock binary, with the NSRL match beside it.
No Temp binary exists in the export besides the workbook, which is not a PE, so there is no cluster to promote. The log says the PE module was checked, the stock shell matches the known hash, and the staged-name rule remains the rule that actually discriminates case text. You resist adding a list of network APIs that would flag half the laptop.
Diagram
Three PE facts and the claim each one is
What the condition is saying
- pe.is_pe
The file has a PE header. It is a gate so a workbook is not discussed as a program.
- Imports
The file declares those names in its import table. It does not show that they ran. Pair them with a case-specific fact.
- imphash
The import tables share a hash. Treat the result as a cluster, then look at paths and full-file hashes.
Check yourself
1. Two PE files share an imphash. One lives in System32 and matched NSRL. One lives in a user’s Temp directory and did not. What does the shared imphash support?