T1584.004 Microsoft Sentinel · KQL

Detect Compromise Infrastructure: Server in Microsoft Sentinel

Adversaries may compromise third-party servers to stage, launch, and execute operations. Rather than purchasing dedicated infrastructure, threat actors hijack legitimate servers — including web servers, mail servers, and application servers — to host malware, serve as command-and-control nodes, support phishing campaigns, or enable watering hole attacks. Because the compromised servers are legitimately owned by third parties, traffic to and from them may blend in with normal business activity. Real-world examples include Lazarus Group staging malware on compromised servers, Volt Typhoon using compromised PRTG monitoring servers for C2, Sandworm compromising EXIM mail servers for campaign infrastructure, and Dragonfly leveraging legitimate websites to host C2 and malware modules.

MITRE ATT&CK

Tactic
Resource Development
Technique
T1584 Compromise Infrastructure
Sub-technique
T1584.004 Server
Canonical reference
https://attack.mitre.org/techniques/T1584/004/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
// T1584.004 — Compromise Infrastructure: Server
// Strategy: correlate outbound connections against threat intelligence,
// detect C2 beaconing patterns, and flag connections to known compromised server ranges.
// Requires Microsoft Sentinel with ThreatIntelligenceIndicator table populated.
let LookbackPeriod = 24h;
let BeaconMinConnections = 5;
let BeaconMinIntervalMin = 1;
let BeaconMaxIntervalMin = 120;
// Pull active TI indicators for IP-based indicators
let ThreatIntelServerIPs = ThreatIntelligenceIndicator
| where TimeGenerated > ago(30d)
| where Active == true
| where isnotempty(NetworkIP)
| where ConfidenceScore >= 50
| distinct NetworkIP, Description, ThreatType;
// Pull active TI indicators for domain-based indicators
let ThreatIntelDomains = ThreatIntelligenceIndicator
| where TimeGenerated > ago(30d)
| where Active == true
| where isnotempty(DomainName)
| where ConfidenceScore >= 50
| distinct DomainName, Description, ThreatType;
// Detection Branch 1: Direct TI IP hit on outbound connections
let TIIPHits = DeviceNetworkEvents
| where Timestamp > ago(LookbackPeriod)
| where ActionType in ("ConnectionSuccess", "ConnectionAttempt", "InboundConnectionAccepted")
| join kind=inner ThreatIntelServerIPs on $left.RemoteIP == $right.NetworkIP
| extend DetectionMethod = "ThreatIntel-IP"
| project Timestamp, DeviceName, AccountName = InitiatingProcessAccountName,
         InitiatingProcessFileName, InitiatingProcessCommandLine,
         RemoteIP, RemotePort, RemoteUrl,
         ThreatDescription = Description, ThreatType,
         DetectionMethod;
// Detection Branch 2: DNS-resolved TI domain hits
let TIDomainHits = DeviceNetworkEvents
| where Timestamp > ago(LookbackPeriod)
| where isnotempty(RemoteUrl)
| extend RequestedDomain = tostring(parse_url(RemoteUrl).Host)
| join kind=inner ThreatIntelDomains on $left.RequestedDomain == $right.DomainName
| extend DetectionMethod = "ThreatIntel-Domain"
| project Timestamp, DeviceName, AccountName = InitiatingProcessAccountName,
         InitiatingProcessFileName, InitiatingProcessCommandLine,
         RemoteIP, RemotePort, RemoteUrl,
         ThreatDescription = Description, ThreatType,
         DetectionMethod;
// Detection Branch 3: Beaconing pattern — periodic connections to same external IP
let BeaconingHosts = DeviceNetworkEvents
| where Timestamp > ago(LookbackPeriod)
| where RemoteIPType == "Public"
| where ActionType == "ConnectionSuccess"
| summarize ConnectionCount = count(),
           FirstSeen = min(Timestamp),
           LastSeen = max(Timestamp),
           Ports = make_set(RemotePort, 10)
  by DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP
| where ConnectionCount >= BeaconMinConnections
| extend SpanMinutes = datetime_diff('minute', LastSeen, FirstSeen)
| where SpanMinutes > 10
| extend AvgIntervalMinutes = toreal(SpanMinutes) / toreal(ConnectionCount - 1)
| where AvgIntervalMinutes between (BeaconMinIntervalMin .. BeaconMaxIntervalMin)
| extend DetectionMethod = "BeaconingPattern"
| project FirstSeen, LastSeen, DeviceName, AccountName = "",
         InitiatingProcessFileName, InitiatingProcessCommandLine,
         RemoteIP, RemotePort = tostring(Ports),
         RemoteUrl = "",
         ThreatDescription = strcat("Beaconing: ", tostring(ConnectionCount), " connections over ", tostring(SpanMinutes), " min, avg interval ", round(AvgIntervalMinutes, 1), " min"),
         ThreatType = "C2-Beacon",
         DetectionMethod
| project-rename Timestamp = FirstSeen;
// Union all branches
union TIIPHits, TIDomainHits, BeaconingHosts
| sort by Timestamp desc
high severity medium confidence

Three-branch detection for T1584.004 using Microsoft Sentinel. Branch 1 correlates outbound DeviceNetworkEvents against active threat intelligence IP indicators (ThreatIntelligenceIndicator table, confidence >= 50) to identify direct connections to known compromised server IPs. Branch 2 correlates network connections to threat-intelligence-listed domains by parsing the RemoteUrl field. Branch 3 implements statistical beaconing detection: groups connections by host/process/destination, calculates average inter-connection interval, and flags sessions with 5+ connections to the same public IP at 1-120 minute intervals — consistent with automated C2 check-in behavior. Requires Microsoft Sentinel TI connector (TAXII, MISP, or native integrations) to be populated.

Data Sources

Network Traffic: Network Connection CreationNetwork Traffic: Network Traffic FlowMicrosoft Defender for EndpointMicrosoft Sentinel Threat Intelligence

Required Tables

DeviceNetworkEventsThreatIntelligenceIndicator

False Positives & Tuning

  • Legitimate software update services or CDN endpoints that have been flagged as TI hits due to shared IP space with previously malicious infrastructure
  • Monitoring and telemetry agents (Datadog, Dynatrace, Splunk UF, PRTG) that beacon home at regular intervals, triggering the beaconing pattern branch
  • Business applications with regular API polling (CRM sync, ERP integrations, health check daemons) creating periodic connection patterns that resemble C2 beaconing
  • Cloud provider metadata endpoints or service discovery mechanisms that appear as repeated connections to the same external IP
  • False TI hits from third-party threat feeds with low-quality indicators — particularly providers that add entire cloud provider IP ranges or CDN prefixes
Download portable Sigma rule (.yml)

Other platforms for T1584.004


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 1Simulated C2 Beaconing to External IP via PowerShell

    Expected signal: Sysmon Event ID 3 (Network Connection): 10 separate connection events from powershell.exe to httpbin.org IP (public), port 80. Each event records SourceIp, DestinationIp=httpbin.org resolved IP, DestinationPort=80, Image=C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe. Sysmon Event ID 22 (DNS Query): DNS lookup for httpbin.org. DeviceNetworkEvents in MDE: 10 ConnectionSuccess events from powershell.exe to same RemoteIP over 5 minutes, enabling beaconing pattern detection.

  2. Test 2DNS Resolution of Known C2 Domain Infrastructure

    Expected signal: Sysmon Event ID 22 (DNS Query): three DnsQueryStatus events with QueryName set to each test domain, Image=C:\Windows\System32\nslookup.exe or the calling process. Windows DNS Client Event Log (Microsoft-Windows-DNS-Client/Operational) Event ID 3008 may also capture these queries. DeviceEvents table in MDE with ActionType=DnsQueryResponse if DNS monitoring is enabled.

  3. Test 3Outbound Connection to TI-Flagged IP via curl

    Expected signal: Sysmon Event ID 3 (Network Connection): connection attempts from curl.exe to 127.0.0.1 on ports 4444 and 8443 — ports commonly used by Cobalt Strike, Metasploit, and other C2 frameworks. DeviceNetworkEvents: RemoteIP=127.0.0.1, RemotePort=4444 and 8443, InitiatingProcessFileName=curl.exe. In a real test with a routable TI-flagged IP, the RemoteIPType would be Public and the ThreatIntelligenceIndicator join would match.

  4. Test 4Linux C2 Beacon Simulation via curl Loop

    Expected signal: Linux auditd: SYSCALL records for connect() and socket() system calls initiated by curl, capturing destination IP and port. Syslog: if curl failures logged, entries in /var/log/syslog. Network flow logs: 8 TCP connection records to httpbin.org IP on port 80 from the source host, each ~15 seconds apart. CEF/Syslog from perimeter firewall: session records for each connection. If osquery is deployed, the process_open_sockets or process_events table captures each connection.

Unlock Pro Content

Get the full detection package for T1584.004 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections