Detect Malicious Image in Microsoft Sentinel
Adversaries may rely on a user running a malicious image to facilitate execution. Amazon Web Services AMIs, Google Cloud Platform Images, Azure Images, and container runtimes such as Docker can be backdoored. Backdoored images may be uploaded to public repositories, and users may download and deploy an instance or container without realizing the image is malicious. This technique is commonly used to deploy cryptocurrency miners, backdoors, and data exfiltration tools. TeamTNT is a prominent threat actor known for publishing malicious Docker images to Docker Hub containing XMRig cryptocurrency miners and credential stealers. Adversaries may also typosquat popular image names to increase the likelihood of accidental deployment.
MITRE ATT&CK
- Tactic
- Execution
- Technique
- T1204 User Execution
- Sub-technique
- T1204.003 Malicious Image
- Canonical reference
- https://attack.mitre.org/techniques/T1204/003/
KQL Detection Query
let MinerProcessNames = dynamic(["xmrig", "xmrig-notls", "minerd", "cpuminer", "cryptonight", "nbminer", "t-rex", "lolminer", "ethminer", "cgminer", "bfgminer", "claymore", "phoenixminer", "teamtntbot"]);
let MiningPoolArgs = dynamic(["stratum+tcp://", "stratum+ssl://", "--donate-level", "-o pool.", "xmrpool", "supportxmr", "minexmr", "moneroocean", "hashvault", "nanopool"]);
let MiningPorts = dynamic([3333, 3334, 4444, 4445, 14444, 45560, 5555, 8333, 7777, 9999, 13333, 19999]);
let MiningPoolDomains = dynamic(["minexmr.com", "supportxmr.com", "nanopool.org", "f2pool.com", "antpool.com", "pool.minergate.com", "xmrpool.eu", "hashvault.pro", "moneroocean.stream", "xmr.pool"]);
// Branch 1: Cryptocurrency miner process execution on endpoints and container hosts
let MinerProcessExecution = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName has_any (MinerProcessNames)
or ProcessCommandLine has_any (MinerProcessNames)
or ProcessCommandLine has_any (MiningPoolArgs)
| extend DetectionBranch = "CryptoMinerProcessExecution"
| extend AlertSeverity = "High"
| project
EventTime = Timestamp,
HostName = DeviceName,
UserName = AccountName,
ProcessName = FileName,
CommandLine = ProcessCommandLine,
ParentProcess = InitiatingProcessFileName,
ParentCommandLine = InitiatingProcessCommandLine,
DetectionBranch,
AlertSeverity,
AdditionalContext = strcat("ParentPID:", tostring(InitiatingProcessId), " SHA256:", SHA256);
// Branch 2: Outbound connections to known mining pool ports and domains
let MiningNetworkConnections = DeviceNetworkEvents
| where Timestamp > ago(24h)
| where (RemotePort in (MiningPorts) and RemoteIPType != "Private")
or RemoteUrl has_any (MiningPoolDomains)
| where InitiatingProcessFileName !in~ ("firefox.exe", "chrome.exe", "msedge.exe", "brave.exe", "opera.exe", "iexplore.exe")
| extend DetectionBranch = "MiningPoolNetworkConnection"
| extend AlertSeverity = "High"
| project
EventTime = Timestamp,
HostName = DeviceName,
UserName = InitiatingProcessAccountName,
ProcessName = InitiatingProcessFileName,
CommandLine = InitiatingProcessCommandLine,
ParentProcess = InitiatingProcessParentFileName,
ParentCommandLine = "",
DetectionBranch,
AlertSeverity,
AdditionalContext = strcat("RemoteIP:", RemoteIP, " RemotePort:", tostring(RemotePort), " RemoteUrl:", RemoteUrl);
// Branch 3: Azure VM deployment from community gallery or unknown publisher image
let SuspiciousCloudImageDeploy = AzureActivity
| where TimeGenerated > ago(24h)
| where OperationNameValue =~ "MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE"
| where ActivityStatusValue =~ "Success"
| extend PropJson = parse_json(Properties)
| extend ImageRef = tostring(PropJson.requestBody)
| where ImageRef has_any ("communityGalleries", "sharedGalleries", "fromCommunityGalleryImageVersion")
or (ImageRef !has_any ("MicrosoftWindowsServer", "Canonical", "RedHat", "SUSE", "Debian", "OpenLogic", "microsoftwindowsdesktop", "center-for-internet-security-inc")
and isnotempty(ImageRef))
| extend DetectionBranch = "SuspiciousCloudImageDeployment"
| extend AlertSeverity = "Medium"
| project
EventTime = TimeGenerated,
HostName = ResourceGroup,
UserName = Caller,
ProcessName = "ARM VM Deployment",
CommandLine = ImageRef,
ParentProcess = CallerIpAddress,
ParentCommandLine = "",
DetectionBranch,
AlertSeverity,
AdditionalContext = strcat("SubscriptionId:", SubscriptionId, " Resource:", _ResourceId);
// Union all detection branches
union MinerProcessExecution, MiningNetworkConnections, SuspiciousCloudImageDeploy
| sort by EventTime desc Multi-branch detection for malicious image execution across endpoint, container host, and cloud IaaS environments. Branch 1 identifies known cryptocurrency miner binary names and command-line arguments (xmrig, minerd, stratum protocol arguments) executing on device endpoints or container hosts via Defender for Endpoint telemetry. Branch 2 detects outbound network connections to known mining pool ports (3333, 4444, 14444, 45560, etc.) and domains from non-browser processes. Branch 3 monitors Azure Activity logs for VM deployments sourcing images from community galleries or publishers not matching major verified vendors, which can indicate deployment of backdoored marketplace or community images. Results are normalized to a common schema and sorted by time for analyst review.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate GPU compute or rendering workloads using non-standard network ports that overlap with mining pool port ranges
- Authorized red team or penetration testing exercises deploying containers or VMs with miner tooling under a formal engagement
- Internal benchmark and performance testing tools with process names similar to mining tools (e.g., t-rex, cgminer used for GPU stress testing)
- DevOps data pipeline workers with names like 'ethminer' or 'cpuminer' used for internal job queue processing (not mining)
- Legitimate third-party marketplace VM deployments for network appliances, security tools, or specialized workloads not from major known publishers
Other platforms for T1204.003
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.
- Test 1Docker Container Executing Cryptocurrency Miner Process Name
Expected signal: Linux syslog or auditd process creation event showing process name 'xmrig' spawned under dockerd/containerd parent process. If Sysmon for Linux is deployed, EventCode=1 with Image containing 'xmrig' and ParentImage containing 'containerd-shim' or 'runc'. Docker daemon logs show container start/stop events.
- Test 2Simulate Mining Pool Network Connection Attempt
Expected signal: If Sysmon for Linux is deployed: EventCode=3 network connection event with Image=curl, DestinationPort=3333, DestinationHostname=pool.minexmr.com. DNS query EventCode=22 for pool.minexmr.com. On Windows equivalent: 'Test-NetConnection -ComputerName pool.minexmr.com -Port 3333' generates Sysmon EventCode=3.
- Test 3Pull and Inspect Publicly Known Malicious-Style Docker Image Name
Expected signal: Docker daemon log entry for image pull. Process creation event for 'wget' process spawned from container runtime (dockerd/containerd parent). Network connection attempt to 127.0.0.1:3333 generating Sysmon EventCode=3 or auditd network event. 'docker history' output shows image layer commands.
- Test 4AWS EC2 Instance Launch from Public Community AMI
Expected signal: AWS CloudTrail RunInstances event with eventName=RunInstances, requestParameters.instancesSet.items[0].imageId containing the public AMI ID, userIdentity fields showing the executing principal, awsRegion=us-east-1. Followed by StopInstances event.
- Test 5Container Environment Variable Credential Exposure Simulation
Expected signal: Process creation event with container spawning wget/curl with credential parameters visible in command line. Network connection attempt to exfil endpoint. Container inspect shows AWS_* environment variables in container configuration. Linux syslog shows process execution under dockerd parent.
References (10)
- https://attack.mitre.org/techniques/T1204/003/
- https://summitroute.com/blog/2018/09/24/investigating_malicious_amis/
- https://info.aquasec.com/hubfs/Threat%20reports/AquaSecurity_Cloud_Native_Threat_Report_2021.pdf
- https://www.lacework.com/blog/teamtnt-the-first-crypto-mining-worm-to-steal-aws-credentials/
- https://unit42.paloaltonetworks.com/teamtnt-cryptojacking-watchdog-masquerade/
- https://docs.microsoft.com/en-us/azure/sentinel/data-connectors-reference
- https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1204.003/T1204.003.md
- https://sysdig.com/blog/teamtnt-docker-hub-cryptomining/
- https://www.trendmicro.com/vinfo/us/security/news/virtualization-and-cloud/coinminer-ddos-bot-attack-docker-daemon-ports
Unlock Pro Content
Get the full detection package for T1204.003 including response playbook, investigation guide, and atomic red team tests.