Despite the availability of newer alternatives like Sliver, Brute Ratel, and Havoc, Cobalt Strike Beacon remains the most frequently observed post-exploitation framework in incident response investigations. It appears in nation-state campaigns, ransomware pre-deployment intrusions, and targeted attacks against every major vertical. The reason is straightforward: it works well, is well-understood by operators, and despite years of detections being published, operators continue to use default configurations that produce known signatures.

This guide covers the four principal detection surfaces: staging and delivery, network-level C2 patterns, named pipe artifacts, and memory indicators. Each section includes deployable Sigma rules and KQL for Microsoft Sentinel/Defender.

Understanding Cobalt Strike’s Staging Model

Cobalt Strike operates in two modes: staged and stageless. In staged delivery, a small loader (typically 4KB) is delivered first and contacts a staging server to retrieve the full Beacon payload. In stageless delivery, the full Beacon is embedded in the initial payload.

The staging URI pattern defaults to a four-byte token followed by a path: /<random>.<extension>. When a Beacon uses DNS staging, it queries <4-char-hex>.stager.<team-server-domain> for the full payload. These patterns, while configurable, appear frequently in operator deployments that reuse default profiles.

Network-Level Detection

Default TLS Certificate

Cobalt Strike’s default HTTPS listener uses a self-signed certificate with predictable attributes. The default certificate has:

  • Subject: CN=*.example.com, OU=IT, O=Corporation, L=Springfield, ST=Illinois, C=US
  • SHA-1 fingerprint: 6ECE5ECE4192683D2D84E25B0BA7E04F9CB7EB7C

While most operational deployments use custom certificates, this default appears routinely in automated scans and lower- sophistication campaigns.

JA3/JA3S Fingerprints

Cobalt Strike’s default HTTPS Beacon produces a consistent JA3S server fingerprint when using its built-in TLS implementation:

JA3S: ae4edc6faf64d08308082ad26be60767

This fingerprint appears in network telemetry for Beacon C2 communications that haven’t been modified to use a custom malleable profile. Network sensors running JA3 (Zeek, Suricata) should alert on this hash.

HTTP Beacon Patterns

Default malleable C2 profiles use predictable URI patterns and HTTP headers. The most common defaults:

  • GET /ca — default staging URI prefix in older Cobalt Strike versions
  • GET /j.ad — default jquery profile URI
  • User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko — IE11 on Windows 7 (common Cobalt Strike default)

KQL — Detecting Default Cobalt Strike User-Agents:

DeviceNetworkEvents
| where RemoteUrl matches regex @"/(ca|pixel\.gif|j\.ad|jquery-[0-9]+\.min\.js)$"
| where InitiatingProcessCommandLine contains "svchost" 
    or InitiatingProcessCommandLine contains "rundll32"
    or InitiatingProcessCommandLine contains "regsvr32"
| project Timestamp, DeviceName, RemoteIP, RemoteUrl, InitiatingProcessCommandLine, InitiatingProcessParentFileName

Beaconing Regularity Detection

Cobalt Strike’s default sleep time is 60 seconds with a 10% jitter. This produces network connections at approximately 54–66 second intervals. Detecting this regularity at scale requires statistical analysis:

KQL — Detecting Regular Beacon Intervals:

let beacon_interval = 60s;
let jitter_pct = 0.15;
DeviceNetworkEvents
| where ActionType == "NetworkSignatureInspected"
| summarize 
    connection_times = make_list(Timestamp),
    count = count()
    by DeviceName, RemoteIP
| where count > 20
| mv-expand connection_times to typeof(datetime)
| sort by DeviceName, RemoteIP, connection_times asc
| extend prev_time = prev(connection_times, 1)
| extend gap_seconds = datetime_diff('second', connection_times, prev_time)
| summarize 
    avg_gap = avg(gap_seconds),
    stdev_gap = stdev(gap_seconds),
    count = count()
    by DeviceName, RemoteIP
| where avg_gap between (50 .. 70)
| where stdev_gap < 10
| where count > 10

Named Pipe Detection

Cobalt Strike uses named pipes for inter-process communication during lateral movement (SMB Beacon) and for injection staging. Default pipe names include:

PatternContext
MSSE-{4-hex-chars}-serverDefault SMB Beacon pipe
msagent_{4-hex-chars}Post-exploitation injection pipe
postex_{hex}Post-exploitation module execution
status_*Internal Beacon status pipes

Sigma — Cobalt Strike Default Named Pipe Creation:

title: Cobalt Strike Default Named Pipe Creation
id: 4f7c3c4d-b5e1-4a3d-8c2f-1b7e9d5a6c0f
status: production
description: Detects creation of named pipes matching Cobalt Strike default patterns for SMB Beacon and post-exploitation modules
references:
  - https://attack.mitre.org/techniques/T1572/
logsource:
  product: windows
  category: pipe_created
detection:
  selection_msse:
    PipeName|re: '\\MSSE-[0-9a-f]{4}-server'
  selection_msagent:
    PipeName|re: '\\msagent_[0-9a-f]{1,8}'
  selection_postex:
    PipeName|re: '\\postex_[0-9a-f]{1,8}'
  condition: 1 of selection_*
falsepositives:
  - None known for MSSE pattern; msagent may have low-rate FPs from legitimate apps
level: high
tags:
  - attack.lateral_movement
  - attack.t1572
  - attack.t1021.002

KQL — Named Pipe Detection:

DeviceEvents
| where ActionType == "NamedPipeEvent"
| where AdditionalFields has "PipeCreated"
| extend PipeName = tostring(parse_json(AdditionalFields).PipeName)
| where PipeName matches regex @"\\\\MSSE-[0-9a-f]{4}-server"
    or PipeName matches regex @"\\\\msagent_[0-9a-f]+"
    or PipeName matches regex @"\\\\postex_[0-9a-f]+"
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, PipeName

Process Injection Indicators

Cobalt Strike’s default injection technique is Reflective DLL Injection via CreateRemoteThread into svchost.exe or another common process. More recently, it uses NtQueueApcThread and NtCreateThreadEx for OPSEC-improved variants.

Key injection patterns:

  • CreateRemoteThread where the target process is svchost.exe, explorer.exe, or notepad.exe
  • Spawning of rundll32.exe or regsvr32.exe with no module path arguments (fileless staging)
  • msiexec.exe /q /i http:// for live-off-the-land staging

Sigma — Suspicious CreateRemoteThread into Common Processes:

title: Cobalt Strike Process Injection into Common System Processes
id: 2e8c1d5a-9f7b-4c3e-a6d2-5b1e8f9c3a7d
status: production
description: Detects CreateRemoteThread calls from unusual parent processes into common Windows system processes, a key Cobalt Strike injection indicator
references:
  - https://attack.mitre.org/techniques/T1055/001/
logsource:
  product: windows
  category: create_remote_thread
detection:
  selection_targets:
    TargetImage|endswith:
      - '\svchost.exe'
      - '\explorer.exe'
      - '\notepad.exe'
      - '\dllhost.exe'
      - '\SearchIndexer.exe'
  filter_legitimate:
    SourceImage|startswith:
      - 'C:\Windows\System32\'
      - 'C:\Windows\SysWOW64\'
    SourceImage|endswith:
      - '\werfault.exe'
      - '\audiodg.exe'
  condition: selection_targets and not filter_legitimate
falsepositives:
  - Security tooling, AV software running in-process
level: high
tags:
  - attack.defense_evasion
  - attack.t1055.001

Memory-Based Detection

Cobalt Strike Beacon running in memory produces detectable artifacts:

  1. MZ/PE header in non-module memory regions — Reflective DLL injection leaves the Beacon DLL in memory without registering it with the Windows loader, so the MZ header appears in a process’s heap or anonymous memory region

  2. Sleep masking evasion artifacts — Modern Beacon versions use sleep masking (encrypting memory while sleeping), but the decryption stub itself remains visible as a RWX memory page in the hosting process

  3. Default Beacon configuration blob — The XOR-encoded configuration block has a predictable structure. YARA rules targeting this structure detect Beacon in both process memory and filesystem dumps

Sigma — RWX Memory Allocation in Remote Process (Injection Precursor):

title: Remote Process RWX Memory Allocation - Cobalt Strike Injection Pattern
id: 7d3b9e2c-4f1a-5c8d-b6e3-2a9f7c1d5e8b
status: experimental
description: Detects VirtualAllocEx calls with PAGE_EXECUTE_READWRITE from non-standard processes, associated with Cobalt Strike staging
logsource:
  product: windows
  category: process_access
detection:
  selection:
    CallTrace|contains: 'VirtualAllocEx'
    GrantedAccess: '0x1fffff'
    TargetImage|endswith:
      - '\svchost.exe'
      - '\explorer.exe'
      - '\RuntimeBroker.exe'
  filter_security_tools:
    SourceImage|contains:
      - 'CrowdStrike'
      - 'SentinelOne'
      - 'CarbonBlack'
      - 'Defender'
  condition: selection and not filter_security_tools
falsepositives:
  - Legitimate security tooling; verify SourceImage carefully
level: medium
tags:
  - attack.defense_evasion
  - attack.t1055

YARA for Beacon Detection in Memory and Disk

rule CobaltStrike_Beacon_Config_Blob {
    meta:
        description = "Detects Cobalt Strike Beacon configuration blob via XOR key pattern"
        author = "SOC Analyst Hub"
        reference = "https://github.com/Sentinel-One/CobaltStrikeParser"
        tlp = "WHITE"
    strings:
        $config_xor_key = { 69 68 68 6B }
        $beacon_marker = { FC 48 83 E4 F0 }
        $sleep_mask_stub = { 48 89 4C 24 ?? 48 89 54 24 ?? 48 89 74 24 }
    condition:
        any of them
}

Detection Prioritisation

Not all Cobalt Strike detections are equal. In priority order:

  1. Named pipe MSSE pattern — near-zero false positives, high confidence
  2. JA3S fingerprint match — very high confidence when correlated with unusual outbound TLS
  3. Regular beacon intervals to external IPs — requires baselining but high value
  4. CreateRemoteThread into system processes — moderate FP rate; filter on source process
  5. HTTP staging URIs — low value against custom profiles; useful for mass campaigns

The named pipe and JA3S detections should be immediate-escalation rules. Beaconing interval detection is better suited to a detection backlog hunting task run on a schedule.

Cobalt Strike’s underlying license leak in 2020 made cracked versions widely available to threat actors who could not previously afford the commercial product. This significantly increased the volume of Cobalt Strike usage by lower-sophistication actors, who are more likely to retain default configurations and therefore produce signatures. Higher-sophistication actors (APT-attributed campaigns) typically use hardened, custom-profile deployments where network signatures are less reliable and endpoint/memory detections become more important.