T1583.005 Microsoft Sentinel · KQL

Detect Botnet in Microsoft Sentinel

Adversaries may buy, lease, or rent a network of compromised systems (botnet) to use during targeting. Botnets provide adversaries with scalable infrastructure for phishing campaigns, DDoS attacks, credential stuffing, and covert C2 relay via Operational Relay Box (ORB) networks. Detection pivots from the unobservable acquisition event itself to observable usage patterns: volumetric inbound attacks against organizational infrastructure, internal hosts exhibiting botnet C2 beaconing behavior, ORB relay traffic routing through VPS/SOHO/IoT IP space, and DNS query patterns consistent with botnet domain generation or C2 resolution.

MITRE ATT&CK

Tactic
Resource Development
Technique
T1583 Acquire Infrastructure
Sub-technique
T1583.005 Botnet
Canonical reference
https://attack.mitre.org/techniques/T1583/005/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
// === QUERY 1: Botnet C2 Beaconing from Compromised Internal Host ===
// Detects internal processes making highly regular outbound connections to the same external IP
// (characteristic of botnet C2 beaconing at fixed intervals)
let ExcludedProcesses = dynamic(["svchost.exe", "SearchIndexer.exe", "MicrosoftEdgeUpdate.exe",
  "OneDrive.exe", "Teams.exe", "outlook.exe", "msedge.exe", "chrome.exe", "firefox.exe"]);
let ExcludedPorts = dynamic([80, 443, 53]);
DeviceNetworkEvents
| where Timestamp > ago(24h)
| where ActionType == "ConnectionSuccess"
| where RemoteIPType == "Public"
| where not(InitiatingProcessFileName has_any (ExcludedProcesses))
| where not(RemotePort in (ExcludedPorts))
| summarize
    ConnectionCount = count(),
    FirstSeen = min(Timestamp),
    LastSeen = max(Timestamp),
    DurationMinutes = datetime_diff('minute', max(Timestamp), min(Timestamp)),
    SampleCommandLine = any(InitiatingProcessCommandLine)
    by DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessId, RemoteIP, RemotePort
| where ConnectionCount >= 12
| where DurationMinutes >= 30
| extend ConnectionsPerHour = toreal(ConnectionCount) / (toreal(DurationMinutes) / 60.0)
// Regular beaconing: many connections, consistent rate
| where ConnectionsPerHour >= 4 and ConnectionsPerHour <= 120
| extend BeaconScore = case(
    ConnectionCount > 100 and DurationMinutes > 120, "Critical",
    ConnectionCount > 50, "High",
    ConnectionCount > 20, "Medium",
    "Low"
  )
| project Timestamp=LastSeen, DeviceName, AccountName, InitiatingProcessFileName,
    InitiatingProcessId, RemoteIP, RemotePort, ConnectionCount, DurationMinutes,
    ConnectionsPerHour, BeaconScore, SampleCommandLine
| sort by ConnectionCount desc

// === QUERY 2: Inbound Volumetric Botnet Attack Pattern (DDoS/Credential Stuffing) ===
// Detects high-rate inbound connections from many distinct source IPs within short time windows
// CommonSecurityLog covers perimeter firewall, WAF, or network device logs
// Uncomment and customize for your environment
// CommonSecurityLog
// | where TimeGenerated > ago(1h)
// | where DeviceAction !in~ ("deny", "block", "drop", "reset")
// | where DestinationPort in (80, 443, 8080, 8443, 22, 3389, 25, 587)
// | summarize
//     UniqueSourceIPs = dcount(SourceIP),
//     TotalRequests = count(),
//     SourceCountries = make_set(DeviceCustomString1, 20)
//     by DestinationIP, DestinationPort, bin(TimeGenerated, 5m)
// | where UniqueSourceIPs > 50 and TotalRequests > 500
// | extend AttackCategory = case(
//     DestinationPort in (80, 443, 8080, 8443), "HTTP Flood / Web Attack",
//     DestinationPort in (22, 3389), "Credential Stuffing / Brute Force",
//     DestinationPort in (25, 587), "Spam Campaign",
//     "Volumetric Flood"
//   )
// | sort by UniqueSourceIPs desc

// === QUERY 3: ORB Network Relay — Internal Host Acting as Relay Node ===
// Detects hosts receiving external connections AND initiating outbound connections to different external IPs
// Pattern: external IP connects in, host immediately connects out to different external IP (relay behavior)
let TimeWindow = 5m;
let InboundConnections = DeviceNetworkEvents
    | where Timestamp > ago(24h)
    | where ActionType == "InboundConnectionAccepted"
    | where RemoteIPType == "Public"
    | project InboundTime=Timestamp, DeviceName, InboundSourceIP=RemoteIP, LocalPort=LocalPort;
let OutboundConnections = DeviceNetworkEvents
    | where Timestamp > ago(24h)
    | where ActionType == "ConnectionSuccess"
    | where RemoteIPType == "Public"
    | where RemotePort !in (80, 443, 53)
    | project OutboundTime=Timestamp, DeviceName, OutboundDestIP=RemoteIP, OutboundPort=RemotePort,
        InitiatingProcessFileName, InitiatingProcessCommandLine;
InboundConnections
| join kind=inner OutboundConnections on DeviceName
| where OutboundTime between (InboundTime .. (InboundTime + TimeWindow))
| where InboundSourceIP != OutboundDestIP
| summarize
    RelayEvents = count(),
    InboundSources = make_set(InboundSourceIP, 10),
    OutboundTargets = make_set(OutboundDestIP, 10)
    by DeviceName, InitiatingProcessFileName
| where RelayEvents >= 3
| sort by RelayEvents desc
high severity medium confidence

Three-part detection targeting observable botnet usage patterns. Query 1 identifies internal hosts exhibiting C2 beaconing behavior — regular periodic connections to a consistent external IP from non-browser processes at a frequency consistent with automated callback intervals. Query 2 (commented template) detects volumetric inbound attacks from many distributed source IPs characteristic of botnet-driven DDoS or credential stuffing campaigns against organizational services. Query 3 identifies hosts acting as ORB relay nodes by correlating inbound external connections with rapid outbound connections to different external targets. Confidence is set to medium because legitimate CDN, telemetry, and update services produce similar connection patterns.

Data Sources

Network Traffic: Network Connection CreationNetwork Traffic: Network Traffic FlowMicrosoft Defender for Endpoint — DeviceNetworkEvents

Required Tables

DeviceNetworkEventsCommonSecurityLog

False Positives & Tuning

  • CDN and telemetry clients (crash reporters, update services) making regular heartbeat connections to the same endpoint
  • Legitimate monitoring agents (Datadog, New Relic, Dynatrace) with fixed-interval health check beacons
  • Business applications with embedded polling loops for license validation or configuration retrieval
  • Load balancers and reverse proxies that accept external connections and forward to internal services — normal relay architecture
  • Peer-to-peer software (backup clients, VPN clients, collaborative tools) that maintain persistent connections to distributed infrastructure
Download portable Sigma rule (.yml)

Other platforms for T1583.005


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 C2 Beaconing — Regular Periodic Outbound Connections

    Expected signal: Sysmon Event ID 3 (Network Connection): 30 events from powershell.exe connecting to 127.0.0.1:8080 at regular ~10-second intervals. KQL DeviceNetworkEvents will show ConnectionCount=30, DurationMinutes=~5, ConnectionsPerHour=~360. The connection will fail (connection refused) if no listener is running, but Sysmon will still log the attempt if configured with network monitoring.

  2. Test 2Simulate ORB Relay Behavior — Inbound-then-Outbound Network Pattern

    Expected signal: Sysmon Event ID 3: two network connection events from powershell.exe within the 5-minute correlation window — one inbound accepted connection (or attempt) on port 19876, and one outbound connection to 8.8.8.8:53. The join query in KQL correlates these events by DeviceName within the TimeWindow variable.

  3. Test 3Connect to IRC-Protocol Port — Botnet C2 Channel Simulation

    Expected signal: Sysmon Event ID 3: network connection from powershell.exe to port 6667. DeviceNetworkEvents: RemotePort=6667, InitiatingProcessFileName=powershell.exe. Note: 127.0.0.1 is excluded from the detection queries as a private IP — to validate the detection pipeline, point this at a controlled external test host on port 6667.

  4. Test 4Mass External Connection Simulation — Botnet Spreader Behavior

    Expected signal: Sysmon Event ID 3: multiple network connection events from powershell.exe to 30 unique IPs in the 203.0.113.0/24 range (TEST-NET-3, RFC 5737 documentation range — routable but safe for testing) on port 22. KQL DeviceNetworkEvents will show InitiatingProcessFileName=powershell.exe with UniqueExternalIPs=30.

Unlock Pro Content

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

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections