Detect Delete Cloud Instance in Splunk
An adversary may delete a cloud instance after performing malicious activities in an attempt to evade detection and remove evidence of their presence. Deleting an instance or virtual machine can eliminate forensic artifacts including memory contents, running processes, local logs, and volatile state that would otherwise be available for incident response. Adversaries such as LAPSUS$ have deleted target cloud resources to trigger incident response processes and maximize disruption, while ransomware operators like Storm-0501 conduct mass deletion of Azure resources across subscriptions. The technique may be combined with T1578.002 (Create Cloud Instance) where adversaries spin up ephemeral instances for malicious work, then delete them upon completion.
MITRE ATT&CK
- Tactic
- Defense Evasion
- Sub-technique
- T1578.003 Delete Cloud Instance
- Canonical reference
- https://attack.mitre.org/techniques/T1578/003/
SPL Detection Query
| tstats summariesonly=false allow_old_summaries=true count min(_time) as firstTime max(_time) as lastTime
from datamodel=Cloud_Infrastructure where
(Cloud_Infrastructure.action=deleted OR Cloud_Infrastructure.action=terminate OR Cloud_Infrastructure.action=deregister)
AND Cloud_Infrastructure.object_category=instance
by Cloud_Infrastructure.user, Cloud_Infrastructure.src, Cloud_Infrastructure.object, Cloud_Infrastructure.action, Cloud_Infrastructure.vendor_account, Cloud_Infrastructure.region
| rename Cloud_Infrastructure.* as *
| eval DeleteType="generic"
| append
[ search index=aws sourcetype=aws:cloudtrail EventName IN ("TerminateInstances","DeleteInstance","DeregisterInstance") errorCode=""
| eval CloudProvider="AWS"
| eval CallerIdentity=coalesce(userIdentity.arn, userIdentity.userName, "unknown")
| eval AccountType=userIdentity.type
| eval TargetInstances=mvindex(split(tostring(requestParameters.instancesSet.items), ","), 0, 10)
| eval InstanceCount=mvcount(split(tostring(requestParameters.instancesSet.items), ","))
| eval DeleteType=if(InstanceCount > 5, "BulkDelete", "SingleDelete")
| eval SuspicionScore=0
| eval SuspicionScore=SuspicionScore + if(InstanceCount > 10, 3, if(InstanceCount > 3, 1, 0))
| eval SuspicionScore=SuspicionScore + if(AccountType="Root", 3, 0)
| eval SuspicionScore=SuspicionScore + if(match(sourceIPAddress, "^(3\..*|52\..*|54\..*)$") AND AccountType!="AWSService", 1, 0)
| table _time, CloudProvider, CallerIdentity, AccountType, EventName, awsRegion, sourceIPAddress, TargetInstances, InstanceCount, DeleteType, SuspicionScore, recipientAccountId
]
| append
[ search index=azure sourcetype=azure:monitor:activity operationName="Microsoft.Compute/virtualMachines/delete" OR operationName="Microsoft.Compute/virtualMachineScaleSets/delete" status.value="Succeeded"
| eval CloudProvider="Azure"
| eval CallerIdentity=coalesce(caller, "unknown")
| eval AccountType=if(match(CallerIdentity, "@"), "UserAccount", "ServicePrincipal")
| eval ResourceName=coalesce(resourceId, "unknown")
| eval SuspicionScore=0
| eval SuspicionScore=SuspicionScore + if(AccountType="UserAccount" AND match(operationName, "delete"), 2, 0)
| eval SuspicionScore=SuspicionScore + if(match(ResourceName, "(?i)(prod|production|critical|primary)"), 2, 0)
| table _time, CloudProvider, CallerIdentity, AccountType, operationName, subscriptionId, resourceGroupName, ResourceName, SuspicionScore
]
| where SuspicionScore >= 1 OR InstanceCount > 3 OR DeleteType="BulkDelete"
| sort - _time Detects cloud instance deletion events across AWS (via aws:cloudtrail) and Azure (via azure:monitor:activity) in Splunk. The query uses a suspicion scoring model: bulk deletions (>3 or >10 instances), root account usage, and production resource targeting increase the score. AWS TerminateInstances, DeleteInstance, and DeregisterInstance are covered alongside Azure VM delete operations. Results with SuspicionScore >= 1 or bulk deletes are surfaced for analyst review.
Data Sources
Required Sourcetypes
False Positives & Tuning
- Auto-scaling scale-in events where the cloud platform terminates instances to reduce capacity based on policy
- Infrastructure as Code (Terraform, Pulumi, CloudFormation) teardown operations during legitimate environment decommissioning
- DevOps CI/CD pipeline cleanup jobs that destroy ephemeral test or staging environments after pipeline completion
- Cloud cost optimization scripts (AWS Instance Scheduler, Azure DevTest Labs auto-shutdown) deleting idle instances on schedule
- Spot instance / preemptible VM reclamation by the cloud provider (appears as TerminateInstances from platform service roles)
Other platforms for T1578.003
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.
- Test 1AWS EC2 Instance Termination via CLI
Expected signal: AWS CloudTrail: EventName=TerminateInstances with RequestParameters containing instancesSet.items[].instanceId. UserIdentity will contain the caller's ARN, userAgent will show 'aws-cli', and sourceIPAddress will show the test machine's IP. ResponseElements will confirm state transition from 'running' to 'shutting-down'. Event appears in CloudTrail within 5-15 minutes.
- Test 2AWS Bulk EC2 Termination — Mass Deletion Pattern
Expected signal: AWS CloudTrail: Single TerminateInstances event with RequestParameters.instancesSet.items containing 5 instance IDs. The bulk nature triggers the high-count hunting query. UserIdentity, sourceIPAddress, and awsRegion fields present. The SPL query InstanceCount field will show 5, triggering BulkDelete classification and elevated SuspicionScore.
- Test 3Azure VM Deletion via Azure CLI
Expected signal: Azure Activity Log: OperationNameValue=Microsoft.Compute/virtualMachines/delete, ActivityStatusValue=Accepted then Succeeded (two events). Caller field contains the authenticated user's UPN or service principal ID. ResourceId contains the full VM resource path. Events appear in Azure Monitor Activity Log within 1-5 minutes and flow to Log Analytics/Sentinel within 5-15 minutes.
- Test 4AWS Bypass Termination Protection Then Terminate
Expected signal: AWS CloudTrail Event 1: EventName=ModifyInstanceAttribute with RequestParameters.attribute=disableApiTermination and RequestParameters.value=false. AWS CloudTrail Event 2: EventName=TerminateInstances with the same instance ID and caller identity. Both events share the same UserIdentityArn and sourceIPAddress. The sequence within minutes is the high-fidelity indicator. A correlation rule matching ModifyInstanceAttribute(disableApiTermination=false) followed by TerminateInstances from the same ARN within 10 minutes should fire at Critical severity.
References (10)
- https://attack.mitre.org/techniques/T1578/003/
- https://aws.amazon.com/premiumsupport/knowledge-center/cloudtrail-search-api-calls/
- https://cloud.google.com/logging/docs/audit#admin-activity
- https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/view-activity-logs
- https://www.mandiant.com/sites/default/files/2021-09/mtrends-2020.pdf
- https://www.microsoft.com/en-us/security/blog/2022/03/22/dev-0537-criminal-actor-targeting-organizations-for-data-exfiltration-and-destruction/
- https://www.microsoft.com/en-us/security/blog/2025/08/01/storm-0501-ransomware-attacks-expanding-to-cloud-environments/
- https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingDisableAPITermination
- https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/lock-resources
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1578.003/T1578.003.md
Unlock Pro Content
Get the full detection package for T1578.003 including response playbook, investigation guide, and atomic red team tests.