YARA rule builder
Pick strings and write a condition that matches five builds of one loader and none of five clean files, including an antivirus signature database.
Goal
Incident response pulled five builds of the same loader from three hosts. You also have five clean files from those hosts that a good rule must leave alone, including an antivirus signature database.
Choose which candidate strings go into the rule, write the condition, and scan the set. The rule is ready when it matches every loader and nothing else. Samples are modelled by the strings they contain; no binaries are involved.
Candidate strings
- Mutex name the loader creates
- Config block marker “QX7CFG”
- Drop path for the second stage
- User agent used for check-in
- Shell command prefix
- Windows system library name
5 of 5 loaders matched · 4 false positives · 0 missed
rule QX7_Loader
{
meta:
description = "QX7 loader family, lab sample set"
author = "HackBlue lab"
strings:
$mutex = "Global\\qx7-sync" ascii wide
$cfg = { 51 58 37 43 46 47 ?? 01 }
$ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" ascii
$k32 = "kernel32.dll" ascii nocase
condition:
any of them
}| File | MZ | Size | Contains | Match | Truth |
|---|---|---|---|---|---|
loader_a.exe | yes | 210 KB | $mutex $cfg $path $ua $cmd $k32 | match | loader |
loader_b.exe | yes | 198 KB | $mutex $cfg $path $ua $k32 | match | loader |
loader_c.dll | yes | 240 KB | $mutex $cfg $ua $cmd $k32 | match | loader |
loader_d.exePacked build, mutex name is generated at run time | yes | 205 KB | $cfg $path $ua $k32 | match | loader |
loader_e.exeNewest build, config marker changed | yes | 221 KB | $mutex $path $ua $k32 | match | loader |
setup.exeSigned installer for a PDF reader | yes | 3.1 MB | $cmd $k32 $ua | match | clean (false positive) |
browser_helper.exe | yes | 1.2 MB | $ua $k32 | match | clean (false positive) |
notepad.exe | yes | 200 KB | $k32 | match | clean (false positive) |
av-defs.binAntivirus signature database that lists these indicators | no | 8.4 MB | $mutex $cfg $path | match | clean (false positive) |
cleanup.ps1Admin script | no | 4 KB | $cmd | no match | clean |
Steps
01Build a rule that matches all five loader samples and none of the five clean files.
Do this in the workbench above. This step completes itself when the condition is met.
02How many clean files does the starter rule (any of them, with four strings) match?
03Why does av-defs.bin match strings from the loader?
04The rule uint16(0) == 0x5A4D and $cfg matches four loaders. What does it miss, and what does that teach?
05Would filesize < 1MB work instead of the MZ header check here?