Cobalt Strike remains one of the most prevalent post-exploitation frameworks used by both red teams and threat actors. Detecting its beacons through YARA rules is a fundamental skill for any SOC analyst or threat hunter.
Understanding beacon artifacts
Cobalt Strike beacons leave identifiable patterns in both their staged and stageless payloads. The key areas to target are:
- Configuration blocks — the beacon stores its config in a predictable structure
- Sleep mask routines — the obfuscation applied during sleep cycles
- Named pipe patterns — default pipe names are a common indicator
A basic detection rule
rule CobaltStrike_Beacon_Config
{
meta:
description = "Detects Cobalt Strike beacon configuration block"
author = "SOC Team"
date = "2026-03"
severity = "high"
strings:
$config_header = { 00 01 00 01 00 02 ?? ?? 00 02 00 01 00 02 ?? ?? }
$default_pipe = "\\\\.\\pipe\\msagent_" ascii wide
$watermark = { 00 09 00 02 00 04 }
condition:
uint16(0) == 0x5A4D and
filesize < 1MB and
($config_header or $default_pipe) and
$watermark
}
Hunting in memory
For in-memory detection, you’ll want rules that match against the decrypted beacon configuration. Use a tool like pe-sieve or BeaconEye to dump process memory first, then scan:
yara -r cobalt_strike_rules.yar /tmp/memory_dumps/
Reducing false positives
The biggest challenge with Cobalt Strike YARA rules is balancing detection coverage against false positives. A few strategies:
- Combine multiple indicators — require at least 2-3 strings to match
- Scope with PE header checks —
uint16(0) == 0x5A4Deliminates non-PE files - Use file size constraints — beacons are typically under 500KB
- Test against known-good corpora — run your rules against a clean Windows install
Automating rule deployment
In a SOC environment, you’ll want these rules deployed across multiple detection points:
import yara
import os
RULES_DIR = "/opt/yara-rules/cobalt-strike/"
def compile_rules():
rule_files = {}
for f in os.listdir(RULES_DIR):
if f.endswith(".yar"):
rule_files[f] = os.path.join(RULES_DIR, f)
return yara.compile(filepaths=rule_files)
rules = compile_rules()
matches = rules.match("/path/to/suspicious/binary.exe")
for match in matches:
print(f"[!] {match.rule}: {match.strings}")
Further reading
The Elastic Security team maintains an excellent public repository of YARA rules. For Cobalt Strike specifically, check SentinelOne’s CobaltStrikeParser for extracting and analyzing beacon configurations programmatically.
