T1573

Encrypted Channel

Command and Control Last updated:

This detection identifies adversaries using custom or non-standard encryption to conceal command and control (C2) traffic. Unlike legitimate TLS/HTTPS, malware implementing encrypted channels often exhibits behavioral anomalies: unusual processes making encrypted connections, connections to raw IP addresses without SNI, self-signed or short-lived certificates, high-frequency beaconing intervals, non-browser processes using port 443/8443 with atypical TLS fingerprints (JA3), and data volumes inconsistent with the application type. This detection correlates process lineage, network destinations, certificate characteristics, and traffic timing to surface encrypted C2 channels used by threat actors such as Tropic Trooper, Lazarus Group, and malware families including RCSession, Cryptoistic, Gomir, and Chaes.

What is T1573 Encrypted Channel?

Encrypted Channel (T1573) maps to the Command and Control tactic — the adversary is trying to communicate with compromised systems to control them in MITRE ATT&CK.

This page provides production-ready detection logic for Encrypted Channel, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Command and Control
Technique
T1573 Encrypted Channel
Canonical reference
https://attack.mitre.org/techniques/T1573/
Microsoft Sentinel / Defender
kusto
let SuspiciousParentProcesses = dynamic(["cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe", "mshta.exe", "regsvr32.exe", "rundll32.exe", "svchost.exe", "explorer.exe"]);
let LegitimateEncryptedApps = dynamic(["chrome.exe", "firefox.exe", "msedge.exe", "iexplore.exe", "outlook.exe", "teams.exe", "onedrive.exe", "slack.exe", "zoom.exe", "msiexec.exe", "wuauclt.exe", "svchost.exe"]);
let EncryptedPorts = dynamic([443, 8443, 8080, 4443, 9443, 3443, 7443]);
// Step 1: Identify network connections from suspicious or non-browser processes on encrypted ports
let SuspiciousEncryptedConnections = DeviceNetworkEvents
| where TimeGenerated >= ago(24h)
| where ActionType == "ConnectionSuccess"
| where RemotePort in (EncryptedPorts)
| where not(InitiatingProcessFileName has_any (LegitimateEncryptedApps))
| where isnotempty(RemoteIP)
// Exclude private/loopback IP ranges
| where not(RemoteIP matches regex @"^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.|::1|fc00:|fe80:)")
| extend IsIPOnlyConnection = (isempty(RemoteUrl) or RemoteUrl == RemoteIP or RemoteUrl matches regex @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
| extend SuspiciousParent = (InitiatingProcessParentFileName has_any (SuspiciousParentProcesses))
| project
    TimeGenerated,
    DeviceName,
    DeviceId,
    InitiatingProcessFileName,
    InitiatingProcessCommandLine,
    InitiatingProcessParentFileName,
    InitiatingProcessAccountName,
    InitiatingProcessId,
    RemoteIP,
    RemotePort,
    RemoteUrl,
    IsIPOnlyConnection,
    SuspiciousParent,
    BytesSent,
    BytesReceived;
// Step 2: Detect beaconing behavior — repeated encrypted connections at regular intervals
let BeaconingDetection = DeviceNetworkEvents
| where TimeGenerated >= ago(24h)
| where ActionType == "ConnectionSuccess"
| where RemotePort in (EncryptedPorts)
| where not(InitiatingProcessFileName has_any (LegitimateEncryptedApps))
| where not(RemoteIP matches regex @"^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)")
| summarize
    ConnectionCount = count(),
    UniqueRemoteIPs = dcount(RemoteIP),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated),
    AvgBytesSent = avg(BytesSent),
    AvgBytesReceived = avg(BytesReceived),
    ConnectionTimes = make_list(TimeGenerated, 50)
    by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemotePort
| where ConnectionCount >= 5
| where UniqueRemoteIPs == 1
| extend DurationMinutes = datetime_diff('minute', LastSeen, FirstSeen)
| extend AvgIntervalMinutes = iff(ConnectionCount > 1, toreal(DurationMinutes) / toreal(ConnectionCount - 1), 0.0)
// Flag regular beaconing: 5+ connections with consistent intervals (1-60 min)
| where AvgIntervalMinutes between (1.0 .. 60.0)
| extend BeaconScore = case(
    AvgIntervalMinutes < 5, "High - Sub-5min beaconing",
    AvgIntervalMinutes < 15, "Medium - Regular beaconing",
    "Low - Periodic connection"
);
// Combine results
SuspiciousEncryptedConnections
| join kind=leftouter (
    BeaconingDetection
    | project DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort, ConnectionCount, AvgIntervalMinutes, BeaconScore
) on DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort
| extend RiskScore = case(
    IsIPOnlyConnection == true and SuspiciousParent == true, "Critical",
    IsIPOnlyConnection == true or (isnotempty(BeaconScore) and BeaconScore startswith "High"), "High",
    SuspiciousParent == true or isnotempty(BeaconScore), "Medium",
    "Low"
)
| where RiskScore in ("Critical", "High", "Medium")
| project
    TimeGenerated,
    DeviceName,
    RiskScore,
    InitiatingProcessFileName,
    InitiatingProcessCommandLine,
    InitiatingProcessParentFileName,
    InitiatingProcessAccountName,
    RemoteIP,
    RemotePort,
    RemoteUrl,
    IsIPOnlyConnection,
    BeaconScore,
    ConnectionCount,
    AvgIntervalMinutes,
    BytesSent,
    BytesReceived
| sort by RiskScore asc, TimeGenerated desc

Detects encrypted C2 channels by identifying non-browser processes making encrypted connections (ports 443, 8443, etc.) to external IPs, particularly connections to raw IP addresses without hostname resolution (SNI omission), and beaconing behavior with regular connection intervals. Assigns risk scores based on parent process suspicion, IP-only destinations, and regularity of connections.

high severity medium confidence

Data Sources

Microsoft Defender for Endpoint

Required Tables

DeviceNetworkEvents

False Positives

  • Custom internal applications or agents that connect to known infrastructure over HTTPS but are not in the allowlist (add to LegitimateEncryptedApps)
  • IT monitoring and management tools (SCCM, Ansible, Puppet) that make frequent scheduled encrypted connections to management infrastructure
  • Security products (EDR agents, vulnerability scanners, DLP solutions) that beacon home over encrypted channels on non-standard ports
  • Cloud sync clients or backup agents connecting to cloud storage endpoints on port 443 at regular intervals
  • VPN clients and network tunneling software that establish persistent encrypted connections as part of normal operation

Sigma rule & cross-platform mapping

The detection logic for Encrypted Channel (T1573) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: network_connection
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Simulate Custom Encrypted C2 Beacon Using PowerShell SSL

    Expected signal: Sysmon Event ID 3 (NetworkConnect) with Image=powershell.exe, DestinationPort=443, DestinationHostname=ifconfig.me; Sysmon Event ID 1 showing PowerShell execution with -ExecutionPolicy Bypass flag; DeviceNetworkEvents showing 5 connections at ~30 second intervals (low jitter beaconing pattern)

  2. Test 2Simulate C2 Connection to Raw IP Address Over HTTPS

    Expected signal: Sysmon Event ID 3 with Image=powershell.exe, DestinationIp=1.1.1.1, DestinationPort=443, DestinationHostname empty or equal to the IP address; DeviceNetworkEvents showing IsIPOnlyConnection=true with RemoteUrl matching RemoteIP

  3. Test 3Simulate Encrypted C2 Beacon from LOLBin (mshta.exe)

    Expected signal: Sysmon Event ID 1 showing mshta.exe execution with HTA file path argument; Sysmon Event ID 3 with Image=mshta.exe, DestinationPort=443, DestinationHostname=httpbin.org; DeviceProcessEvents and DeviceNetworkEvents correlation showing mshta.exe as initiating process

  4. Test 4Linux Custom Encrypted Beacon Simulation Using OpenSSL

    Expected signal: Auditd SYSCALL records for connect() calls from openssl process; syslog entries showing openssl process network activity; on hosts with Sysmon for Linux, Event ID 3 showing openssl making TLS connections to external IP on port 443 at ~30 second intervals


Response Playbook

Triage

  1. Step 1: Identify the initiating process — retrieve the full process tree (parent → child → grandchild) for the alerting process using DeviceProcessEvents or Sysmon Event ID 1. Determine if the process is a known legitimate application or exhibits LOLBin behavior.
  2. Step 2: Examine the destination — query the remote IP against threat intelligence sources (VirusTotal, Shodan, AbuseIPDB). Check if the IP is a known cloud provider, CDN, or malicious infrastructure. Look up WHOIS/ASN data to determine hosting provider and registration age.
  3. Step 3: Analyze the connection pattern — retrieve all connections from this process/host to the same destination over the past 7 days. Calculate average interval between connections. Intervals of 30s, 60s, 5m, 15m, or 30m are strong beaconing indicators.
  4. Step 4: Examine TLS certificate details — if available in network logs or proxy logs, extract the certificate CN, issuer, validity period, and SANs. Self-signed certs, certificates valid for <30 days or >5 years, or certificates with generic CNs (e.g., 'localhost', IP addresses) are red flags.
  5. Step 5: Review data transfer volumes — compare BytesSent vs BytesReceived ratios. C2 channels often show small outbound (heartbeat/check-in) with occasional larger inbound (command/payload). Consistent near-equal bidirectional traffic may indicate tunneled sessions.
  6. Step 6: Check process command line and loaded modules — examine the initiating process command line for encoded arguments, suspicious flags, or unusual paths. Query DeviceImageLoadEvents for DLLs loaded by the process, particularly custom crypto libraries.
  7. Step 7: Correlate with other suspicious activity on the host — search for related indicators: recent file drops (DeviceFileEvents), registry modifications (DeviceRegistryEvents), privilege escalation (SecurityEvent 4672), or lateral movement events within 24h of the encrypted channel activity.

Containment

  1. If confirmed malicious: Isolate the endpoint using EDR/MDM isolation to prevent further C2 communication while preserving the system for forensic analysis.
  2. Block the remote IP and any associated domains at the perimeter firewall, web proxy, and DNS sinkholes. Apply the block to all network segments, not just the affected host.
  3. Terminate the suspicious process and any child processes. Document all PIDs before termination for evidence collection.
  4. If a user account was used to execute the suspicious process, disable or reset the account credentials immediately. Check for OAuth tokens or API keys associated with the account that may need rotation.
  5. Search for the same process binary or network destination across the entire environment using EDR fleet queries to identify additional compromised hosts.
  6. If the process was running as a service or scheduled task, disable the persistence mechanism to prevent re-establishment after containment.

Evidence Collection

  1. Export the complete process tree and command line arguments from EDR for the alerting process and all ancestors.
  2. Capture a full memory dump of the suspicious process before termination if forensics team requires it — memory often contains decrypted C2 traffic, keys, and configuration.
  3. Collect the suspicious binary from disk: calculate SHA256 hash, extract PE metadata, and submit to sandboxes (Any.run, Cuckoo) for behavioral analysis and key extraction.
  4. Export all network connection logs (DeviceNetworkEvents, proxy logs, firewall logs, DNS query logs) for the affected host for the past 7-30 days to establish C2 timeline.
  5. Collect Sysmon operational logs (Event ID 1, 3, 7, 8, 10, 11, 12, 13) from the endpoint for the period of compromise.
  6. Capture packet captures (PCAP) from network monitoring infrastructure if available — even encrypted traffic metadata (timing, size, directionality) aids in identifying the C2 protocol and infrastructure.
  7. Export Windows Prefetch files (C:\Windows\Prefetch\) to establish execution history and frequency of the suspicious binary.
  8. Collect scheduled tasks (schtasks /query /fo LIST /v), services (sc query), and autorun registry keys to identify persistence mechanisms.

Escalation Criteria

  • ! Escalate immediately if the suspicious process has established connections to more than one external IP, indicating active C2 infrastructure rotation or multi-stage payload delivery.
  • ! Escalate if the encrypted channel is running under a SYSTEM, service account, or privileged user context — this indicates post-exploitation activity with elevated access.
  • ! Escalate if lateral movement indicators are present (successful remote logins, PsExec/WMI activity, SMB connections) within the same timeframe as the encrypted channel activity.
  • ! Escalate if the beaconing host is a server (domain controller, file server, build system, database server) rather than a workstation — server compromise has higher blast radius.
  • ! Escalate if memory analysis or sandbox detonation reveals the binary performs decryption of embedded payloads, suggesting staged malware with encrypted secondary C2.
  • ! Escalate if multiple hosts in the same subnet show the same pattern within a short window — this may indicate a worm or automated lateral movement component.
  • ! Escalate if the investigation reveals exfiltration indicators: large outbound transfers (BytesSent > 10MB) to the C2 IP, or connections timing after access to sensitive data repositories.

Investigation Guide

Forensic Artifacts

  • > Process memory dump: decrypted C2 traffic buffers, encryption keys, hardcoded C2 IP/domains, and configuration data
  • > Network PCAP: TLS handshake metadata (JA3/JA3S fingerprints, cipher suites, SNI values, certificate chain)
  • > Windows Prefetch: C:\Windows\Prefetch\<processname>-*.pf — confirms execution frequency and loaded DLLs
  • > DNS cache: ipconfig /displaydns — may show resolved domains associated with C2 even after process termination
  • > Windows Event Log: Security (4688 process creation if audit enabled), Sysmon operational log
  • > Scheduled tasks and services: C:\Windows\System32\Tasks\, HKLM\SYSTEM\CurrentControlSet\Services\
  • > Browser history and extensions: malware may abuse browser processes for encrypted channel cover
  • > Binary on disk: PE headers, embedded resources, import table (CryptEncrypt, WSAStartup, SSL APIs), packed sections
  • > Linux: /proc/<pid>/net/tcp6 for active encrypted connections, /proc/<pid>/maps for loaded libraries, auditd logs

Tuning Guidance

Start by building an allowlist of legitimate processes in your environment that routinely make encrypted connections (update agents, monitoring tools, backup clients). Add these to the LegitimateEncryptedApps list in both KQL and SPL queries. For beaconing detection, adjust the minimum ConnectionCount threshold (default: 5) and interval window based on observed false positives — backup tools and monitoring agents may check in every 5-15 minutes legitimately. For the IP-only connection check, some CDNs and cloud services return connections to IP addresses without SNI — maintain a known-safe IP allowlist. Consider deploying SSL/TLS inspection at your perimeter to enable JA3 fingerprint analysis, which dramatically improves detection accuracy for custom crypto implementations. In environments with Defender for Endpoint P2, leverage the built-in network inspection capabilities which provide additional certificate metadata not available in standard DeviceNetworkEvents. The low-jitter beaconing hunt (StdDev < 10%) is highly specific — most legitimate software has much more variance in connection timing.


Hunting Queries

Hunts for low-prevalence processes (seen on 5 or fewer endpoints globally) making encrypted connections — indicative of custom malware or implants vs. widely deployed legitimate software.

Hunting — KQL
kql
// Hunt for JA3 fingerprint anomalies — processes with rare TLS fingerprints
// Requires network proxy/SSL inspection data in CommonSecurityLog or custom table
DeviceNetworkEvents
| where TimeGenerated >= ago(7d)
| where ActionType == "ConnectionSuccess"
| where RemotePort in (443, 8443, 4443)
| where not(RemoteIP matches regex @"^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)")
| summarize
    TotalConnections = count(),
    UniqueDestinations = dcount(RemoteIP),
    Hosts = make_set(DeviceName, 20),
    SampleCommandLines = make_set(InitiatingProcessCommandLine, 5)
    by InitiatingProcessFileName, InitiatingProcessSHA256
| where TotalConnections < 10 and UniqueDestinations <= 3
// Low-prevalence encrypted channels — rare processes making few encrypted connections
| join kind=leftouter (
    DeviceNetworkEvents
    | where TimeGenerated >= ago(7d)
    | summarize GlobalPrevalence = dcount(DeviceId) by InitiatingProcessSHA256
) on InitiatingProcessSHA256
| where GlobalPrevalence <= 5
| project InitiatingProcessFileName, InitiatingProcessSHA256, TotalConnections, UniqueDestinations, GlobalPrevalence, Hosts, SampleCommandLines
| sort by GlobalPrevalence asc
Hunting — SPL
spl
index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
| where RemotePort IN ("443", "8443", "4443", "8080")
| where NOT match(DestinationIp, "^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\.168\\.|127\\.)")
| eval ProcessName=lower(mvindex(split(Image, "\\"), -1))
| stats
    dc(host) AS HostCount,
    dc(DestinationIp) AS UniqueIPs,
    count AS TotalConns,
    values(host) AS AffectedHosts
    by ProcessName, Hashes
| where HostCount <= 3 AND TotalConns >= 5
| sort HostCount

Hunts for high-regularity beaconing with low jitter (standard deviation < 10% of average interval). Legitimate software typically has variable connection intervals; malware beacons often use simple sleep timers with very consistent timing.

Hunting — KQL
kql
// Hunt for encrypted beaconing with high regularity (low jitter)
// Adversaries often implement timers with little randomness
DeviceNetworkEvents
| where TimeGenerated >= ago(3d)
| where ActionType == "ConnectionSuccess"
| where RemotePort in (443, 8443, 4443, 8080, 9443)
| where not(RemoteIP matches regex @"^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)")
| where not(InitiatingProcessFileName has_any ("chrome.exe", "firefox.exe", "msedge.exe", "outlook.exe", "teams.exe", "onedrive.exe"))
| sort by DeviceName, InitiatingProcessFileName, RemoteIP, TimeGenerated asc
| serialize
| extend PrevTime = prev(TimeGenerated, 1)
| extend PrevProcess = prev(InitiatingProcessFileName, 1)
| extend PrevHost = prev(DeviceName, 1)
| extend PrevIP = prev(RemoteIP, 1)
| where DeviceName == PrevHost and InitiatingProcessFileName == PrevProcess and RemoteIP == PrevIP
| extend IntervalSeconds = datetime_diff('second', TimeGenerated, PrevTime)
| where IntervalSeconds > 0
| summarize
    ConnectionCount = count(),
    AvgInterval = avg(IntervalSeconds),
    StdDevInterval = stdev(IntervalSeconds),
    MinInterval = min(IntervalSeconds),
    MaxInterval = max(IntervalSeconds)
    by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemotePort
| where ConnectionCount >= 8
// Low jitter: standard deviation less than 10% of average interval
| where StdDevInterval < (AvgInterval * 0.10)
| extend JitterPercent = round(StdDevInterval / AvgInterval * 100, 1)
| sort by JitterPercent asc
Hunting — SPL
spl
index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
| where RemotePort IN ("443", "8443", "4443", "8080")
| where NOT match(DestinationIp, "^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\.168\\.|127\\.)")
| eval ProcessName=lower(mvindex(split(Image, "\\"), -1))
| where NOT ProcessName IN ("chrome.exe", "firefox.exe", "msedge.exe", "outlook.exe", "teams.exe")
| sort host, ProcessName, DestinationIp, _time
| streamstats current=f last(_time) AS prev_time by host, ProcessName, DestinationIp
| eval interval_seconds=_time - prev_time
| where interval_seconds > 0
| stats count AS conn_count, avg(interval_seconds) AS avg_interval, stdev(interval_seconds) AS std_interval by host, ProcessName, CommandLine, DestinationIp, DestinationPort
| where conn_count >= 8
| eval jitter_pct=round(std_interval / avg_interval * 100, 1)
| where jitter_pct < 10
| sort jitter_pct

Hunts for processes that load cryptographic libraries (bcrypt, openssl, etc.) immediately before making outbound encrypted connections. This pattern identifies custom encryption implementations used by malware families like Gomir and RCSession that load crypto APIs at runtime just before C2 beaconing.

Hunting — KQL
kql
// Hunt for processes loading crypto libraries immediately before making network connections
// Custom encryption implementations often load CNG/crypto DLLs right before C2 activity
let CryptoDLLs = dynamic(["bcrypt.dll", "ncrypt.dll", "crypt32.dll", "cryptsp.dll", "rsaenh.dll", "dpapi.dll", "libssl", "openssl", "boringssl"]);
DeviceImageLoadEvents
| where TimeGenerated >= ago(24h)
| where FileName has_any (CryptoDLLs)
| where not(InitiatingProcessFileName has_any ("chrome.exe", "firefox.exe", "msedge.exe", "outlook.exe", "teams.exe", "lsass.exe", "svchost.exe", "services.exe"))
| project
    CryptoLoadTime = TimeGenerated,
    DeviceName,
    DeviceId,
    InitiatingProcessFileName,
    InitiatingProcessCommandLine,
    InitiatingProcessId,
    InitiatingProcessAccountName,
    CryptoDLL = FileName,
    CryptoSHA256 = SHA256
| join kind=inner (
    DeviceNetworkEvents
    | where TimeGenerated >= ago(24h)
    | where ActionType == "ConnectionSuccess"
    | where RemotePort in (443, 8443, 4443, 8080)
    | where not(RemoteIP matches regex @"^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)")
    | project NetworkTime = TimeGenerated, DeviceName, InitiatingProcessId, RemoteIP, RemotePort, BytesSent, BytesReceived
) on DeviceName, InitiatingProcessId
| where NetworkTime > CryptoLoadTime and NetworkTime < datetime_add('minute', 5, CryptoLoadTime)
| project CryptoLoadTime, NetworkTime, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName, CryptoDLL, RemoteIP, RemotePort, BytesSent, BytesReceived
| sort by CryptoLoadTime desc
Hunting — SPL
spl
index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=7
| eval ImageLoaded=lower(ImageLoaded)
| where match(ImageLoaded, "bcrypt\.dll|ncrypt\.dll|crypt32\.dll|cryptsp\.dll|rsaenh\.dll|libssl|openssl")
| eval ProcessName=lower(mvindex(split(Image, "\\"), -1))
| where NOT ProcessName IN ("chrome.exe", "firefox.exe", "msedge.exe", "outlook.exe", "lsass.exe", "svchost.exe")
| eval crypto_time=_time
| join type=inner ProcessId [
    search index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
    | where RemotePort IN ("443", "8443", "4443", "8080")
    | where NOT match(DestinationIp, "^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\.168\\.|127\\.)")
    | eval net_time=_time
    | table ProcessId, net_time, DestinationIp, DestinationPort, host
]
| eval time_diff=net_time - crypto_time
| where time_diff >= 0 AND time_diff <= 300
| table host, ProcessName, CommandLine, ImageLoaded, DestinationIp, DestinationPort, time_diff
| sort time_diff

Atomic Red Team Tests

Test 1 Simulate Custom Encrypted C2 Beacon Using PowerShell SSL
windows

Simulates a custom encrypted C2 channel by establishing a TLS connection from PowerShell to an external endpoint. This validates that non-browser processes making encrypted connections are detected, particularly from scripting engines that are common malware carriers.

Command

powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$url = 'https://ifconfig.me/all.json'; for ($i=0; $i -lt 5; $i++) { try { $r = Invoke-RestMethod -Uri $url -UseBasicParsing; Write-Host 'Beacon $($i+1): Connected' } catch { Write-Host 'Failed: $_' }; Start-Sleep -Seconds 30 }"

Cleanup

powershell
# No cleanup required — connections are outbound only. Kill PowerShell process if still running.
Get-Process powershell | Where-Object {$_.MainWindowTitle -eq ''} | Stop-Process -Force

Expected Telemetry

Sysmon Event ID 3 (NetworkConnect) with Image=powershell.exe, DestinationPort=443, DestinationHostname=ifconfig.me; Sysmon Event ID 1 showing PowerShell execution with -ExecutionPolicy Bypass flag; DeviceNetworkEvents showing 5 connections at ~30 second intervals (low jitter beaconing pattern)

Expected Detection

Alert fires on PowerShell making repeated encrypted connections at regular intervals; beaconing hunt query flags low-jitter pattern (5 connections, ~30s average interval, StdDev < 3s)

Test 2 Simulate C2 Connection to Raw IP Address Over HTTPS
windows

Tests detection of encrypted connections to raw IP addresses without hostname (SNI omission), which is a common indicator of custom C2 implementations that embed IP addresses directly to avoid DNS-based detection.

Command

powershell
powershell.exe -NoProfile -Command "Add-Type @'
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
public class TrustAll {
    public static bool Validate(object s, X509Certificate c, X509Chain ch, SslPolicyErrors e) { return true; }
}
'@
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = [TrustAll]::Validate
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
try { $r = (New-Object System.Net.WebClient).DownloadString('https://1.1.1.1/') } catch { }
Write-Host 'Connection attempt to raw IP complete'"

Cleanup

powershell
# No cleanup required — single connection attempt only

Expected Telemetry

Sysmon Event ID 3 with Image=powershell.exe, DestinationIp=1.1.1.1, DestinationPort=443, DestinationHostname empty or equal to the IP address; DeviceNetworkEvents showing IsIPOnlyConnection=true with RemoteUrl matching RemoteIP

Expected Detection

Alert fires with RiskScore=High or Critical due to IP-only encrypted connection from PowerShell; the IsIPOnlyConnection flag is set to true triggering elevated risk scoring

Test 3 Simulate Encrypted C2 Beacon from LOLBin (mshta.exe)
windows

Tests detection of encrypted channel established via mshta.exe (Microsoft HTML Application Host), a Living Off the Land Binary commonly abused by threat actors including Tropic Trooper to proxy C2 traffic through trusted Windows processes.

Command

powershell
# Create temporary HTA file that makes HTTPS connections
$htaContent = @'
<script language="VBScript">
Function MakeRequest()
    Dim http
    Set http = CreateObject("MSXML2.XMLHTTP")
    http.Open "GET", "https://httpbin.org/get", False
    http.Send
    MsgBox "Response: " & http.Status
End Function
MakeRequest
</script>
'@
$htaPath = "$env:TEMP\test_beacon.hta"
$htaContent | Out-File -FilePath $htaPath -Encoding ASCII
mshta.exe $htaPath

Cleanup

powershell
Remove-Item -Path "$env:TEMP\test_beacon.hta" -Force -ErrorAction SilentlyContinue

Expected Telemetry

Sysmon Event ID 1 showing mshta.exe execution with HTA file path argument; Sysmon Event ID 3 with Image=mshta.exe, DestinationPort=443, DestinationHostname=httpbin.org; DeviceProcessEvents and DeviceNetworkEvents correlation showing mshta.exe as initiating process

Expected Detection

Alert fires with RiskScore=Medium or High since mshta.exe is in the SuspiciousParentProcesses list — the process itself is the initiator; detection identifies non-browser process (mshta.exe) making encrypted connection on port 443

Test 4 Linux Custom Encrypted Beacon Simulation Using OpenSSL
linux

Simulates a custom encrypted C2 channel on Linux using OpenSSL's s_client, which bypasses certificate validation similar to how malware implements custom TLS without proper verification. Tests detection of unusual processes establishing encrypted connections.

Command

bash
# Simulate beaconing — 5 connections at 30-second intervals using openssl s_client
for i in $(seq 1 5); do
  echo 'GET / HTTP/1.0\r\n\r\n' | timeout 5 openssl s_client -connect httpbin.org:443 -quiet 2>/dev/null | head -1
  echo "Beacon $i sent at $(date)"
  sleep 30
done

Cleanup

bash
# No cleanup required — outbound connections only. Kill the loop if still running:
# kill %1

Expected Telemetry

Auditd SYSCALL records for connect() calls from openssl process; syslog entries showing openssl process network activity; on hosts with Sysmon for Linux, Event ID 3 showing openssl making TLS connections to external IP on port 443 at ~30 second intervals

Expected Detection

Beaconing hunt query flags regular interval connections from openssl s_client process; low-jitter pattern detection triggers on 5 connections with StdDev/AvgInterval ratio < 10%

Related Detections

Detection Variants (1)

Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.