mcpField
I
investigating-aws-incidents

investigating-aws-incidents

github.com/trilwu安全17749 次安装12 周前更新
代码仓库

关于 investigating-aws-incidents

面向事件响应人员的 AWS 入侵调查技能,利用 CloudTrail、VPC Flow Logs 等证据还原事件。重点是定位受影响主体、重建活动时间线,并在遏制前保全证据。

主要功能

  1. 01定位主体与凭证
  2. 02关联 CloudTrail 事件
  3. 03检查 IAM 持久化
  4. 04分析 GuardDuty 发现
  5. 05排查 S3 与快照外传

适用场景

  1. 01调查泄露的 AWS 访问密钥
  2. 02追踪异常 API 调用或 GuardDuty 警报
  3. 03检查疑似 IAM 持久化
  4. 04评估 S3 或快照数据失窃

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/trilwu/secskills --skill investigating-aws-incidents

安装后在 Claude Code 中输入/investigating-aws-incidents确认已加载。

详细介绍

调查 AWS 事件

在 AWS 中,事件通常通过攻击者无法删除的日志进行重建——CloudTrail、VPC Flow Logs,以及控制平面对每次 API 调用的记录。因此,调查就是围绕遭到入侵的主体开展日志关联:访问密钥或代入的角色,以及它发起的 API 调用序列。找到该主体,提取它生成的所有事件,入侵的其他情况便会从时间线中显现出来。

适用场景

  • AWS 访问密钥暴露或泄漏——提交到了代码仓库、出现在 pastebin 中,或被 AWS abuse 标记
  • CloudTrail 活动异常——来自陌生区域、IP 或用户代理的 API 调用
  • GuardDuty 发现——凭证外传、Tor 流量、加密货币挖矿或异常 IAM 行为
  • IAM 变更异常——出现未经授权的新用户、密钥、角色、登录配置文件或策略附加
  • EC2 加密货币挖矿——按需实例、GPU 系列用量激增,或出现意外的账单提醒
  • S3 数据外传——GetObject 调用激增、存储桶被设为公开,或快照被共享

不适用场景

  • 事件发生在 Microsoft 365 / Entra ID,而非 AWS——使用 investigating-m365-entra
  • 事件涉及 Azure 资源/订阅——使用 investigating-azure-incidents
  • 事件发生在 Google Cloud——使用 investigating-gcp-incidents
  • 一般的 IR 流程和主机级响应——使用 responding-to-incidents
  • 你是攻击者,而非响应人员——使用 exploiting-cloud-platforms
  • 攻击目标明确转向 EKS 上的 Kubernetes——使用 attacking-eks-gke-aks
  • 尚未确认事件,只进行主动威胁搜寻——使用 hunting-threats

第一小时分诊

按顺序执行三项操作:识别主体、提取其近期活动、在遏制前保全证据。

确定遭入侵主体的范围。 无论报告涉及密钥泄漏、GuardDuty 发现还是账单激增,都要将其确定为单个主体 ARN——IAM 用户、角色或根账户。该 ARN 是后续所有工作的锚点。

# What is this key/session, and does it still work?
aws sts get-caller-identity                       # if you hold the suspect creds
# Resolve an access key ID to its owner
aws iam get-access-key-last-used --access-key-id AKIA...
# Enumerate the principal's current footprint
aws iam list-access-keys --user-name <user>
aws iam list-attached-user-policies --user-name <user>
aws iam list-user-policies --user-name <user>

提取主体的近期活动。 事件历史记录(见下文)是最快的初步检查方式;S3 日志存储桶才是事实来源。

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=Username,AttributeValue=<user> \
  --start-time 2026-07-01T00:00:00Z --max-results 200

# By access key -- catches role sessions that lookup-by-username misses
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIA...

在不惊动攻击者的情况下隔离——先创建快照,再进行遏制。 如果攻击者发现自己的密钥在操作过程中被停用,就会触发你尚未发现的持久化手段。除正在发生的持续损害外,应先保全证据(创建卷快照、导出日志),梳理持久化情况,然后一次性遏制所有威胁。如果损害正在发生——例如正在进行挖矿或数据外传——就立即停止损害,并接受由此带来的代价。

CloudTrail 深入分析

事件历史与 S3 日志存储桶。 控制台中的事件历史可供搜索,但只涵盖 90 天内的管理事件,且不会记录数据事件。CloudTrail S3 日志存储桶(或 CloudTrail Lake)才是权威记录,也是唯一包含 S3/Lambda 数据事件的地方——初步检查之后,请查询这里,而不是控制台。确认实际记录了哪些内容:

aws cloudtrail describe-trails
aws cloudtrail get-trail-status --name <trail>          # IsLogging: true?
aws cloudtrail get-event-selectors --trail-name <trail> # data events on?

userIdentity 类型能告诉你正在查看的内容:

type含义调查提示
IAMUser长期用户凭证accessKeyId 是追踪切入点。是人类用户还是服务账户?
AssumedRole临时 STS 凭证查看 sessionContext.sessionIssuer,了解来源角色。
AWSServiceAWS 服务正在执行操作通常无害,但要检查是否有看似伪造的服务调用。
Root根账户API 调用几乎不可能是合法的。按严重事件处理。
FederatedUser / WebIdentityUserGetFederationToken 代理 / OIDC Web 身份追踪至代理的 IAM 用户,或 IdP 会话。

对于 AssumedRole,sessionContext.sessionIssuer.arn 会标明角色,而 sessionContext.attributes.mfaAuthenticated 会告诉你是否使用了 MFA。

建议搜索的异常字段:

  • sourceIPAddress —— 本应仅在 VPC 内运行的角色凭证,却出现外部 IP(下文介绍的 IMDS 窃取特征)。与 VPC Flow Logs 进行关联分析。
  • userAgent —— 对于通常显示控制台或来自 Lambda 的 SDK 客户端的主体,如果出现 aws-cli/2.x、Boto3、python-requests,或任何包含 kali 的内容,都值得关注。
  • awsRegion —— 在你未开展业务的区域发起调用(攻击者会在 ap-* / sa-* 区域启动挖矿,以避人耳目)。枚举操作会在短时间内触及许多区域。
  • errorCode —— 大量出现 AccessDenied / UnauthorizedOperation,表明正在进行枚举:攻击者在摸清被盗主体可以执行哪些操作。
-- Athena over the CloudTrail S3 bucket: AccessDenied enumeration storm
SELECT eventname, count(*) AS n
FROM cloudtrail_logs
WHERE useridentity.accesskeyid = 'AKIA...'
  AND errorcode = 'AccessDenied'
  AND eventtime > '2026-07-01T00:00:00Z'
GROUP BY eventname ORDER BY n DESC;

攻击者常见 API 模式

在时间线上搜索以下操作序列。几乎所有使用被盗密钥的入侵都呈现这种模式:

  • GetCallerIdentity —— 通常是首次调用。攻击者借此确认密钥对应的身份以及账户所有者。
  • 枚举 —— 在 IAM、S3、EC2、RDS、Secrets Manager 中执行 List* / Get* / Describe*,通常伴随大量 AccessDenied。
  • 权限提升 —— CreateUser、CreateAccessKey、AttachUserPolicy(留意 AdministratorAccess)、PutUserPolicy(使用内联策略,使其不会显示在附加策略列表中)、CreateLoginProfile(为仅限 API 的账户设置控制台密码)、UpdateLoginProfile。
  • 滥用 iam:PassRole —— 将高权限角色传递给新的 EC2 实例、Lambda 或 Glue 作业,以继承其权限。留意与 RunInstances / CreateFunction 同时出现的 PassRole。
  • 篡改信任策略 —— 使用 UpdateAssumeRolePolicy,或通过 CreateRole 创建信任策略中指定外部账户的角色(跨账户后门)。
  • STS 链式调用 —— 先通过 AssumeRole 切换到权限更高的角色,再切换到另一个角色,逐步构建链条,以掩盖最初被盗密钥的来源。
# Pull the IAM mutating calls for the window
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=CreateAccessKey
# Repeat for: CreateUser, AttachUserPolicy, PutUserPolicy, CreateLoginProfile,
#             UpdateAssumeRolePolicy, CreateRole, AssumeRole
# (iam:PassRole is a permission, not an event -- find it in requestParameters of
#  RunInstances / CreateFunction, not via lookup-by-EventName)

持久化排查

清除威胁时,明确枚举每种机制——轮换唯一泄露的密钥,无法处理攻击者创建的第二个密钥。

  • 在事件时间窗口内创建的新 IAM 用户 / 密钥 / 角色。
  • 现有用户的第二个访问密钥 —— 对受害账户或其他账户执行 CreateAccessKey;一个用户最多可以有两个密钥。
  • 服务账户上的控制台登录配置文件 —— 对从未使用过控制台的主体执行 CreateLoginProfile,是高度可疑的信号。
  • 已修改的角色信任策略 —— UpdateAssumeRolePolicy 添加外部主体,或允许来自其他账户的 sts:AssumeRole。
  • Lambda 后门 —— 新建或更新的函数用于生成凭证或重新创建用户,通常由 EventBridge 定时触发。
  • 定时调用攻击者 Lambda 的 EventBridge / CloudWatch Events 规则。
  • iam:CreateServiceLinkedRole 及其他权限不易察觉的角色。
# Users and keys created recently
aws iam list-users --query 'Users[?CreateDate>=`2026-07-01`].[UserName,CreateDate]'
for u in $(aws iam list-users --query 'Users[].UserName' --output text); do
  aws iam list-access-keys --user-name "$u" \
    --query 'AccessKeyMetadata[].[UserName,AccessKeyId,CreateDate]' --output text
done

# Roles whose trust policy names an external account
aws iam list-roles --query 'Roles[].[RoleName,AssumeRolePolicyDocument]'

# Recently modified Lambda and the EventBridge rules that fire them
aws lambda list-functions --query 'Functions[].[FunctionName,LastModified]'
aws events list-rules --query 'Rules[].[Name,ScheduleExpression,State]'

IMDS / SSRF 凭证窃取特征

经典的 AWS 权限提升方式:攻击者利用 SSRF 或在 EC2 实例上获得立足点,读取 实例元数据服务(http://169.254.169.254/latest/meta-data/iam/...), 窃取实例角色的临时凭证,再在其他地方使用这些凭证。

这种特征在 CloudTrail 中一目了然:实例角色的会话 凭证出现在一个并非该实例的 sourceIPAddress 中。 该角色是为实例 创建的,因此,任何来自外部或无关 IP 的调用都意味着凭证已离开该实例。

-- Role session creds used from outside the VPC
SELECT eventtime, eventname, sourceipaddress, useragent
FROM cloudtrail_logs
WHERE useridentity.arn LIKE '%assumed-role/<instance-role>%'
  AND sourceipaddress NOT LIKE '10.%'
  AND sourceipaddress NOT LIKE '172.%'
ORDER BY eventtime;

IMDSv1(简单的 GET 请求,无会话令牌)会让这一过程轻而易举,本身也是一个 调查发现——通过 aws ec2 describe-instances 确认实例是否强制使用 IMDSv2 (HttpTokens: required)。将凭证窃取时间段与 VPC Flow Logs 中的出站 SSRF 流量及凭证重用来源关联起来。

GuardDuty 调查发现分类

GuardDuty 是调查的发令枪,而非调查本身。每种调查发现类型都对应一个需要在 CloudTrail 中确认的假设:

调查发现类型含义
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.*实例角色凭证在实例之外被使用——即上述 IMDS 窃取。
UnauthorizedAccess:IAMUser/MaliciousIPCaller某个主体从已知恶意 IP 发起调用。
UnauthorizedAccess:IAMUser/TorIPCaller通过 Tor 发起 API 调用——几乎不可能是合法管理员。
CryptoCurrency:EC2/BitcoinTool.B!DNS某个实例正在与挖矿池通信——确认存在加密货币挖矿。
Recon:IAMUser/*枚举操作——AccessDenied 风暴。
Persistence:IAMUser/*、PrivilegeEscalation:IAMUser/*IAM 变更与上述权限提升模式相符。
Policy:S3/BucketAnonymousAccessGranted某个存储桶已设为公开访问——可能被用作数据外传中转点。
aws guardduty list-findings --detector-id <id> \
  --finding-criteria '{"Criterion":{"severity":{"Gte":4}}}'
aws guardduty get-findings --detector-id <id> --finding-ids <id>

即使 CloudTrail 窗口内已不存在较早的调查发现,它们仍会保留主体和 IP 信息—— 即使原始事件已从 Event history 中过期,也要据此继续追查。

数据窃取检测

  • S3 GetObject 激增——敏感存储桶上的 GetObject 数量或字节数骤增,只有在 记录 S3 数据事件时才能看到。按主体检查请求数。
  • 存储桶被设为公开——PutBucketPolicy / PutBucketAcl 授予 AllUsers 或 AuthenticatedUsers 访问权限,或者 PutPublicAccessBlock 禁用了 公共访问阻止功能。
  • 快照共享——ModifySnapshotAttribute 或 ModifyImageAttribute 将外部账户或 all 添加到卷或 AMI 中(通过对外共享快照窃取数据)。
  • RDS 数据外传——ModifyDBSnapshotAttribute 共享数据库快照,或者 StartExportTask 将快照导出到攻击者控制的 S3 存储桶。
SELECT eventname, useridentity.arn, sourceipaddress,
       json_extract_scalar(requestparameters, '$.attributeType') AS attr
FROM cloudtrail_logs
WHERE eventname IN ('ModifySnapshotAttribute','ModifyImageAttribute',
                    'ModifyDBSnapshotAttribute','PutBucketPolicy','PutBucketAcl')
  AND eventtime > '2026-07-01T00:00:00Z';

攻击者尝试的反取证手段

能力较强的攻击者会试图蒙蔽你。留意以下操作,并且至关重要的是,采取措施应对:

  • StopLogging / DeleteTrail——关闭 CloudTrail。
  • PutEventSelectors——缩小跟踪记录范围(丢弃数据事件或整个区域的事件),但不删除跟踪。
  • DeleteFlowLogs——删除 VPC Flow Logs,以隐藏网络侧活动。
  • DeleteDetector / UpdateDetector(禁用)/ suspend——关闭 GuardDuty。

应对这些操作的办法是使用独立于成员账户的 Organizations 级跟踪,将日志写入受锁定保护的中央 S3 存储桶(MFA 删除、Object Lock、独立的日志存档账户),遭入侵的主体无法访问该存储桶。 StopLogging 本身的操作会在生效前记录到该处。如果你有组织级跟踪,攻击者的清理操作 就是证据,而不是监控盲区。如果没有,则应将盲区时间段记为范围界定方面的 限制。

# Was logging tampered with? These calls are the finding.
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=StopLogging
# Repeat: DeleteTrail, PutEventSelectors, DeleteFlowLogs, DeleteDetector

证据保全

  • 对所有涉事实例的卷创建 EBS 快照,并且必须在接触实例之前完成。使用案件 ID 添加标签,并应用资源策略/法律保全措施,确保快照无法被删除。

    aws ec2 create-snapshot --volume-id vol-xxx \
      --description "IR-2026-042 preserve" \
      --tag-specifications 'ResourceType=snapshot,Tags=[{Key=case,Value=IR-2026-042},{Key=legal-hold,Value=true}]'
    
  • 在运行中的实例上采集内存,并且必须在终止实例之前完成——对于驻留型植入程序或内存中的凭据,这是唯一的数据来源。采集后,按照 analyzing-memory-images 中的方法进行分析。

  • 将相关时间范围内的 CloudTrail 数据导出到保全位置,并在保留期限到期前复制 VPC Flow Logs 和所有 GuardDuty 调查结果。

  • 为所有证据材料添加标签并实施法律保全措施;如果事件可能演变为监管调查或诉讼事项,应在采集前联系法务。

遏制与清除

完成范围界定后,一次性执行所有操作。部分遏制会向攻击者发出警报。

  • 停用密钥,不要删除——删除会销毁证据;停用的密钥仍会显示在时间线中。

    aws iam update-access-key --user-name <user> \
      --access-key-id AKIA... --status Inactive
    
  • 撤销活动会话——停用密钥不会终止由该密钥生成、正在进行中的临时会话。附加内联拒绝策略,使现在之前签发的所有会话/令牌失效(AWSRevokeOlderSessions 模式):

    aws iam put-user-policy --user-name <user> \
      --policy-name AWSRevokeOlderSessions \
      --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Deny",
        "Action":"*","Resource":"*","Condition":{"DateLessThan":
        {"aws:TokenIssueTime":"2026-07-20T00:00:00Z"}}}]}'
    

    对于角色,可在角色的内联策略或权限边界中添加等效的拒绝策略。

  • 轮换该主体能够访问的所有凭据:其他密钥、该主体读取过的 Secrets Manager/SSM 中的机密,以及已失陷实例上的所有硬编码凭据。

  • 隔离安全组——将挖矿或数据外传实例移至无出站流量的安全组,而不是终止实例,以便保留内存和磁盘供分析。

  • 清除攻击者持久化机制——删除创建的用户/密钥/角色,恢复被篡改的信任策略,移除后门 Lambda 和 EventBridge 规则——但仅限已记录这些内容之后。

应予驳斥的自我安慰

  • “GuardDuty 没有发出警报,所以什么事都没发生。” GuardDuty 仅覆盖部分行为,并且必须在正确的区域启用。没有调查结果并不代表没有发生——CloudTrail 时间线才是权威依据。
  • “我们已经轮换泄露的密钥,所以事情结束了。” 泄露的密钥只是第一步。第二个密钥、新用户、修改过的信任策略或后门 Lambda 都不会因轮换密钥而消失。关闭事件前,必须逐一排查所有持久化机制。
  • “活动来自 AWS IP 段,所以是合法的。” 攻击者也会在 EC2 上运行工具。应关联分析主体、用户代理和行为——不能只看 IP 的归属方。
  • “CloudTrail 中没有 CreateUser,所以不存在持久化机制。” 内联策略(PutUserPolicy)、现有用户上的第二个访问密钥,以及修改过的角色信任策略,都能在不创建用户的情况下实现持久化。
  • “这只是加密货币挖矿,优先级不高。” 挖矿意味着拥有 RunInstances 权限的主体已遭入侵——相同权限也可能用于外传数据或提升权限。挖矿只是显而易见的症状,并非事件范围。
  • “实例角色权限很低,所以 SSRF 无关紧要。” 请核实这一点。iam:PassRole 和 AssumeRole 链接经常会将权限有限的实例角色转变为整个账户范围的访问权限。追踪该角色能够访问的资源,不要想当然。
  • “日志只保留 90 天,所以入侵始于最近 90 天内。” 这是你能看到的时间范围,不是攻击者的活动时间线。应将其记录为范围界定缺口,并检查组织跟踪或 Lake 是否有更长的保留期限。

参考资料

  • investigating-m365-entra -- 面向 M365 / Entra ID 事件的云端 IR 相关技能
  • responding-to-incidents -- 通用 IR 流程、证据处理和主机级响应
  • exploiting-cloud-platforms -- 攻击侧内容;介绍如何执行这些 AWS TTP
  • attacking-eks-gke-aks -- 当攻击路径具体转向 EKS 上的 Kubernetes 时
  • analyzing-memory-images -- 使用 Volatility 处理实例内存转储
  • hunting-threats -- 在尚未确认事件时进行主动威胁搜寻
  • reporting-security-findings -- 组织事件叙述和交付成果
  • AWS CLI、Athena 和 CloudTrail Lake -- 查询权威日志
  • cloudtrail-partitioner -- 为 CloudTrail S3 存储桶分区,以便快速执行 Athena 查询
  • Prowler -- 对账户进行回顾性安全态势和错误配置评估
  • stratus-red-team -- 模拟 AWS 攻击 TTP,了解每种攻击会在 CloudTrail 中留下哪些痕迹
  • AWS Security Incident Response Guide;GuardDuty finding-type reference

评论

支持 Markdown