Abusing Roles/ClusterRoles in Kubernetes
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.
Belirli bir fiil ile Herhangi Bir Kaynağa Erişim
RBAC'de, bazı izinler önemli riskler oluşturur:
create
: Herhangi bir küme kaynağını oluşturma yetkisi verir ve ayrıcalık yükselmesine neden olabilir.list
: Tüm kaynakları listeleme izni verir ve hassas verilerin sızmasına neden olabilir.get
: Hizmet hesaplarından gizli bilgilere erişimi sağlar ve güvenlik tehdidi oluşturur.
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:
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
Aşağıdaki komutla pod oluşturun:
Bu tweet'ten bir satır ve bazı eklemelerle:
Ş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 PrivilegesDeployment, 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:
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:
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:
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:
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 vehttps://<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).
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:
hostPath readOnly korumasını atlatma
Bu araştırmada belirtildiği gibi, korumayı atlamak mümkündür:
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.
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:
Veya REST API'sini kullanın:
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.
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:
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):
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:
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/ephemeralcontainers
'ı gü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:
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.
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.
Yaml dosyanızı düzenleyin ve aşağıdaki satırları yorum işaretini kaldırarak ekleyin:
Proxy'nin günlüklerini görüntüleyin:
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:
Durumunu kontrol etmek için hazır olup olmadığını kontrol edin:
Ardından yeni bir pod dağıtın:
ErrImagePull
hatasını gördüğünüzde, görüntü adını aşağıdaki sorgulardan biriyle kontrol edin:
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:
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
Last updated