Minimal rule
rule suspicious_upx
{
meta:
author = "you"
description = "find UPX packed samples"
strings:
$mz = { 4D 5A }
$upx1 = "UPX0" ascii
$upx2 = "UPX1" ascii
condition:
$mz at 0 and 1 of ($upx*)
}
String modifiers you will actually use
$a = "powershell" ascii nocase
$b = "cmd.exe /c" wide
$c = /https?:\/\/[A-Za-z0-9._-]+/ ascii
$d = { 68 ?? ?? ?? ?? 6A 00 6A 00 }
# useful modifiers
ascii wide nocase fullword xor base64 base64wide private
Common condition examples
# at least N strings
condition:
2 of ($api*)
# all strings in a set
condition:
all of ($ps*)
# filesize + section checks
condition:
filesize < 500KB and $mz at 0
# suspicious PE imports
condition:
pe.is_pe and
3 of ("VirtualAlloc","WriteProcessMemory","CreateRemoteThread")
# offset / count logic
condition:
#url > 3 and @mz[1] == 0
Modules worth knowing
import "pe"
import "hash"
import "math"
import "dotnet"
import "elf"
# examples
pe.machine == pe.MACHINE_AMD64
pe.number_of_sections > 6
math.entropy(0, filesize) > 7.2
hash.md5(0, filesize) == "..."
Scanning with yara / yara64
yara rules.yar sample.bin
yara -r rules/ samples/
yara -s rules.yar sample.bin # print matching strings
yara -m rules.yar sample.bin # print meta
yara -n rules.yar sample.bin # fast mode
yarac rules.yar compiled.yarc
yara compiled.yarc sample.bin
# scan memory dumps carefully; pre-filter first
Rule debugging
yara -s rule.yar sample.bin
yara -D rule.yar sample.bin # warnings / rule diagnostics
# develop iteratively
1. start with one reliable string
2. verify on positive sample
3. test against benign files
4. add thresholds, sizes, pe checks
5. remove noisy generic strings
Quick suspicious packer / loader rule ideas
rule loader_combo
{
strings:
$s1 = "VirtualAlloc" ascii wide
$s2 = "WriteProcessMemory" ascii wide
$s3 = "CreateRemoteThread" ascii wide
$s4 = "powershell -enc" ascii nocase
condition:
pe.is_pe and 2 of ($s1,$s2,$s3) or $s4
}
Useful external helpers
strings -a sample.bin | grep -Ei "http|powershell|cmd.exe|rundll32|regsvr32"
peframe sample.exe
lief / rabin2 / objdump for imports + sections
ssdeep / tlsh for similarity clustering
Wide strings matter
Windows malware often stores strings in UTF-16LE. Add wide.
Do not overfit one sample
A rule built from one hash/string may miss variants or explode with false positives.
Generic APIs are noisy
VirtualAlloc alone is weak. Combine with imports, sizes, or additional strings.