From Analysis to Defence
After analysing a malware sample, the analyst produces defensive signatures that security tools can deploy immediately. Two signature types cover the two detection domains:
- YARA rules: match file content on disk or in memory at the endpoint
- Snort/Suricata rules: match network traffic at the sensor
Together they provide defence in depth: YARA stops the file if it reaches a host, Snort/Suricata blocks the C2 communication at the network perimeter.
YARA Rules
YARA is a pattern-matching tool for files and memory. A YARA rule has three sections: metadata, strings, and condition.
Rule structure
rule Detect_Dropper_C2 {
meta:
description = "Detects dropper with hardcoded C2"
author = "Ashish Revar"
date = "2026-05-12"
hash = "abc123..."
strings:
$mz = { 4D 5A } // PE magic bytes
$cmd = "cmd.exe /c" ascii nocase
$url = "http://evil.com/gate.php" wide ascii
$ua = "Mozilla/5.0 (compatible)" ascii
$mutex = "Global\\MicrosoftUpdateService3"
condition:
$mz at 0 and 2 of ($cmd, $url, $ua, $mutex)
}
String types and modifiers
| Type | Syntax | What It Matches |
|---|---|---|
| Plain string | $s = "cmd.exe" | Exact byte sequence |
ascii | $s = "cmd.exe" ascii | ASCII encoding (default) |
wide | $s = "cmd.exe" wide | UTF-16LE encoding (Windows Unicode) |
nocase | $s = "cmd.exe" nocase | Case-insensitive |
fullword | $s = "cmd" fullword | Only standalone word: not "cmdline" |
| Hex bytes | $s = { 4D 5A ?? 00 } | Byte pattern with ?? wildcards |
| Hex with jumps | $s = { 4D 5A [2-4] 50 45 } | Variable-length gap between bytes |
| Regex | $s = /https?:\/\/[0-9.]{7,15}\/gate/ nocase | Regular expression |
Condition logic
condition:
$mz at 0 // PE file (MZ at offset 0)
and filesize < 500KB // reasonable size
and 2 of ($cmd, $url, $ua) // at least 2 of 3 IOC strings
and not $mutex // exclude known false positive
Operators: and, or, not, all of, any of, N of, at, in
Writing effective YARA rules
Good rule: specific enough to avoid false positives, broad enough to catch variants
// Too specific — fails if one byte changes
$url = "http://185.220.101.47/gate.php"
// Better — matches the gate endpoint pattern across IP variants
$url = /https?:\/\/[0-9.]{7,15}\/gate\.php/
// Too broad — matches almost any Windows binary
$cmd = "cmd.exe"
// Better — matches the specific abuse pattern
$cmd = "cmd.exe /c vssadmin delete shadows" nocase
Testing YARA rules
# Test against a single file
yara rule.yar suspicious.exe
# Test recursively against a directory
yara -r rule.yar malware_samples/
# Verify no false positives against clean files
yara rule.yar C:\Windows\System32\notepad.exe
# Should produce NO output
# Scan memory of a running process
yara -p 3412 rule.yar
Snort / Suricata Rules
Snort and Suricata inspect network traffic in real time, alerting when C2 patterns cross the sensor.
Rule structure
action proto src_ip src_port direction dst_ip dst_port (options)
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (
msg:"Malware C2 beacon — custom User-Agent";
flow:established,to_server;
content:"User-Agent: Mozilla/5.0 (compatible)";
content:"POST /gate.php";
sid:1000042;
rev:1;
)
Key options
| Option | Purpose | Example |
|---|---|---|
flow | Connection direction and state | flow:established,to_server |
content | Exact byte match | content:"POST /gate.php" |
pcre | Perl-compatible regex | pcre:"/gate\.php\?id=[A-F0-9]{16}/i" |
nocase | Case-insensitive match | content:"user-agent"; nocase |
distance | Next content N bytes after previous | distance:0 |
within | Next content within N bytes of previous | within:50 |
dsize | Match on packet data size | dsize:>100 |
threshold | Alert rate limiting | threshold:type limit, track by_src, count 1, seconds 60 |
Example: DGA domain detection
alert udp $HOME_NET any -> any 53 (
msg:"Possible DGA domain query — high entropy hostname";
content:"|01 00 00 01 00 00 00 00 00 00|";
pcre:"/[a-z]{12,20}\.(com|net|org|info)\x00/i";
sid:1000043;
rev:1;
)
flow:established,to_server explained
established: TCP three-way handshake completedto_server: traffic flowing from client to server (outbound from$HOME_NET)
This combination matches only genuine C2 POST requests: not SYN packets, not server responses.
Defence in Depth: Combining Both
Network perimeter:
Snort/Suricata rule → blocks C2 communication
→ Catches malware that reached the host but fires its beacon
Endpoint:
YARA rule → detects the file on disk or in memory
→ Catches malware before or during execution
Together:
If YARA misses a new variant → Snort catches the beacon
If Snort misses encrypted C2 → YARA catches the file
YARA Rule Sources
| Source | URL | Content |
|---|---|---|
| YARA-Rules project | github.com/Yara-Rules/rules | Community rules for major families |
| Mandiant/FireEye | github.com/mandiant/red_team_tool_countermeasures | Rules for APT tools |
| Neo23x0 (Florian Roth) | github.com/Neo23x0/signature-base | High-quality community rules |
| CAPE output | Local CAPE instance | Auto-generated rules from extracted configs |
Always test community rules against a clean file corpus before deployment: false positive rates vary significantly.

