关于 investigating-aws-incidents
面向事件响应人员的 AWS 入侵调查技能,利用 CloudTrail、VPC Flow Logs 等证据还原事件。重点是定位受影响主体、重建活动时间线,并在遏制前保全证据。
主要功能
- 01定位主体与凭证
- 02关联 CloudTrail 事件
- 03检查 IAM 持久化
- 04分析 GuardDuty 发现
- 05排查 S3 与快照外传
适用场景
- 01调查泄露的 AWS 访问密钥
- 02追踪异常 API 调用或 GuardDuty 警报
- 03检查疑似 IAM 持久化
- 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,了解来源角色。 |
AWSService | AWS 服务正在执行操作 | 通常无害,但要检查是否有看似伪造的服务调用。 |
Root | 根账户 | API 调用几乎不可能是合法的。按严重事件处理。 |
FederatedUser / WebIdentityUser | GetFederationToken 代理 / 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 TTPattacking-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