YARA: Complete Guide to Malware Detection, Threat Hunting, and Rule-Based Analysis Using Kali Linux

YARA: Complete Guide to Malware Detection, Threat Hunting, and Rule-Based Analysis Using Kali Linux

YARA (“Yet Another Recursive Acronym,” or informally “the pattern matching swiss knife for malware researchers”) is an open-source tool created by Victor Manuel Álvarez (originally at VirusTotal) used to identify and classify malware samples by creating descriptions — called rules — based on textual or binary patterns. Each rule is a set of strings (plain text, hex bytes, or regular expressions) plus a boolean condition that decides whether a file “matches.”

YARA is used for:

YARA ships as both a standalone command-line binary (yara) and a Python library (yara-python) for scripting.

Key Concepts

How to Install

On Kali Linux (already included in most Kali images):

sudo apt update
sudo apt install yara -y

Verify installation:

yara --version

Install the Python bindings (for scripting):

sudo apt install python3-yara -y
# or via pip inside a venv
pip install yara-python --break-system-packages

Build from source (latest version, with all modules):

sudo apt install -y automake libtool make gcc pkg-config \
    libssl-dev libjansson-dev libmagic-dev flex bison
git clone --recursive https://github.com/VirusTotal/yara.git
cd yara
./bootstrap.sh
./configure --enable-cuckoo --enable-magic --enable-dotnet
make
sudo make install
sudo ldconfig

Syntax

yara [OPTIONS] RULES_FILE TARGET
yara [OPTIONS] RULES_FILE PID

Where:

Basic rule syntax:

rule RuleName : tag1 tag2
{
    meta:
        author = "analyst"
        description = "detects sample X"
        date = "2026-07-19"

    strings:
        $s1 = "malicious_string" nocase
        $s2 = { E8 ?? ?? ?? ?? 5D C3 }
        $s3 = /regex_pattern/

    condition:
        uint16(0) == 0x5A4D and ($s1 or $s2) and $s3
}

All Command-Line Options (Kali Linux yara binary)

OptionLong formDescription
-t <tag>--tag=<tag>Only print matches for rules tagged with <tag>
-i <identifier>--identifier=<identifier>Only print matches for rules named <identifier>
-n--negatePrint only rules that did not match
-g--print-tagsPrint rule tags
-m--print-metaPrint rule metadata
-D--print-module-dataPrint module data (e.g., PE header fields used)
-e--print-namespacePrint rule namespace
-S--print-statsPrint rule-matching performance statistics
-s--print-stringsPrint matching strings and their offsets
-L--print-string-lengthPrint length of matched strings
-X--print-xor-keyPrint XOR key used, if xor modifier matched
-r--recursiveRecursively scan directories
-f--fast-scanFast matching mode (stop after first match per string)
-w--no-warningsDisable warning messages
-d <id>=<value>--define=<id>=<value>Define an external variable for use in conditions
-x <mod>=<file>--module-data=<mod>=<file>Pass extra data to a module
-a <seconds>--timeout=<seconds>Abort scanning after N seconds
-k <seconds>--stack-size=<slots>Set maximum stack size for the rule VM
-p <n>--threads=<n>Use N threads for scanning
-l <n>--max-rules=<n>Abort scanning after matching N rules
-C--compiled-rulesTreat RULES_FILE as a pre-compiled rules file
-N--no-follow-symlinksDon’t follow symlinks while scanning
-h--helpShow help
-v--versionShow version

yarac (the rule compiler) — compiles .yar rules into a faster-loading binary format:

yarac rules.yar compiled_rules.yrc
yara -C compiled_rules.yrc target_file

Basic Usage (Expected Output)

$ yara my_rule.yar suspicious.exe

Expected output when a rule matches:

Trojan_Generic suspicious.exe

Nothing is printed if there is no match.

With verbose flags:

$ yara -s -m my_rule.yar suspicious.exe
Trojan_Generic [author="analyst",description="detects sample X"] suspicious.exe
0x1040:$s1: malicious_string
0x2af0:$s2: E8 12 34 56 78 5D C3

Practical Examples with Output

Example 1 — Scan a single file

$ yara malware_rules.yar sample.exe
Emotet_Loader sample.exe

Example 2 — Recursively scan a directory

$ yara -r malware_rules.yar /home/analyst/samples/
Emotet_Loader /home/analyst/samples/batch1/sample1.exe
Cobalt_Strike_Beacon /home/analyst/samples/batch1/beacon.bin

Example 3 — Show matched strings with offsets

$ yara -s malware_rules.yar sample.exe
Emotet_Loader sample.exe
0x1a2f:$str_cmd: cmd.exe /c powershell -enc
0x2044:$str_mutex: Global\\EmotetMutex2024

Example 4 — Print rule metadata and tags

$ yara -m -g malware_rules.yar sample.exe
Emotet_Loader [banker,trojan] [family="Emotet",severity="high"] sample.exe

Example 5 — Scan a running process by PID

$ sudo yara -p 4 injected_rules.yar 6821
CobaltStrike_Beacon_Memory 6821

Example 6 — Using the pe module to check a compile timestamp and section count

import "pe"
rule Suspicious_PE_Timestamp
{
    condition:
        pe.timestamp < 946684800 and pe.number_of_sections > 8
}
$ yara -D pe_rules.yar sample.exe
Suspicious_PE_Timestamp sample.exe
pe.timestamp: 915148800
pe.number_of_sections: 10

Example 7 — Negate match (find files that do NOT match a known-good rule)

$ yara -n known_good.yar /mnt/samples/*.exe
KnownGood_Signed_Binary /mnt/samples/unsigned_tool.exe

Example 8 — Using external variables in a condition

rule Filesize_Check
{
    condition:
        filesize < filesize_limit
}
$ yara -d filesize_limit=1048576 size_rule.yar sample.bin
Filesize_Check sample.bin

Example 9 — Compile rules for faster repeated scanning

$ yarac big_ruleset.yar big_ruleset.yrc
$ time yara -C big_ruleset.yrc -r /mnt/samples/
real    0m1.204s

Example 10 — Multi-threaded recursive scan with a timeout

$ yara -r -p 8 -a 60 malware_rules.yar /mnt/evidence/
Ransomware_LockBit /mnt/evidence/case001/payload.exe

Example 11 — Hex wildcard pattern matching

rule Shellcode_NOP_Sled
{
    strings:
        $nop = { 90 90 90 90 90 ?? ?? ?? ?? }
    condition:
        $nop
}
$ yara nop_rule.yar shellcode.bin
Shellcode_NOP_Sled shellcode.bin

Example 12 — Regex string with count condition

rule Multiple_IP_Addresses
{
    strings:
        $ip = /\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/
    condition:
        #ip >= 5
}
$ yara ip_rule.yar config_dump.txt
Multiple_IP_Addresses config_dump.txt

Common Use Cases

Automation with Bash

Batch scan and log results with timestamps:

#!/bin/bash
RULES="/opt/yara-rules/all_rules.yar"
TARGET_DIR="/mnt/samples"
LOGFILE="/var/log/yara_scan_$(date +%F).log"

echo "[*] Starting YARA scan: $(date)" | tee -a "$LOGFILE"
yara -r -s -m -w "$RULES" "$TARGET_DIR" | tee -a "$LOGFILE"
echo "[*] Scan complete: $(date)" | tee -a "$LOGFILE"

Alert only on matches (for cron/SOC pipeline):

#!/bin/bash
MATCHES=$(yara -r /opt/yara-rules/all_rules.yar /mnt/incoming/)
if [ -n "$MATCHES" ]; then
    echo "$MATCHES" | mail -s "YARA ALERT: Malware detected" soc@example.com
fi

Recompile all rule files nightly for performance:

#!/bin/bash
for rule in /opt/yara-rules/*.yar; do
    yarac "$rule" "${rule%.yar}.yrc"
done

Tips and Best Practices

Troubleshooting

ProblemCause / Fix
error: syntax error, unexpected ...Malformed rule syntax — check for missing colons, braces, or semicolons
warning: rule "X" is slowOverly broad regex or wildcard hex string — narrow the pattern
No matches on a known-bad fileCheck string modifiers (nocase/wide), confirm condition logic, test each string individually with -s
yara: error scanning ...: Permission deniedRun with elevated privileges when scanning process memory (sudo)
Compiled rules (-C) fail to loadCompiled rules are version-specific — recompile with the same yara/yarac version installed
Extremely slow scans on large directoriesUse -p for multithreading, -f for fast-scan mode, and compiled rulesets
Module (pe, elf) fields return undefinedThe module wasn’t built into your YARA binary — rebuild from source with --enable-<module>, or install yara with full module support

References

Exit mobile version