<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT -->
---
name: yara-rules-guide
description: YARA rule syntax and pattern matching reference for malware detection, threat hunting, and file classification
tags: [detection, security]
---

# YARA Rules Guide

## Overview

YARA is a pattern-matching tool designed to identify and classify malware samples, suspicious files, and other artifacts. Security researchers describe malware families or threat indicators using rules composed of textual patterns, hexadecimal sequences, regular expressions, and boolean conditions. YARA rules are the standard language for file-based threat detection across antivirus engines, sandboxes, threat intelligence platforms, and incident response toolkits.

A YARA rule consists of three main sections: **meta** (descriptive metadata), **strings** (patterns to search for), and **condition** (boolean logic that determines a match). Rules can also import modules (PE, ELF, math, hash) to inspect file structure and properties beyond raw content.

## When to Use This Skill

- Writing detection signatures for known malware families or campaigns.
- Hunting for suspicious files across endpoints, network shares, or malware repositories.
- Classifying unknown samples during incident response triage.
- Building automated file scanning pipelines in CI/CD or upload processing.
- Creating retroactive detection rules after threat intelligence reports.
- Validating that security tools correctly identify known-bad artifacts.

## How It Works

### Step 1: Analyze the Sample

Examine the malware sample or suspicious artifact to identify distinctive characteristics. Use static analysis tools (strings, hex editors, disassemblers) to find unique byte sequences, embedded strings, filenames, mutexes, registry keys, or structural anomalies.

### Step 2: Identify Unique Patterns

Select patterns that are specific to the malware and unlikely to appear in benign software. Good patterns include:
- Unique strings (C2 domains, mutex names, PDB paths, error messages).
- Specific byte sequences from obfuscation routines or shellcode.
- Structural characteristics (unusual section names, import combinations).
- Behavioral indicators (encoded commands, specific API call patterns).

### Step 3: Write String Definitions

Define strings using the appropriate type for each pattern:

**Text strings:**
```
$s1 = "malware_config.dat"
$s2 = "cmd.exe /c whoami" nocase
$s3 = "CreateRemoteThread" wide ascii
```

**Hexadecimal strings (byte patterns):**
```
$hex1 = { 4D 5A 90 00 03 00 00 00 }       // MZ header
$hex2 = { 68 ?? ?? ?? ?? FF 15 }            // push addr; call [addr]
$hex3 = { 48 8B [2-4] 48 89 }              // mov reg, [rip+?]; mov ...
```

**Regular expressions:**
```
$re1 = /https?:\/\/[a-z0-9\-\.]+\.(xyz|top|buzz)\/[a-z]{8}/
$re2 = /[A-Za-z0-9+\/]{50,}={0,2}/         // base64 blob
```

**String modifiers reference:**

| Modifier | Effect |
|----------|--------|
| `nocase` | Case-insensitive matching |
| `wide` | Match UTF-16LE encoding (two bytes per character) |
| `ascii` | Match ASCII encoding (default, explicit when combined with `wide`) |
| `fullword` | Match only when delimited by non-alphanumeric characters |
| `base64` | Match the base64-encoded form of the string |
| `base64wide` | Match base64-encoded form in UTF-16LE |
| `xor` | Match XOR-encoded variants (optional key range: `xor(0x00-0xff)`) |
| `private` | Do not report the string in match output |

### Step 4: Build the Condition

Combine string matches and file properties using boolean logic:

**Basic operators:**
```
condition:
    $s1 and $s2                         // both strings present
    $s1 or $s2                          // either string present
    not $s3                             // string absent
    any of ($s*)                         // any string matching $s prefix
    all of ($s*)                         // all strings matching $s prefix
    2 of ($s1, $s2, $s3, $s4)           // at least 2 of the listed strings
```

**Positional operators:**
```
condition:
    $hex1 at 0                          // string at file offset 0
    $s1 in (0..1024)                    // string within first 1KB
    #s1 > 3                             // string appears more than 3 times
```

**File properties:**
```
condition:
    filesize < 500KB                    // file size constraint
    filesize > 1MB and filesize < 10MB
    uint16(0) == 0x5A4D                 // MZ header check (little-endian)
    uint32(0) == 0x464C457F             // ELF header check
```

**Iteration (for loops):**
```
condition:
    for any i in (1..#s1) : (@s1[i] < 0x1000)   // any occurrence in first 4KB
    for all section in pe.sections : (section.entropy > 7.0)
```

### Step 5: Test and Validate

Run the rule against a corpus of known-good and known-bad samples to verify accuracy:

```bash
# Scan a single file
yara rule.yar suspicious_file.exe

# Scan a directory recursively
yara -r rule.yar /path/to/samples/

# Show matching strings and their offsets
yara -s rule.yar suspicious_file.exe

# Show metadata and tags
yara -m rule.yar suspicious_file.exe

# Compile rules for faster scanning
yarac rules_dir/ compiled.yarc
yara -C compiled.yarc /path/to/scan/
```

Iterate on the rule to eliminate false positives while maintaining detection of all known variants.

## Examples

### Example 1: Detecting a Known Webshell Pattern

A YARA rule to detect common PHP webshell indicators:

```yara
rule PHP_Webshell_Generic
{
    meta:
        author = "FAOS Security"
        description = "Detects common PHP webshell patterns"
        severity = "high"
        date = "2025-01-15"
        reference = "T1505.003 - Server Software Component: Web Shell"

    strings:
        $eval1 = "eval($_" ascii nocase
        $eval2 = "eval(base64_decode(" ascii nocase
        $eval3 = "eval(gzinflate(" ascii nocase
        $exec1 = "system($_" ascii nocase
        $exec2 = "passthru($_" ascii nocase
        $exec3 = "shell_exec($_" ascii nocase
        $exec4 = "exec($_" ascii nocase
        $upload = "move_uploaded_file(" ascii nocase
        $obf1 = "str_rot13(" ascii nocase
        $obf2 = "gzuncompress(" ascii nocase
        $obf3 = "chr(ord(" ascii nocase
        $marker1 = "FilesMan" ascii nocase
        $marker2 = "b374k" ascii nocase
        $marker3 = "r57shell" ascii nocase
        $marker4 = "c99shell" ascii nocase

    condition:
        filesize < 1MB and
        (
            any of ($marker*) or
            (any of ($eval*) and any of ($exec*)) or
            (any of ($eval*) and $upload) or
            (2 of ($obf*) and any of ($exec*))
        )
}
```

### Example 2: Detecting Suspicious PowerShell Encoding

A YARA rule for identifying obfuscated PowerShell commands commonly used in malware droppers:

```yara
rule Suspicious_PowerShell_Encoding
{
    meta:
        author = "FAOS Security"
        description = "Detects encoded or obfuscated PowerShell execution"
        severity = "medium"
        mitre_attack = "T1059.001 - PowerShell, T1027 - Obfuscated Files"
        date = "2025-01-15"

    strings:
        $ps_enc1 = "-EncodedCommand" ascii nocase
        $ps_enc2 = "-enc " ascii nocase
        $ps_enc3 = "-ec " ascii nocase
        $ps_bypass1 = "-ExecutionPolicy Bypass" ascii nocase
        $ps_bypass2 = "-ep bypass" ascii nocase
        $ps_bypass3 = "Set-ExecutionPolicy Unrestricted" ascii nocase
        $ps_hidden1 = "-WindowStyle Hidden" ascii nocase
        $ps_hidden2 = "-w hidden" ascii nocase
        $ps_noprof = "-NoProfile" ascii nocase
        $ps_nonint = "-NonInteractive" ascii nocase
        $dl_cradle1 = "DownloadString(" ascii nocase
        $dl_cradle2 = "DownloadFile(" ascii nocase
        $dl_cradle3 = "Invoke-WebRequest" ascii nocase
        $dl_cradle4 = "Net.WebClient" ascii nocase
        $dl_cradle5 = "Start-BitsTransfer" ascii nocase
        $iex1 = "Invoke-Expression" ascii nocase
        $iex2 = "IEX(" ascii nocase
        $iex3 = "IEX (" ascii nocase

        $b64_ps = "powershell" base64 base64wide

    condition:
        (
            any of ($ps_enc*) and
            (any of ($ps_bypass*) or any of ($ps_hidden*))
        ) or
        (
            any of ($dl_cradle*) and any of ($iex*)
        ) or
        (
            any of ($ps_enc*) and any of ($dl_cradle*)
        ) or
        $b64_ps
}
```

### Example 3: PE Module Analysis for Suspicious Executables

A YARA rule using the PE module to detect executables with anomalous structural properties:

```yara
import "pe"
import "math"

rule Suspicious_PE_Characteristics
{
    meta:
        author = "FAOS Security"
        description = "Detects PE files with suspicious structural anomalies"
        severity = "medium"
        date = "2025-01-15"

    condition:
        uint16(0) == 0x5A4D and                          // MZ header
        filesize < 5MB and
        (
            // Suspicious section names
            for any section in pe.sections : (
                section.name == ".upx0" or
                section.name == ".aspack" or
                section.name == ".nsp0" or
                section.name == ".enigma" or
                section.name == ".themida"
            )
            or
            // High entropy in code section (likely packed/encrypted)
            for any section in pe.sections : (
                section.name == ".text" and
                math.entropy(section.offset, section.size) > 7.2
            )
            or
            // Very few imports (typical of packed malware)
            (pe.number_of_imports > 0 and pe.number_of_imports < 5)
            or
            // Writable and executable section (RWX)
            for any section in pe.sections : (
                section.characteristics & 0xE0000000 == 0xE0000000
            )
            or
            // Timestamp anomaly: compiled in the future or before 2000
            (pe.timestamp > 1893456000 or pe.timestamp < 946684800)
        )
}
```

## Best Practices

### Do This

- Include comprehensive metadata: author, description, date, severity, MITRE ATT&CK reference, and sample hashes.
- Test rules against large benign file corpora (clean OS installs, common applications) before deployment.
- Use the most specific string types possible -- hex patterns with wildcards are more precise than broad regex.
- Combine content-based strings with structural checks (file size, headers, entropy) to reduce false positives.
- Version your YARA rules in source control and track which rule detected which sample.
- Use `private` modifier for strings that assist matching logic but should not clutter output.
- Prefer `fullword` for function names and API calls to avoid substring matches.
- Document why each string was selected and what malware behavior it represents.

### Don't Do This

- Do not write rules that match only on common strings (e.g., "http://", "kernel32.dll") without additional constraints.
- Do not use unbounded regular expressions like `/.*/` that cause excessive scanning time.
- Do not omit `filesize` constraints -- scanning multi-gigabyte files without limits degrades performance.
- Do not rely on a single string match; use conditions that require multiple indicators.
- Do not forget to handle encoding variants (wide, ascii, base64) when targeting cross-platform malware.
- Do not deploy rules to production without testing against a false-positive validation set.
- Do not use overly broad hex wildcards like `{ ?? ?? ?? ?? }` that match nearly everything.

## Security Checklist

- [ ] Rule includes complete metadata (author, description, date, severity, references)
- [ ] Rule tagged with MITRE ATT&CK technique IDs where applicable
- [ ] Strings are specific enough to avoid matching benign software
- [ ] Condition logic requires multiple indicators (defense in depth)
- [ ] File size constraint included to limit scanning scope
- [ ] Rule tested against known-good sample corpus (zero false positives)
- [ ] Rule tested against known-bad sample corpus (confirmed detection)
- [ ] Hex patterns verified with correct byte order and wildcard placement
- [ ] Regular expressions bounded and tested for performance
- [ ] Rule compiles without warnings (`yara -w rule.yar`)
- [ ] Encoding variants considered (wide, ascii, base64, xor) for cross-platform coverage
- [ ] Rule documented in threat intelligence platform with associated campaign or malware family
- [ ] Performance tested: rule scans 10,000 files without excessive latency

## Related Skills

- @mitre-attck-reference -- Map YARA detections to ATT&CK techniques for coverage analysis
- @sigma-rules-guide -- Complement file-based YARA rules with log-based Sigma detection rules
- @ir-playbook-templates -- Integrate YARA scanning steps into incident response workflows
- @cve-epss-guide -- Correlate YARA-detected exploits with CVE and EPSS vulnerability data
- @cwe-sans-top25 -- Link malware behaviors to underlying software weaknesses

## Additional Resources

- YARA documentation: https://yara.readthedocs.io/en/stable/
- YARA GitHub repository: https://github.com/VirusTotal/yara
- VirusTotal YARA module reference: https://yara.readthedocs.io/en/stable/modules.html
- YARA-Forge community rules: https://github.com/YARAHQ/yara-forge
- Awesome YARA (curated list): https://github.com/InQuest/awesome-yara
- Florian Roth's signature-base: https://github.com/Neo23x0/signature-base

<!-- Source: .faos/custom/skills/security/yara-rules-guide/SKILL.md -->
