Playbooks
T1525, T1526, T1078, T1530Cloud Incident Response
How incident response differs in cloud environments — IAM pivoting, data exfiltration via cloud storage, log sources that replace on-prem artifacts, cloud-native detection queries, and the playbook adjustments analysts need.
View on Graph
How Cloud IR Differs from On-Prem
- Cloud incident response operates under fundamentally different assumptions than traditional on-prem IR.
- MITRE ATT&CK maps cloud reconnaissance to
T1526(Cloud Service Discovery) andT1525(Implant Internal Image), since attackers who compromise the identity plane can also plant backdoored AMIs and container images for persistence. - Key differences: (1) No physical access — you cannot unplug a cable. Containment is API-driven (revoke IAM keys, modify security groups, apply SCPs). (2) Shared responsibility: the cloud provider secures the infrastructure; you secure your data, identities, and configurations. (3) Logs are API-driven — every action in the cloud generates an API event, which is both a blessing (complete audit trail) and a challenge (volume).
Cloud-Native Log Sources
AWS
| Log Source | What It Captures | Retention | Critical Events |
|---|---|---|---|
| CloudTrail | Every API call in the account | Configurable (default 90 days) | ConsoleLogin, CreateAccessKey, AttachRolePolicy, PutBucketPolicy, ModifySnapshotAttribute, AuthorizeSecurityGroupIngress |
| VPC Flow Logs | IP traffic metadata (src/dst IP, port, protocol, packets) | Configurable | All traffic — baseline for anomaly detection |
| GuardDuty | Managed threat detection | Same as alert retention | Credential compromise, EC2 malware, S3 exfiltration, crypto mining |
| S3 Access Logs | Object-level access requests | Configurable | GetObject from unusual IPs, bulk ListBucket |
| CloudWatch Logs | Application and system logs | Configurable | OS-level events, application errors |
Azure
| Log Source | What It Captures | Critical Events |
|---|---|---|
| Azure Activity Log | Control plane operations (subscription-level) | Create Role Assignment, Update Key Vault, Delete Diagnostic Setting |
| Azure AD Sign-in Logs | User authentication attempts | Impossible travel, anonymous IP, unfamiliar device, MFA denied |
| Azure AD Audit Logs | Directory configuration changes | Privileged role assignment, application registration, conditional policy changes |
| NSG Flow Logs | Network traffic metadata | Traffic to/from Azure resources |
GCP
| Log Source | What It Captures | Critical Events |
|---|---|---|
| Cloud Audit Logs | Admin activity, data access, system events | SetIamPolicy, storage.objects.create, compute.instances.create |
| VPC Flow Logs | Network traffic metadata | Anomalous outbound connections |
Detection Queries by Attack Scenario
Scenario 1: AWS IAM Privilege Escalation
Attackers who compromise an IAM user will attempt to escalate privileges by attaching policies, creating admin users, or modifying trust relationships.
SPL query — detect privilege escalation via IAM changes (run in Splunk):
index=cloudtrail eventSource="iam.amazonaws.com"
| search eventName IN ("AttachRolePolicy", "AttachUserPolicy", "PutUserPolicy", "CreatePolicy", "UpdateAssumeRolePolicy", "CreateUser", "CreateAccessKey")
| stats count, values(sourceIPAddress) as SourceIPs, values(userIdentity.arn) as UserARN by eventName, requestParameters.policyArn
| eval severity = if(eventName="AttachRolePolicy" OR eventName="PutUserPolicy", "HIGH — policy attachment", "MEDIUM — IAM configuration change")
| table _time, eventName, UserARN, SourceIPs, requestParameters.policyArn, severity
KQL query (Azure Sentinel) — detect Azure RBAC escalation (see the KQL guide):
AzureActivity
| where OperationName in ("Create Role Assignment", "Update Role Assignment", "Delete Role Assignment")
| where ActivityStatus == "Succeeded"
| extend Role = tostring(Properties.role)
| extend Principal = tostring(Properties.principalDisplayName)
| where Role contains "Owner" or Role contains "Contributor" or Role contains "Admin"
| project TimeGenerated, Caller, Principal, Role, OperationName
Scenario 2: Data Exfiltration via Cloud Storage
SPL query — detect large S3 object retrievals (compatible with Elastic Security EQL):
index=cloudtrail eventSource="s3.amazonaws.com"
| search eventName="GetObject"
| stats sum(eventParameters.responseElements.bytesTransferred) as totalBytes by sourceIPAddress, userIdentity.arn, requestParameters.bucketName
| where totalBytes > 50000000
| eval alert = "HIGH — user " . userIdentity.arn . " downloaded " . round(totalBytes/1048576, 2) . "MB from " . requestParameters.bucketName
| table _time, sourceIPAddress, userIdentity.arn, requestParameters.bucketName, totalBytes, alert
SPL query — detect public bucket exposure changes:
index=cloudtrail eventSource="s3.amazonaws.com"
| search eventName IN ("PutBucketAcl", "PutBucketPolicy")
| search requestParameters.AccessControlPolicy.AccessControlList.Grant.Grantee.URI="*acs.amazonaws.com/groups/global/AllUsers*" OR requestParameters.Policy="*Principal\":\"*\"*"
| eval alert = "CRITICAL — bucket made public by " . userIdentity.arn . " on " . requestParameters.bucketName
| table _time, userIdentity.arn, sourceIPAddress, requestParameters.bucketName, alert
Scenario 3: Cloud Credential Compromise
SPL query — detect console login from unusual location (impossible travel):
index=cloudtrail eventName="ConsoleLogin"
| search responseElements.ConsoleLogin="Success"
| iplocation sourceIPAddress
| eval login_hour = strftime(_time, "%H")
| stats count, values(sourceIPAddress) as IPs, values(userIdentity.arn) as Users by Country, City
| where Country!="US" AND Country!=""
| eval alert = "HIGH — cloud console login from " . Country . " — possible credential compromise"
| table _time, Users, IPs, Country, City, alert
KQL query (Azure Sentinel) — detect Azure MFA push denial flood:
SigninLogs
| where ResultType == "500121" // MFA denied
| summarize DenialCount = count() by UserPrincipalName, IPAddress, AppDisplayName, bin(TimeGenerated, 5m)
| where DenialCount > 10
| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, DenialCount
| sort by DenialCount desc
Scenario 4: Cloud Resource Hijacking (Crypto Mining)
SPL query — detect EC2 instance creation from unusual IAM roles:
index=cloudtrail eventSource="ec2.amazonaws.com"
| search eventName="RunInstances"
| stats count, values(requestParameters.instanceType) as InstanceTypes, values(sourceIPAddress) as SourceIPs by userIdentity.arn
| where count > 5
| eval alert = "HIGH — multiple instances launched by " . userIdentity.arn . " — possible resource hijacking"
| table _time, userIdentity.arn, count, InstanceTypes, alert
Containment in the Cloud — API-Driven Actions
AWS Containment Actions
| Action | Command | Use Case |
|---|---|---|
| Revoke IAM credentials | aws iam update-access-key --access-key-id AKIA... --status Inactive | Compromised user key |
| Detach IAM policy | aws iam detach-user-policy --user-name jdoe --policy-arn arn:aws:iam::... | Privilege escalation prevention |
| Deny all access via SCP | Create SCP with Deny * effect for the compromised account/OU | Widespread compromise |
| Isolate EC2 instance | Modify security group to deny all ingress/egress | Compromised EC2 |
| Disable access key | aws iam update-access-key --access-key-id AKIA... --status Inactive | API key compromise |
Azure Containment Actions
| Action | Command | Use Case |
|---|---|---|
| Disable user | Disable in Azure AD | Compromised user account |
| Revoke sessions | Revoke-AzureADUserAllRefreshToken | Active session hijack |
| Detach role | Remove role assignment | Privilege escalation |
| Block resource | Create NSG deny rule | Compromised VM |
| Remove app consent | Revoke OAuth grant | OAuth application abuse |
GCP Containment Actions
| Action | Command | Use Case |
|---|---|---|
| Revoke IAM | gcloud projects remove-iam-policy-binding | Compromised service account |
| Disable service account | gcloud iam service-accounts disable | API key compromise |
| Remove from organization | Move project to separate folder with restrictive org policy | Widespread compromise |
Cloud IR Decision Tree
Cloud incident detected
│
├─ What type of cloud resource is compromised?
│ ├─ IAM user/service account → Revoke credentials, check CloudTrail for API calls
│ ├─ Compute (EC2/VM/Compute Engine) → Isolate, capture snapshot, check for persistence
│ ├─ Storage (S3/Blob/GCS) → Lock down access, review access logs for data theft
│ └─ Container/orchestration (EKS/AKS/GKE) → Capture pod logs, check RBAC configuration
│
├─ Is the management plane compromised?
│ ├─ Yes → Assume all resources in the account are at risk. Apply organization-level SCPs.
│ └─ No → Isolate the specific resource. Proceed with single-account investigation.
│
├─ What is the blast radius?
│ ├─ Single resource → Targeted. Investigate access source. Rotate credentials.
│ └─ Multiple resources across services → Automated (likely crypto mining or data exfiltration bot). Apply broad containment.
│
└─ Post-incident: Review root cause
├─ Was it a leaked API key? → Rotate all keys. Enable key rotation policies.
├─ Was it a misconfigured bucket? → Apply organization-wide bucket policies. Enable S3 Block Public Access.
├─ Was it a compromised admin credential? → Review identity provider. Enable MFA for all users.
└─ Was it an exploited CVE? → Patch, update, or replace affected service.
Related
- Cloud Security Fundamentals — detection and response for T1525 techniques
- Cloud Threats — Credential Theft, IMDS Abuse, Hijacking, Privilege Escalation — detection and response for T1525, T1552, T1613 techniques
- Privilege Escalation Investigation — detection and response for T1068 techniques
- Suspicious Authentication — detection and response for T1078 techniques
- MITRE ATT&CK for Triage — covers the mitre att&ck for triage concepts
