Detect Cloud GPU / Compute-Optimized Instance Burst Provisioning for Cryptocurrency Mining in CrowdStrike LogScale
Once an adversary obtains valid cloud credentials (a leaked IAM access key, an over-permissioned CI/CD service principal, or a session hijacked via token theft), one of the most direct ways to monetize that access is Resource Hijacking: rather than exfiltrating data or staging ransomware, the actor simply rents the victim's own compute at the victim's expense to mine cryptocurrency. The observable pattern is distinctive from routine autoscaling or ML workload provisioning: the actor scripts a burst of RunInstances (AWS) or Microsoft.Compute/virtualMachines/write (Azure) calls requesting GPU-accelerated or bare-metal compute-optimized instance families (AWS p3/p3dn/p4d/p4de/p5, g4dn/g4ad/g5/g5g/g6, trn1/inf2, and .metal families; Azure NC/ND/NV/HB/HC series) — the same instance classes used for legitimate ML training and HPC, chosen specifically for their hash-rate-per-dollar economics rather than any workload the victim actually asked for. Launches are frequently fanned out across multiple regions or even multiple linked accounts/subscriptions in the same short window to slip under any single region's service quota and to slow discovery, since most organizations' cost anomaly alerting operates on a daily or slower cadence while the mining operation itself can be running within minutes of credential compromise. Once running, the instances typically establish outbound TCP connections on ports associated with the Stratum mining protocol (3333, 4444, 5555, 7777, 8080, 14444, 14433, 45560) to a mining pool endpoint, and sustain near-100% CPU/GPU utilization for as long as the credentials remain valid — the direct cost impact (often tens of thousands of dollars within a day for GPU-class instances) is frequently the first signal a victim organization notices, arriving as a shocking cloud bill days after the actual compromise.
MITRE ATT&CK
- Tactic
- Impact
LogScale Detection Query
#event_simpleName=/(CloudTrail|AzureActivityLog)/
(eventName="RunInstances" AND instanceType=/^(p3|p3dn|p4d|p4de|p5|g4dn|g4ad|g5|g5g|g6|trn1|inf2)\.|\.metal$/)
OR (operationName=/MICROSOFT\.COMPUTE\/VIRTUALMACHINES\/WRITE/ AND vmSize=/^Standard_(NC|ND|NV|HB|HC)/)
| Identity := coalesce(field=[userIdentityArn, caller])
| AccountOrSub := coalesce(field=[recipientAccountId, subscriptionId])
| ResourceType := coalesce(field=[instanceType, vmSize])
| groupBy([Identity, AccountOrSub], function=[count(as=LaunchCount), collect(ResourceType, limit=20)])
| test(LaunchCount >= 5)
| sort(LaunchCount, order=desc) CrowdStrike LogScale query over ingested AWS CloudTrail and Azure Activity Log repositories. Flags identities launching 5 or more GPU-accelerated or compute-optimized instances/VMs, grouping by calling identity and account/subscription for triage of a scripted resource-hijacking burst.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate distributed ML training or hyperparameter sweep bursts
- Render farm/VFX/HPC batch jobs scheduled to burst-provision GPU capacity
- Cluster autoscalers backing legitimate GPU-accelerated inference workloads
- Authorized capacity or benchmark testing using the same instance families
- First production training run from a newly onboarded ML team
Other platforms for THREAT-Impact-CloudGPUCryptojackingBurstProvisioning
Testing Methodology
Validate this detection against 3 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 1Simulate AWS GPU Instance Burst Launch
Expected signal: AWS CloudTrail management events: eventName=RunInstances, eventSource=ec2.amazonaws.com, requestParameters.instancesSet.items[].instanceType=g4dn.xlarge, five or more events from the same userIdentity.arn within a few minutes.
- Test 2Simulate Azure GPU VM Burst Provisioning
Expected signal: Azure Activity Log entries: operationName=MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE, resultType=Success, properties.responseBody.properties.hardwareProfile.vmSize=Standard_NC6s_v3, five or more events from the same caller within a few minutes.
- Test 3Simulate Outbound Stratum Mining Pool Connection
Expected signal: VPC Flow Logs / NSG Flow Logs showing an outbound TCP connection attempt from the test instance's ENI to destination port 3333/4444 against the test destination 203.0.113.10.
References (6)
- https://attack.mitre.org/techniques/T1496/001/
- https://attack.mitre.org/tactics/TA0040/
- https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html
- https://learn.microsoft.com/en-us/azure/virtual-machines/sizes-gpu
- https://aws.amazon.com/blogs/security/how-to-use-aws-cost-anomaly-detection-to-identify-anomalous-spend/
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1496.001/T1496.001.md
Response Playbook
Triage
- Identify the calling identity (UserIdentityArn on AWS, Caller on Azure): is this a recognized ML/data-science automation role, a CI/CD service principal, or an identity with no history of launching GPU/compute-optimized instances? A first-time or human interactive identity bursting GPU launches outside a documented project is the highest-priority scenario
- Enumerate exactly which instance types/VM sizes were launched and in which regions/subscriptions — a fan-out across multiple regions or linked accounts in a short window is a strong signal of an actor deliberately evading per-region service quotas and slow-cadence cost alerting
- Check the launched instances' outbound network connections for Stratum mining protocol indicators (TCP ports 3333, 4444, 5555, 7777, 8080, 14444, 14433, 45560 to non-cloud-provider destinations) and sustained near-100% CPU/GPU utilization shortly after launch
- Correlate the calling identity's recent authentication history (console login, AssumeRole/token issuance, service principal credential use) for signs of compromise — impossible travel, a new MFA device, or an unfamiliar source IP/ASN immediately preceding the burst
- Check cost/billing anomaly data (AWS Cost Anomaly Detection, Azure Cost Management alerts) for a spend spike correlated with the launch burst — GPU-class instance mining is frequently discovered first through the bill, not the control-plane log
- Determine whether the same identity or account also shows other cloud-credential-abuse indicators in the same window (new IAM access keys, new role trust policy grants, disabled CloudTrail/Activity Log delivery) that would suggest broader compromise beyond a single stolen credential
Containment
- Immediately terminate/deallocate the identified GPU/compute-optimized instances and revoke or rotate the credentials (IAM access keys, AWS STS sessions, Azure service principal secrets/certificates) used to launch them
- Suspend or restrict the IAM policy/Azure RBAC role that allowed this identity to call RunInstances/virtualMachines write for expensive instance families — consider a service control policy or Azure Policy that requires approval for GPU/bare-metal instance types going forward
- Set or lower per-region and per-account EC2/VM service quotas for GPU and metal instance families to bound the blast radius of any future compromise of this or similar identities
- Review and revoke any newly created IAM users/roles, access keys, or Azure app registrations that may have been added by the attacker as a persistence foothold alongside the mining launch
- Notify billing/finance stakeholders immediately given the direct and often large financial impact, and open a support case with the cloud provider — both AWS and Azure have documented processes for requesting fee forgiveness on confirmed compromise-driven mining charges
- If Stratum-protocol egress was confirmed, block the destination mining pool IPs/domains at the network/security-group layer and hunt for the same indicators across the rest of the estate
Evidence Collection
- Full CloudTrail/Activity Log record for every RunInstances/virtualMachines-write call in the burst, including request parameters (instance type, AMI/image, security groups, key pair), response elements (instance IDs), source IP, and the complete userIdentity/caller block
- VPC Flow Logs / NSG Flow Logs for the launched instances showing outbound connections, particularly to the Stratum mining protocol port set and any repeated connections to a small number of external IPs
- Instance/VM performance metrics (CloudWatch CPUUtilization, Azure Monitor Percentage CPU/GPU metrics) confirming sustained high utilization consistent with mining rather than idle or briefly-used capacity
- IAM credential report / Azure AD sign-in logs for the calling identity's authentication history over the 48-72 hours preceding the burst
- Cloud provider billing/cost-explorer data itemizing the compute spend attributable to the malicious instances, needed for both incident scoping and any fee-forgiveness request
Escalation Criteria
- !The calling identity has no documented history or business justification for launching GPU/compute-optimized instances, and no corresponding change ticket or project exists
- !Launches fan out across multiple regions or multiple linked accounts/subscriptions within the same short window
- !Confirmed outbound connections from the launched instances to Stratum mining protocol ports or known mining pool infrastructure
- !The same identity shows other signs of credential compromise (impossible travel, new MFA device/access key, unfamiliar source ASN) in the authentication logs
- !Estimated or actual compute spend from the burst exceeds a material threshold for the organization, or the burst is still ongoing at time of detection
Investigation Guide
Related Techniques
Forensic Artifacts
- >
AWS CloudTrail RunInstances event records including full requestParameters (instanceType, imageId, securityGroupIds) and responseElements (instancesSet with instance IDs) - >
Azure Activity Log entries for Microsoft.Compute/virtualMachines/write including the full HTTP request body in the Properties field (vmSize, location, image reference) - >
VPC/NSG Flow Log records for the launched instances' outbound connections, particularly repeated connections on Stratum protocol ports - >
CloudWatch/Azure Monitor CPU and GPU utilization metrics for the affected instances over their runtime - >
AWS Cost Explorer / Azure Cost Management line-item billing data attributing spend to the specific instance IDs and identity - >
IAM access key / Azure AD sign-in logs for the calling identity's authentication and credential-issuance history
Tuning Guidance
The single highest-value tuning lever is an allowlist of known ML/data-science and render-farm automation identities (IAM role ARNs / Azure AD service principal object IDs) that legitimately launch GPU fleets on a recurring basis — exclude them by identity, not by instance type, since the instance types themselves are identical between legitimate ML workloads and mining. Keep the BurstWindow and MinLaunchCount thresholds calibrated to your organization's actual GPU usage baseline: an org that never uses GPU instances can lower MinLaunchCount to 1-2 for a much more sensitive alert, while an ML-heavy org should rely more heavily on the identity allowlist and the region/subscription fan-out signal than on raw launch count. Pair this control-plane detection with an endpoint/network-layer rule for Stratum protocol port connections (3333/4444/5555/7777/8080/14444/14433/45560) where VPC/NSG Flow Logs are available — the combination of an unrecognized identity's GPU burst plus confirmed Stratum egress is a near-definitive true positive. Also monitor cloud cost anomaly alerts as a backstop, since a determined actor using unfamiliar-but-technically-valid instance types could otherwise evade a static instance-type allowlist.
Hunting Queries
30-day baseline hunt across both clouds for any GPU/compute-optimized instance launch, establishing which identities routinely use this class of compute (data-science teams, render pipelines) versus which appear only once or for the first time — a first-time caller launching a burst is significantly higher-suspicion than a recognized ML/automation identity with a long history.
// Hunt: any RunInstances/virtualMachines-write call for GPU or metal instance families over 30 days, to baseline which identities routinely launch this class of compute vs which show up for the first time
union
(AWSCloudTrail
| where TimeGenerated > ago(30d)
| where EventName == "RunInstances"
| extend InstanceType = tostring(parse_json(tostring(RequestParameters)).instancesSet.items[0].instanceType)
| where InstanceType matches regex @"^(p3|p3dn|p4d|p4de|p5|g4dn|g4ad|g5|g5g|g6|trn1|inf2)\." or InstanceType endswith ".metal"
| summarize Launches = count(), Types = make_set(InstanceType) by UserIdentityArn, RecipientAccountId),
(AzureActivity
| where TimeGenerated > ago(30d)
| where OperationNameValue == "MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE"
| extend VmSize = tostring(parse_json(tostring(Properties)).responseBody.properties.hardwareProfile.vmSize)
| where VmSize matches regex @"^Standard_(NC|ND|NV|HB|HC)"
| summarize Launches = count(), Types = make_set(VmSize) by Caller, SubscriptionId)
| sort by Launches desc index=aws sourcetype="aws:cloudtrail" eventName="RunInstances"
| eval InstanceType=mvindex(spath(requestParameters, "instancesSet.items{}.instanceType"), 0)
| regex InstanceType="^(p3|p3dn|p4d|p4de|p5|g4dn|g4ad|g5|g5g|g6|trn1|inf2)\.|\.metal$"
| stats count as Launches, values(InstanceType) as Types by userIdentity.arn, recipientAccountId
| append
[ search index=azure sourcetype="azure:activity" operationName="MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE"
| eval VmSize=spath(properties, "responseBody.properties.hardwareProfile.vmSize")
| regex VmSize="^Standard_(NC|ND|NV|HB|HC)"
| stats count as Launches, values(VmSize) as Types by caller, subscriptionId ]
| sort - Launches Atomic Red Team Tests
Launches five disposable GPU instances (g4dn.xlarge) in rapid succession from a test account, simulating the burst-provisioning pattern used to stand up a mining fleet. Use a throwaway test account/VPC with strict service quotas and terminate immediately after the test.
Command
for i in $(seq 1 5); do aws ec2 run-instances --image-id ami-0abcdef1234567890 --instance-type g4dn.xlarge --count 1 --subnet-id subnet-0test --tag-specifications 'ResourceType=instance,Tags=[{Key=purpose,Value=df00tech-atomic-test}]'; done Cleanup
aws ec2 describe-instances --filters 'Name=tag:purpose,Values=df00tech-atomic-test' --query 'Reservations[].Instances[].InstanceId' --output text | xargs -r aws ec2 terminate-instances --instance-ids Expected Telemetry
AWS CloudTrail management events: eventName=RunInstances, eventSource=ec2.amazonaws.com, requestParameters.instancesSet.items[].instanceType=g4dn.xlarge, five or more events from the same userIdentity.arn within a few minutes.
Expected Detection
Alert fires once LaunchCount >= 5 within the 1-hour BurstWindow for the same UserIdentityArn/RecipientAccountId — CloudProvider=AWS, ResourceTypes containing g4dn.xlarge.
Creates five disposable NC-series GPU VMs in rapid succession in a test resource group, simulating the same burst-provisioning pattern on Azure. Use a throwaway test subscription/resource group and delete immediately after the test.
Command
for i in $(seq 1 5); do az vm create --resource-group df00tech-atomic-test-rg --name df00tech-atomic-gpu-$i --image Ubuntu2204 --size Standard_NC6s_v3 --generate-ssh-keys --no-wait; done Cleanup
az group delete --name df00tech-atomic-test-rg --yes --no-wait Expected Telemetry
Azure Activity Log entries: operationName=MICROSOFT.COMPUTE/VIRTUALMACHINES/WRITE, resultType=Success, properties.responseBody.properties.hardwareProfile.vmSize=Standard_NC6s_v3, five or more events from the same caller within a few minutes.
Expected Detection
Alert fires once LaunchCount >= 5 within the 1-hour BurstWindow for the same Caller/SubscriptionId — CloudProvider=Azure, ResourceTypes containing Standard_NC6s_v3.
Opens an outbound TCP connection to a locally-controlled listener on a Stratum mining protocol port from a disposable test instance, simulating the network egress pattern of an active cryptomining process without running any actual miner binary.
Command
nc -zv 203.0.113.10 3333 || true; nc -zv 203.0.113.10 4444 || true Cleanup
No persistent state created; no cleanup required beyond terminating the disposable test instance used to run the command. Expected Telemetry
VPC Flow Logs / NSG Flow Logs showing an outbound TCP connection attempt from the test instance's ENI to destination port 3333/4444 against the test destination 203.0.113.10.
Expected Detection
Feeds the network-layer correlation described in tuningGuidance: an unrecognized identity's GPU launch burst combined with Stratum-port egress from the resulting instance should be treated as a near-definitive true positive even if the control-plane burst threshold alone was not met.
Related Detections
Tactic Hub
Detection Variants (1)
Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.