# Performing Cloud Forensics Investigation

> 通过收集和分析来自 AWS、Azure 和 GCP 服务的日志、快照和元数据，在云环境中开展取证调查。

- Skill: `killvxk/performing-cloud-forensics-investigation` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/performing-cloud-forensics-investigation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/performing-cloud-forensics-investigation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/performing-cloud-forensics-investigation

---


# 执行云取证调查

## 适用场景
- 调查 AWS、Azure 或 GCP 云环境中的安全漏洞时
- 从云基础设施收集易失性和非易失性证据时
- 通过云服务 API 日志追踪未授权访问时
- 在需要保全云端证据的事件响应期间
- 分析被入侵的虚拟机、容器或无服务器函数时

## 前置条件
- 对调查中的云账户具有管理员访问权限
- 配置了适当权限的 AWS CLI、Azure CLI 或 gcloud CLI
- 了解云原生日志（CloudTrail、Activity Log、Audit Log）
- 安装了云 SDK 的取证工作站
- 了解目标云中的 IAM、网络和计算服务
- 适用于云环境的证据保全程序

## 工作流程

### 步骤 1：保全云端证据并确定范围

```bash
# === AWS 证据保全 ===
# 对被入侵的 EC2 实例卷创建快照
INSTANCE_ID="i-0abc123def456789"
VOLUME_IDS=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID \
   --query 'Reservations[].Instances[].BlockDeviceMappings[].Ebs.VolumeId' --output text)

for vol in $VOLUME_IDS; do
   aws ec2 create-snapshot --volume-id $vol \
      --description "Forensic snapshot - Case 2024-001 - $(date -u)" \
      --tag-specifications "ResourceType=snapshot,Tags=[{Key=Case,Value=2024-001},{Key=Evidence,Value=true}]"
done

# 捕获实例元数据
aws ec2 describe-instances --instance-ids $INSTANCE_ID \
   > /cases/case-2024-001/cloud/instance_metadata.json

# 捕获安全组规则
aws ec2 describe-security-groups --group-ids $(aws ec2 describe-instances \
   --instance-ids $INSTANCE_ID --query 'Reservations[].Instances[].SecurityGroups[].GroupId' --output text) \
   > /cases/case-2024-001/cloud/security_groups.json

# 捕获网络接口
aws ec2 describe-network-interfaces --filters "Name=attachment.instance-id,Values=$INSTANCE_ID" \
   > /cases/case-2024-001/cloud/network_interfaces.json

# 隔离实例（将安全组替换为取证隔离安全组）
aws ec2 modify-instance-attribute --instance-id $INSTANCE_ID \
   --groups sg-forensic-isolation

# === Azure 证据保全 ===
# 对被入侵的 VM 磁盘创建快照
az snapshot create --resource-group forensics-rg \
   --name "case-2024-001-osdisk-snapshot" \
   --source "/subscriptions/SUB_ID/resourceGroups/RG/providers/Microsoft.Compute/disks/vm-osdisk"

# === GCP 证据保全 ===
gcloud compute disks snapshot compromised-disk \
   --snapshot-names="case-2024-001-forensic" \
   --zone=us-central1-a
```

### 步骤 2：收集云 API 和访问日志

```bash
# === AWS CloudTrail 日志 ===
# 下载调查期间的 CloudTrail 事件
aws cloudtrail lookup-events \
   --start-time "2024-01-15T00:00:00Z" \
   --end-time "2024-01-20T23:59:59Z" \
   --max-results 1000 \
   > /cases/case-2024-001/cloud/cloudtrail_events.json

# 过滤特定用户活动
aws cloudtrail lookup-events \
   --lookup-attributes AttributeKey=Username,AttributeValue=compromised-user \
   --start-time "2024-01-15T00:00:00Z" \
   > /cases/case-2024-001/cloud/user_activity.json

# 下载 S3 访问日志
aws s3 sync s3://my-cloudtrail-bucket/AWSLogs/ /cases/case-2024-001/cloud/cloudtrail_s3/

# 使用 Athena 对 CloudTrail 进行大规模查询分析
aws athena start-query-execution \
   --query-string "SELECT eventTime, eventName, userIdentity.arn, sourceIPAddress, errorCode
                   FROM cloudtrail_logs
                   WHERE eventTime BETWEEN '2024-01-15' AND '2024-01-20'
                   AND sourceIPAddress NOT IN ('10.0.0.0/8')
                   ORDER BY eventTime" \
   --result-configuration OutputLocation=s3://forensics-bucket/athena-results/

# === AWS VPC Flow Logs ===
aws logs filter-log-events \
   --log-group-name "vpc-flow-logs" \
   --start-time $(date -d "2024-01-15" +%s000) \
   --end-time $(date -d "2024-01-20" +%s000) \
   --filter-pattern "ACCEPT" \
   > /cases/case-2024-001/cloud/vpc_flow_logs.json

# === Azure Activity Log ===
az monitor activity-log list \
   --start-time "2024-01-15T00:00:00Z" \
   --end-time "2024-01-20T23:59:59Z" \
   --output json > /cases/case-2024-001/cloud/azure_activity.json

# === GCP Audit Logs ===
gcloud logging read 'logName="projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Factivity"
   AND timestamp>="2024-01-15T00:00:00Z"
   AND timestamp<="2024-01-20T23:59:59Z"' \
   --format=json > /cases/case-2024-001/cloud/gcp_audit.json
```

### 步骤 3：分析 IAM 和访问模式

```bash
# 分析被入侵凭据的使用情况
python3 << 'PYEOF'
import json
from collections import defaultdict

with open('/cases/case-2024-001/cloud/cloudtrail_events.json') as f:
    data = json.load(f)

# 按来源 IP 分析
ip_events = defaultdict(list)
error_events = []
critical_actions = []

for event in data.get('Events', []):
    ct = json.loads(event.get('CloudTrailEvent', '{}'))
    source_ip = ct.get('sourceIPAddress', 'Unknown')
    event_name = ct.get('eventName', 'Unknown')
    user_arn = ct.get('userIdentity', {}).get('arn', 'Unknown')
    error = ct.get('errorCode')
    timestamp = ct.get('eventTime', '')

    ip_events[source_ip].append(event_name)

    if error:
        error_events.append({'time': timestamp, 'action': event_name, 'error': error, 'ip': source_ip})

    # 标记关键操作
    critical = ['CreateUser', 'CreateAccessKey', 'AttachUserPolicy', 'CreateRole',
                'PutBucketPolicy', 'StopLogging', 'DeleteTrail', 'CreateKeyPair',
                'RunInstances', 'AuthorizeSecurityGroupIngress']
    if event_name in critical:
        critical_actions.append({'time': timestamp, 'action': event_name, 'user': user_arn, 'ip': source_ip})

print("=== 来源 IP 分析 ===")
for ip, events in sorted(ip_events.items(), key=lambda x: len(x[1]), reverse=True):
    print(f"  {ip}: {len(events)} 个事件（{len(set(events))} 个唯一操作）")

print(f"\n=== 访问错误（共 {len(error_events)} 个）===")
for e in error_events[:10]:
    print(f"  [{e['time']}] {e['action']} -> {e['error']} 来自 {e['ip']}")

print(f"\n=== 关键操作（共 {len(critical_actions)} 个）===")
for a in critical_actions:
    print(f"  [{a['time']}] {a['action']} 由 {a['user']} 从 {a['ip']} 执行")
PYEOF
```

### 步骤 4：获取并分析虚拟机磁盘镜像

```bash
# 从快照创建取证分析实例
SNAPSHOT_ID="snap-0abc123def456789"

# 在隔离的取证 VPC 中从快照创建卷
FORENSIC_VOL=$(aws ec2 create-volume --snapshot-id $SNAPSHOT_ID \
   --availability-zone us-east-1a \
   --tag-specifications "ResourceType=volume,Tags=[{Key=Case,Value=2024-001}]" \
   --query 'VolumeId' --output text)

# 附加到取证分析实例（只读挂载）
aws ec2 attach-volume --volume-id $FORENSIC_VOL \
   --instance-id i-forensic-workstation \
   --device /dev/xvdf

# 在取证实例上只读挂载
sudo mount -o ro /dev/xvdf1 /mnt/evidence

# 对挂载的卷执行标准磁盘取证
# 提取日志、分析文件系统、检查持久化机制
ls /mnt/evidence/var/log/
cp -r /mnt/evidence/var/log/ /cases/case-2024-001/cloud/vm_logs/
cp -r /mnt/evidence/etc/crontab /cases/case-2024-001/cloud/persistence/
cp -r /mnt/evidence/home/*/.ssh/ /cases/case-2024-001/cloud/ssh_keys/
cp -r /mnt/evidence/home/*/.bash_history /cases/case-2024-001/cloud/bash_history/
```

### 步骤 5：生成云取证报告

```bash
# 将调查结果整理为结构化报告
python3 << 'PYEOF'
report = """
云取证调查报告
======================================
案例：2024-001
云服务商：AWS（账户：123456789012）
区域：us-east-1
调查期间：2024-01-15 至 2024-01-20

已保全证据：
- EC2 实例快照：snap-0abc123def456789（i-0abc123def456789）
- CloudTrail 日志：2024-01-15 至 2024-01-20
- VPC Flow Logs：2024-01-15 至 2024-01-20
- 实例元数据：已捕获并哈希
- 安全组配置：已在隔离时捕获

调查发现：
1. 初始访问：
   - 被入侵的 IAM 访问密钥 AKIA... 从 IP 203.0.113.45 使用
   - 首次未授权 API 调用：2024-01-15 14:32:00 UTC
   - IP 地理位置：境外（非公司 IP 段）

2. 持久化：
   - 新建 IAM 用户 'backup-admin' 并授予 AdministratorAccess
   - 为 backup-admin 生成新访问密钥对
   - EC2 实例 authorized_keys 中添加了 SSH 密钥

3. 横向移动：
   - S3 存储桶策略修改为允许公开访问
   - 安全组规则修改为允许来自 0.0.0.0/0 的 SSH
   - 新启动 3 个 EC2 实例用于加密货币挖矿

4. 数据外泄：
   - S3 存储桶 'company-confidential' 被访问 234 次
   - 通过 GetObject API 调用下载了 12 GB 数据
   - 数据被传输至外部 IP 185.x.x.x

5. 反取证：
   - CloudTrail 日志记录于 2024-01-18 03:00 UTC 被禁用
   - CloudWatch 日志组被删除

修复建议：
- 立即轮换所有 IAM 凭据
- 为所有账户启用 MFA
- 恢复 CloudTrail 日志记录
- 审查并限制 S3 存储桶策略
- 实施 GuardDuty 进行持续监控
"""

with open('/cases/case-2024-001/cloud/cloud_forensics_report.txt', 'w') as f:
    f.write(report)
print(report)
PYEOF
```

## 关键概念

| 概念 | 描述 |
|------|------|
| 云 API 日志 | 记录所有 API 调用的服务日志（CloudTrail、Activity Log、Audit Log） |
| 卷快照（Volume snapshots） | 用于取证保全的云磁盘卷时间点副本 |
| VPC Flow Logs | 显示来源、目标和操作的网络流量元数据日志 |
| IAM 凭据泄露 | 未授权使用访问密钥、令牌或角色扮演 |
| 实例元数据（Instance metadata） | EC2/VM 配置数据，包括网络、存储和安全设置 |
| 共享责任（Shared responsibility） | 云服务商负责基础设施安全；客户负责数据和访问安全 |
| 证据易失性（Evidence volatility） | 云资源可能被终止；证据必须快速保全 |
| 多区域制品 | 攻击可能跨区域，需要跨区域日志收集 |

## 工具与系统

| 工具 | 用途 |
|------|------|
| AWS CLI | 用于 AWS 服务交互和日志收集的命令行界面 |
| CloudTrail | 用于调查和审计的 AWS API 调用日志服务 |
| Azure Monitor | Azure 日志记录和诊断平台 |
| GCP Cloud Logging | Google Cloud 审计和访问日志服务 |
| Athena | 用于大规模分析 CloudTrail 日志的 AWS 无服务器 SQL 查询服务 |
| Prowler | 开源 AWS 安全评估和取证收集工具 |
| ScoutSuite | 多云安全审计工具 |
| CADO Response | 云原生数字取证和事件响应平台 |

## 常见场景

**场景 1：IAM 访问密钥被入侵**
在 CloudTrail 中识别被入侵的密钥，追踪用该密钥发起的所有 API 调用，确定来源 IP 和执行的操作，检查持久化机制（新用户、角色、密钥），吊销被入侵凭据，评估数据访问范围。

**场景 2：EC2 实例加密货币挖矿（Cryptojacking）**
在 CloudTrail 中检测未授权的实例启动，对挖矿实例创建快照进行分析，检查允许 C2 通信的安全组变更，识别初始访问向量（密钥盗取、SSRF），计算产生的资源费用。

**场景 3：S3 数据泄露**
分析 S3 访问日志和 CloudTrail 中的 GetObject/PutBucketPolicy 事件，识别谁修改了存储桶策略允许公开访问，确定数据暴露范围，检查来自未授权 IP 的数据下载，评估合规报告要求。

**场景 4：EKS/AKS/GKE 容器逃逸**
收集 Kubernetes 审计日志和云服务商日志，分析 Pod 创建事件中的权限提升尝试，检查节点级日志中的容器逃逸证据，检测对云元数据服务（169.254.169.254）的未授权访问，追踪横向移动至云 API。

## 输出格式

```
云取证摘要：
  云服务商：AWS（us-east-1）账户：123456789012
  调查期间：2024-01-15 至 2024-01-20
  事件类型：IAM 凭据泄露 + 数据外泄

  已收集证据：
    EBS 快照：        3 个卷已保全
    CloudTrail 事件：  12,456 条（攻击者 IP 发起 1,234 条）
    VPC Flow Logs：    45,678 条记录
    S3 访问日志：      2,345 条记录

  攻击时间线：
    2024-01-15 14:32 - 被入侵访问密钥首次从 203.0.113.45 使用
    2024-01-15 14:45 - 创建具有管理员权限的新 IAM 用户
    2024-01-16 02:00 - S3 存储桶策略被修改（启用公开访问）
    2024-01-16 03:00 - 从 company-confidential 存储桶下载 12 GB
    2024-01-18 03:00 - CloudTrail 日志记录被禁用

  影响评估：
    数据暴露：来自 3 个 S3 存储桶的 12 GB
    创建资源：3 个 EC2 实例（加密货币挖矿）
    估计费用：未授权计算费用 $4,500
```

