T1543.005 Microsoft Sentinel · KQL

Detect Container Service in Microsoft Sentinel

Adversaries may create or modify container or container cluster management tools that run as daemons, agents, or services on individual hosts. These include software for creating and managing individual containers, such as Docker and Podman, as well as container cluster node-level agents such as kubelet. By modifying these services, an adversary may achieve persistence or escalate their privileges on a host. Common abuse patterns include using 'docker run' or 'podman run' with the '--restart=always' directive to configure a container to persistently restart after daemon restarts or host reboots, using '--privileged', '--pid=host', or '--net=host' flags to break container isolation and gain access to the underlying host kernel, bind-mounting the root filesystem ('-v /:/') to read or modify host files, and leveraging Kubernetes DaemonSets to deploy malicious containers persistently across all current and future cluster nodes. Threat actor groups including TeamTNT have exploited exposed Docker APIs to deploy cryptomining and backdoor containers with restart=always policies. Privilege escalation via docker group membership is documented in GTFOBins and widely exploited in post-exploitation scenarios.

MITRE ATT&CK

Tactic
Persistence Privilege Escalation
Technique
T1543 Create or Modify System Process
Sub-technique
T1543.005 Container Service
Canonical reference
https://attack.mitre.org/techniques/T1543/005/

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let SuspiciousContainerFlags = dynamic([
    "--restart=always", "--restart always",
    "--privileged",
    "--pid=host",
    "--net=host", "--network=host",
    "--cap-add=SYS_ADMIN", "--cap-add SYS_ADMIN",
    "--cap-add ALL", "--cap-add=ALL",
    "-v /:/", "--volume /:/",
    "--device /dev/mem", "--device /dev/kmem"
]);
let ContainerRuntimes = dynamic(["docker", "podman", "nerdctl"]);
// Signal 1: Container run with persistence (restart=always) or privilege escalation flags
let ContainerRunAbuse = DeviceProcessEvents
| where Timestamp > ago(24h)
| where (FileName in~ (ContainerRuntimes)) or (InitiatingProcessFileName in~ (ContainerRuntimes))
| where ProcessCommandLine has "run"
| where ProcessCommandLine has_any (SuspiciousContainerFlags)
| extend PersistenceFlag = ProcessCommandLine has_any ("--restart=always", "--restart always")
| extend PrivilegedFlag = ProcessCommandLine has_any ("--privileged", "--pid=host", "--net=host", "--network=host", "--cap-add=SYS_ADMIN", "--cap-add SYS_ADMIN", "--cap-add ALL", "--cap-add=ALL")
| extend HostMountFlag = ProcessCommandLine has_any ("-v /:/", "--volume /:/", "--device /dev/mem", "--device /dev/kmem")
| extend RiskScore = toint(PersistenceFlag) + toint(PrivilegedFlag) + toint(HostMountFlag)
| extend AttackPattern = case(
    PersistenceFlag and PrivilegedFlag, "CRITICAL: Persistent privileged container — auto-restart with full host kernel access",
    PersistenceFlag and HostMountFlag, "CRITICAL: Persistent container with host root filesystem mount",
    PrivilegedFlag and HostMountFlag, "HIGH: Privileged container with host root filesystem access",
    PersistenceFlag, "MEDIUM: Container persistence via restart=always policy",
    PrivilegedFlag, "HIGH: Container privilege escalation or host escape via capability flags",
    HostMountFlag, "HIGH: Host root filesystem bind mount — full host file read/write",
    "MEDIUM: Suspicious container configuration"
)
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
         InitiatingProcessFileName, InitiatingProcessCommandLine,
         PersistenceFlag, PrivilegedFlag, HostMountFlag, RiskScore, AttackPattern;
// Signal 2: Docker exec spawning interactive shell (post-exploitation inside container)
let ContainerExecShell = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ (ContainerRuntimes)
| where ProcessCommandLine has "exec" 
| where ProcessCommandLine has_any ("/bin/bash", "/bin/sh", "/bin/zsh", "bash", "sh -i", "sh -c")
| where not(InitiatingProcessFileName in~ ("containerd", "dockerd", "container-shim"))
| extend PersistenceFlag = false
| extend PrivilegedFlag = false
| extend HostMountFlag = false
| extend RiskScore = 1
| extend AttackPattern = "MEDIUM: Interactive shell exec into running container — potential lateral movement or post-exploitation"
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
         InitiatingProcessFileName, InitiatingProcessCommandLine,
         PersistenceFlag, PrivilegedFlag, HostMountFlag, RiskScore, AttackPattern;
ContainerRunAbuse
| union ContainerExecShell
| sort by Timestamp desc
high severity medium confidence

Detects container service abuse for persistence and privilege escalation via Microsoft Defender for Endpoint DeviceProcessEvents on Linux hosts. Signal 1 identifies Docker, Podman, or nerdctl run commands containing flags associated with container persistence (restart=always), privilege escalation (--privileged, --pid=host, --net=host, --cap-add=SYS_ADMIN), or host filesystem access (-v /:/). Signal 2 detects interactive shell execution via 'docker exec' which indicates post-exploitation activity. RiskScore aggregates flag categories for prioritization — score of 2+ indicates combined persistence with privilege escalation and warrants immediate investigation.

Data Sources

Process: Process CreationCommand: Command ExecutionMicrosoft Defender for Endpoint (Linux)

Required Tables

DeviceProcessEvents

False Positives & Tuning

  • Legitimate infrastructure-as-code pipelines (Ansible, Terraform, Puppet) deploying containers with specific restart policies in staging and production environments
  • Platform engineering teams running privileged containers for system-level tooling such as monitoring exporters (node-exporter, Falco), network packet capture tools, or kernel debuggers
  • Container security tooling (Falco, Sysdig, Tetragon) that require --privileged or specific capabilities to instrument the kernel
  • Developers using 'docker exec' to debug running containers in development environments
  • CI/CD systems running Docker-in-Docker (DinD) builds that require privileged containers or socket mounts
Download portable Sigma rule (.yml)

Other platforms for T1543.005


Testing Methodology

Validate this detection against 5 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 1Docker Container Persistence via restart=always

    Expected signal: Linux auditd EXECVE: type=EXECVE with a0=docker, a1=run, a2=-d, a3=--restart=always, a4=--name, a5=df00tech-persist-test. MDE DeviceProcessEvents: FileName=docker, ProcessCommandLine contains 'run' and '--restart=always'. Expected PersistenceFlag=true, PrivilegedFlag=false, HostMountFlag=false, RiskScore=1.

  2. Test 2Privileged Container Execution with Host PID Namespace

    Expected signal: Linux auditd EXECVE: type=EXECVE with args containing 'docker', 'run', '--privileged', '--pid=host'. MDE DeviceProcessEvents: ProcessCommandLine contains '--privileged' and '--pid=host'. PrivilegedFlag=true, RiskScore=1.

  3. Test 3Container with Host Root Filesystem Bind Mount

    Expected signal: Linux auditd EXECVE: args containing 'docker', 'run', '-v', '/:/host-root:ro'. MDE DeviceProcessEvents: ProcessCommandLine contains '-v /:/host-root'. HostMountFlag triggers on '-v /:/'. RiskScore=1.

  4. Test 4Combined Persistent Privileged Container (Critical Combination)

    Expected signal: Linux auditd EXECVE: args contain 'docker', 'run', '-d', '--restart=always', '--privileged', '--name', 'df00tech-critical-test'. MDE DeviceProcessEvents: ProcessCommandLine contains '--restart=always' and '--privileged'. PersistenceFlag=true, PrivilegedFlag=true, RiskScore=2.

  5. Test 5Kubernetes DaemonSet Creation for Cluster-Wide Persistence

    Expected signal: Kubernetes API server audit log: verb=create, objectRef.resource=daemonsets, objectRef.namespace=default, objectRef.name=df00tech-persist-daemonset, responseStatus.code=201. AzureDiagnostics Category=kube-audit or AKSAuditAdmin table: DaemonSet creation event with requesting user and full object spec.

Unlock Pro Content

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

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections