<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 -->
<!-- NERF is a trademark of defconxt. -->
---
name: performing-cloud-incident-response
description: >-
  Performs incident response in AWS, Azure, and GCP cloud environments including
  CloudTrail analysis, IAM containment, snapshot-based forensics, and cloud-native
  evidence preservation.
domain: cybersecurity
subdomain: incident-response
tags:
  - cloud-ir
  - AWS
  - Azure
  - GCP
  - CloudTrail
  - IAM-containment
  - cloud-forensics
version: '1.0'
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1078.004"]
---

# Performing Cloud Incident Response

## Overview

Cloud incident response differs fundamentally from on-premises IR. There is no
physical access to hardware, evidence is ephemeral (instances can be terminated),
and the blast radius can span multiple regions and services. This skill covers
cloud-native evidence collection (CloudTrail, VPC Flow Logs, Azure Activity Log),
IAM-based containment (deny-all policies, key rotation), snapshot-based forensics,
and multi-cloud investigation techniques.

Key principle: in cloud IR, **contain via IAM first** — network isolation alone
is insufficient when API access bypasses network controls.

## Prerequisites

| Tool | Purpose | Install |
|------|---------|---------|
| AWS CLI | AWS investigation and containment | `pip install awscli` |
| az CLI | Azure investigation | `curl -sL https://aka.ms/InstallAzureCLIDeb \| bash` |
| gcloud CLI | GCP investigation | Google Cloud SDK |
| Prowler | AWS security assessment | `pip install prowler` |
| CloudQuery | Multi-cloud asset inventory | `brew install cloudquery` |
| Steampipe | Cloud SQL queries | `brew install steampipe` |

## Key Concepts

### Cloud Evidence Sources

| Source | Provider | Contains |
|--------|----------|----------|
| CloudTrail | AWS | API call history (management + data events) |
| VPC Flow Logs | AWS | Network connection metadata |
| GuardDuty | AWS | Threat detection findings |
| Azure Activity Log | Azure | Control plane operations |
| NSG Flow Logs | Azure | Network connection metadata |
| Cloud Audit Logs | GCP | Admin and data access logs |
| VPC Flow Logs | GCP | Network connection metadata |

### IAM Containment Strategy

```
1. Apply explicit DenyAll policy to compromised principal
2. Deactivate access keys (do NOT delete — preserve for investigation)
3. Invalidate active sessions (revoke temporary credentials)
4. Rotate credentials for affected service accounts
5. Review and revoke cross-account trust relationships
```

## Workflow

### Step 1 — Preserve Cloud Evidence

```bash
# AWS — Download CloudTrail events for the incident timeframe
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventSource,AttributeValue=iam.amazonaws.com \
  --start-time "2026-03-15T00:00:00Z" \
  --end-time "2026-03-17T23:59:59Z" \
  --output json > /evidence/cloudtrail_iam.json

# AWS — Copy CloudTrail logs to forensics bucket
aws s3 sync s3://company-cloudtrail-logs/AWSLogs/ \
  s3://forensics-evidence-bucket/INC-2026-0342/cloudtrail/ \
  --exclude "*" --include "*2026-03-1*"

# AWS — Enable VPC Flow Logs if not already active
aws ec2 create-flow-logs \
  --resource-type VPC --resource-ids vpc-0abc123 \
  --traffic-type ALL --log-destination-type s3 \
  --log-destination arn:aws:s3:::forensics-evidence-bucket/flowlogs
```

### Step 2 — Contain Compromised IAM Principal

```bash
# AWS — Apply DenyAll inline policy
aws iam put-user-policy --user-name compromised-user \
  --policy-name IncidentDenyAll \
  --policy-document '{
    "Version":"2012-10-17",
    "Statement":[{"Effect":"Deny","Action":"*","Resource":"*"}]
  }'

# AWS — Deactivate access keys
aws iam list-access-keys --user-name compromised-user --query 'AccessKeyMetadata[].AccessKeyId' | \
  jq -r '.[]' | while read key; do
    aws iam update-access-key --user-name compromised-user --access-key-id "$key" --status Inactive
  done

# AWS — Revoke active sessions for IAM role
aws iam put-role-policy --role-name compromised-role \
  --policy-name RevokeOlderSessions \
  --policy-document '{
    "Version":"2012-10-17",
    "Statement":[{
      "Effect":"Deny","Action":"*","Resource":"*",
      "Condition":{"DateLessThan":{"aws:TokenIssueTime":"2026-03-17T15:00:00Z"}}
    }]
  }'
```

### Step 3 — Snapshot-Based Forensics

```bash
# AWS — Snapshot compromised EC2 volumes
INSTANCE_ID="i-0abc123def456"
VOLUMES=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[].Instances[].BlockDeviceMappings[].Ebs.VolumeId' --output text)

for vol in $VOLUMES; do
  aws ec2 create-snapshot --volume-id "$vol" \
    --description "IR Evidence - INC-2026-0342" \
    --tag-specifications "ResourceType=snapshot,Tags=[{Key=Incident,Value=INC-2026-0342}]"
done

# AWS — Isolate instance with restrictive security group
aws ec2 create-security-group --group-name ir-isolate --description "IR Isolation" --vpc-id vpc-0abc
SG_ID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=ir-isolate --query 'SecurityGroups[0].GroupId' --output text)
aws ec2 modify-instance-attribute --instance-id "$INSTANCE_ID" --groups "$SG_ID"
```

### Step 4 — Investigate API Activity

```bash
# AWS — Find all actions by compromised identity
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=compromised-user \
  --start-time "2026-03-10T00:00:00Z" \
  --output json | jq '.Events[] | {time: .EventTime, name: .EventName, source: .EventSource}'

# AWS — Detect reconnaissance patterns
aws cloudtrail lookup-events \
  --start-time "2026-03-15T00:00:00Z" \
  --output json | jq '[.Events[].EventName] | group_by(.) | map({event: .[0], count: length}) | sort_by(-.count)[:20]'

# Azure — Query activity log
az monitor activity-log list \
  --start-time "2026-03-15T00:00:00Z" \
  --caller "compromised@company.com" \
  --output json > /evidence/azure_activity.json
```

### Step 5 — Assess Blast Radius

```bash
# AWS — List resources created by compromised principal
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=compromised-user \
  --output json | jq '.Events[] | select(.EventName | startswith("Create") or startswith("Run") or startswith("Put"))'

# AWS — Check for persistence mechanisms
aws iam list-attached-user-policies --user-name compromised-user
aws iam list-user-policies --user-name compromised-user
aws lambda list-functions --query 'Functions[?LastModified>=`2026-03-15`]'
```

## Detection

```yaml
title: Cloud Incident Response Detection
id: 0281d459-5792-4ac9-ae7c-ccc6c7e957fd
status: experimental
description: Detects suspicious activity related to performing cloud incident response techniques in incident response context
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    CommandLine: "*performing*cloud*"
  condition: selection
level: high
tags:
  - attack.t1078.004
  - attack.impact
falsepositives:
  - Incident response team running authorized forensic collection tools
```

## Verification

- [ ] CloudTrail / Activity Log events preserved to forensics bucket
- [ ] Compromised IAM principal contained with DenyAll policy
- [ ] Access keys deactivated (not deleted)
- [ ] Active sessions invalidated
- [ ] EBS snapshots created for affected instances
- [ ] Network isolation applied via security group changes
- [ ] Full API activity timeline reconstructed for compromised identity
- [ ] Blast radius assessment completed (created resources, data access)
- [ ] Persistence mechanisms identified and removed

## References

- AWS Security Incident Response Guide: https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide
- Azure Security Incident Response: https://learn.microsoft.com/en-us/security/operations/incident-response-overview
- MITRE ATT&CK Cloud Matrix: https://attack.mitre.org/matrices/enterprise/cloud/
- MITRE ATT&CK T1078.004 (Valid Accounts: Cloud Accounts)
- SANS Cloud Forensics Poster
