Slide 1

Slide 1 text

Z氏 Kubernetes クラスタを、 手中に収めることができた か OTSUKA, Motohiro / Yuanying

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

2018年12月4日

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

CVE-2018-1002105

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Z A

Slide 9

Slide 9 text

某X社 社内環境 A氏: 社内開発者、k8s クラスタ 開発 者アカウントを持っているも セキュ リティ上 理由によりクラスタ管理者 相当 権限を持っていない。 Z氏: 協力会社社員。k8s へ アクセス権を持っていな い。ひょんなことから k8s API エンドポイントを知ってし まった。

Slide 10

Slide 10 text

Z氏 Kubernetes クラスタを、 手中に収めることができた か

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

kube-apiserver

Slide 13

Slide 13 text

Central dogma of molecular biology https://en.wikipedia.org/wiki/Central_dogma_of_molecular_biology

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Central dogma of Kubernetes apiserver master node

Slide 16

Slide 16 text

The API server is the gateway to the Kubernetes cluster. It is the central touch point that is accessed by all users, automation, and components in the Kubernetes cluster. -- Managing Kubernetes https://www.oreilly.com/library/view/managing-kubernetes/9781492033905/ch04.html

Slide 17

Slide 17 text

reconciliation loop 各コンポーネント 、apiserver に保持された 状態を監視し、実際 オブジェクト Actual な状態を apiserver に宣言された状態へと変 化させていく。

Slide 18

Slide 18 text

例え ReplicaSets

Slide 19

Slide 19 text

replicasets controller apiserver Node (kubelet) RS replica:2

Slide 20

Slide 20 text

replicasets controller apiserver Node (kubelet) RS replica:2

Slide 21

Slide 21 text

replicasets controller apiserver Node (kubelet) Pod Pod

Slide 22

Slide 22 text

replicasets controller apiserver Node (kubelet)

Slide 23

Slide 23 text

replicasets controller apiserver Node (kubelet)

Slide 24

Slide 24 text

Central dogma of Kubernetes apiserver master node

Slide 25

Slide 25 text

apiserver replicasets controller Node (kubelet) RS replica:2 watch watch post

Slide 26

Slide 26 text

apiserver replicasets controller Node (kubelet) RS replica:2 get watch

Slide 27

Slide 27 text

apiserver replicasets controller Node (kubelet) post watch Pod Pod

Slide 28

Slide 28 text

apiserver replicasets controller Node (kubelet) get Pod Pod

Slide 29

Slide 29 text

apiserver replicasets controller Node (kubelet)

Slide 30

Slide 30 text

reconciliation loop 各コンポーネント 、apiserver に保持された 状態を監視し、実際 オブジェクト Actual な状態を apiserver に宣言された状態へと変 化させていく。

Slide 31

Slide 31 text

kube-api Pod PV with CSI Vol Volume Attachment kube controller-manager attach/detach controller Storage Bacend Volume StatefulSet (replica: 1) external attacher Controller CSI Plugin Empty Dir Volume CSI call via UDS Node DaemonSet driver registrar Node CSI Plugin kubelet CSI/k8s internal call via UDS host /.../sockets Device /var/lib/kubelet/XXX CSI call via UDS Watch Watch Watch Watch/ Update Create

Slide 32

Slide 32 text

There is no general rule without some exceptions. https://en.wikipedia.org/wiki/Feline_leukemia_virus

Slide 33

Slide 33 text

Central dogma of molecular biology https://en.wikipedia.org/wiki/Central_dogma_of_molecular_biology

Slide 34

Slide 34 text

Reverse transcription (RNA -> DNA) Rev. Transcriptase

Slide 35

Slide 35 text

RNA replication (RNA -> RNA) RNA Polymerase

Slide 36

Slide 36 text

Central dogma of Kubernetes apiserver master node

Slide 37

Slide 37 text

apiserver ? ?

Slide 38

Slide 38 text

apiserver Pod (Node) Aggregated API server 1. Pod に対する exec/attach/port_forward 2. Aggregated API Server

Slide 39

Slide 39 text

Pod に対する exec/attach/port_forward

Slide 40

Slide 40 text

Pod に対する exec/attach/port_forward apiserver kubelet Kubernetes API (ユーザ 権限) Kubelet API (apiserver 権限)

Slide 41

Slide 41 text

Kubelet API ● /pods ● /spec/ ● /exec/{podNamespace}/{podID}/{containerName} ● /attach/{podNamespace}/{podID}/{containerName} ● /portForward/{podNamespace}/{podID}/{containerName}

Slide 42

Slide 42 text

Kubelet API -- 認証 --

Slide 43

Slide 43 text

apiserver kubelet Kubernetes API GET /api/v1/namespaces/${NS}/pods/${POD}/exec Authorization: Bearer ${USER_TOKEN} Kubelet API with Client Cert (API Server) GET /exec/${NS}/${POD}/${CONTAINER}

Slide 44

Slide 44 text

apiserver kubelet Kubernetes API GET /api/v1/namespaces/${NS}/pods/${POD}/exec Authorization: Bearer ${USER_TOKEN} Kubelet API with Client Cert (API Server) GET /exec/${NS}/${POD}/${CONTAINER} apiserver から リクエストをどうにか して書き換えられれ 、kubelet API 自在に操ることができそうだぞ ……!?

Slide 45

Slide 45 text

Aggregated API Server

Slide 46

Slide 46 text

Kubernetes APIを 拡張する方法 1. Custom Resource Definition (CRD) ○ オススメ 方法 2. Aggregated API Server ○ CRD で 実現不可能な API を実装する場合

Slide 47

Slide 47 text

k8s api metrics server service catalog Kubernetes に Kubernetes API に加えて別 API を追加する。

Slide 48

Slide 48 text

Aggregated API Servers k8s api metrics server service catalog Aggregator (k8s api endpoint)

Slide 49

Slide 49 text

Aggregated API Servers kube-apiserver k8s api metrics server service catalog Aggregator

Slide 50

Slide 50 text

Aggregated API Server -- サービスディスカバリ --

Slide 51

Slide 51 text

$ curl -k https://${API_ENDPOINT}/apis $ curl -k https://${API_ENDPOINT}/apis/${API_GROUP}/${API_VERSION}

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

Aggregated API Server ● Service Catalog ● Metrics Server ● …

Slide 55

Slide 55 text

Aggregated API Server -- 認証 --

Slide 56

Slide 56 text

Aggregated API Aggregator (apiserver) Aggregated API Server に、認証 情報をどう伝えるか? Kubernetes いくつも 認証手段 を持っているため、単にリクエストを 転送するだけだと、バックエンドがそ 認証手段を解決しなけれ ならな くなる。

Slide 57

Slide 57 text

Aggregated API Aggregator (apiserver) GET /api HTTP/1.1 Authorization: Bearer ${TOKEN} GET /api HTTP/1.1 X-Remote-User: user-a Authorization API user-a こ API を call できるか? token から認証し、 ユーザアカウント名を取得 認証プロキシとして動作

Slide 58

Slide 58 text

Aggregated API Aggregator (apiserver) GET /api HTTP/1.1 Authorization: Bearer ${TOKEN} GET /api HTTP/1.1 X-Remote-User: user-a Authorization API user-a こ API を call できるか? token から認証し、 ユーザアカウント名を取得 apiserver から リクエストをどうにか して書き換えられれ 、Aggregated API Server API 自在に操ること ができそうだぞ……!?

Slide 59

Slide 59 text

唐突に HTTP 基礎

Slide 60

Slide 60 text

Web Server

Slide 61

Slide 61 text

Web Server TCP 接続

Slide 62

Slide 62 text

Web Server TCP 接続 HTTP 要求

Slide 63

Slide 63 text

Web Server TCP 接続 HTTP 要求 HTTP 応答

Slide 64

Slide 64 text

Web Server TCP 接続 HTTP 要求 HTTP 応答

Slide 65

Slide 65 text

Web Server TCP 接続 TCP 解放 HTTP 要求 HTTP 応答

Slide 66

Slide 66 text

TCP 接続 TCP 解放 HTTP 要求 Reverse Proxy Backend TCP 接続 HTTP 応答 HTTP 応答 TCP 解放 HTTP 要求

Slide 67

Slide 67 text

WebSocket?

Slide 68

Slide 68 text

TCP 接続 TCP 解放 HTTP Upgrade Reverse Proxy Backend TCP 接続 TCP 解放 HTTP Upgrade WebSocket 接続モード Reverse Proxy WebSocket 接 続モードへと切り替わった ち、 Client から パケットを Backend へ中継 みを行う。

Slide 69

Slide 69 text

TCP 接続 TCP 解放 HTTP Upgrade Reverse Proxy Backend TCP 接続 TCP 解放 HTTP Upgrade Upgrade に失敗した場合、接続を 終了し以降 クライアントから リ クエスト 破棄する必要がある。 HTTP Upgrade 失敗!

Slide 70

Slide 70 text

今回 脆弱性

Slide 71

Slide 71 text

TCP 接続 HTTP Upgrade Reverse Proxy Backend TCP 接続 HTTP Upgrade HTTP Upgrade 失敗! WebSocket 接続モード HTTP Upgrade に失敗し、 WebSocket を受信する準備が 整っていないサーバに対して無制 限にデータを送れてしまう! エラーハンドリングに問題があり、Upgrade が失敗したにも関わらず、Reverse Proxy が WebSocket 接続モードに移行してしま う。

Slide 72

Slide 72 text

何ができるか?

Slide 73

Slide 73 text

バックエンド APIをリクエストできる人 誰でも、 apiserver 権限でバックエンド APIをリクエストできてしまう。

Slide 74

Slide 74 text

権限昇格 脆弱性

Slide 75

Slide 75 text

デモ

Slide 76

Slide 76 text

apiserver kubelet A氏: 社内開発者 Z氏: 協力会社社員 $ kubectl exec $ kubectl exec GET /pods 本来呼び出せない kubelet API を呼び出してみる

Slide 77

Slide 77 text

デモ環境 namespace: production namespace: development A氏: 社内開発者 Z氏: 協力会社社員 nginx-prod nginx-dev

Slide 78

Slide 78 text

デモ環境 namespace: production namespace: development A氏: 社内開発者 Z氏: 協力会社社員 nginx-prod nginx-dev

Slide 79

Slide 79 text

デモ環境 namespace: production namespace: development A氏: 社内開発者 Z氏: 協力会社社員 nginx-prod nginx-dev

Slide 80

Slide 80 text

namespace: production namespace: development apiserver kubelet A氏: 社内開発者 $ kubectl exec prod $ kubectl exec dev apiserver にて、ユーザ認証に基づ き、適切な kubelet api を呼び出して いる。

Slide 81

Slide 81 text

TCP 接続 HTTP Upgrade Reverse Proxy Backend TCP 接続 HTTP Upgrade HTTP Upgrade 失敗! WebSocket 接続モード エラーハンドリングに問題があり、Upgrade が失敗したにも関わらず、Reverse Proxy が WebSocket 接続モードに移行してしま う。

Slide 82

Slide 82 text

apiserver kubelet A氏: 社内開発者 Z氏: 協力会社社員 $ kubectl exec $ kubectl exec GET /pods 本来呼び出せない kubelet API を呼び出してみる

Slide 83

Slide 83 text

Aggregated API Servers kube-apiserver k8s api metrics server service catalog Aggregator A氏: 社内開発者 Z氏: 協力会社社員 本来呼び出せない metrics api を呼び出してみる

Slide 84

Slide 84 text

Aggregated API Server -- サービスディスカバリ --

Slide 85

Slide 85 text

No content

Slide 86

Slide 86 text

TCP 接続 HTTP 要求 apiserver metrics server TCP 接続 HTTP 要求 GET /apis/metrics.k8s.io/v1beta1 Host: minikube GET /apis/metrics.k8s.io/v1beta1 Host: metrics-server

Slide 87

Slide 87 text

TCP 接続 HTTP 要求 apiserver metrics server TCP 接続 HTTP 要求 GET /apis/metrics.k8s.io/v1beta1 Host: minikube Connection: Upgrade GET /apis/metrics.k8s.io/v1beta1 Host: metrics-server Connection: Upgrade 本来 必要 ない Connection: Upgrade を載 せてみると? HTTP Upgrade 失敗! そもそも Upgrade に対応し てない で…。 アタックチャンス!

Slide 88

Slide 88 text

Aggregated API Aggregator (apiserver) GET /api HTTP/1.1 Authorization: Bearer ${TOKEN} GET /api HTTP/1.1 X-Remote-User: user-a Authorization API user-a こ API を call できるか? token から認証し、 ユーザアカウント名を取得

Slide 89

Slide 89 text

No content

Slide 90

Slide 90 text

Aggregated API Server API を呼び出すことができる。

Slide 91

Slide 91 text

ただし!

Slide 92

Slide 92 text

Aggregated API Server API で 「Kubernetes クラスタ乗っ取り」API が実装されていれ 可能。

Slide 93

Slide 93 text

kubectl exec できる かもしれない。

Slide 94

Slide 94 text

まとめ 1. Kubernetes API に対する exec/attach/port_forward 呼び出し 権限を 持っている人 、ノード上 Podに対して任意 コ マンドを実行できてしまう。 2. Kubernetes API エンドポイントを知ってる人 ク ラスタを乗っ取ることができる、という 言い過 ぎ。

Slide 95

Slide 95 text

まとめ 2 1. どちらにしろ環境による。 ○ 他 人から 情報を鵜呑みにせず、脆弱性が 自分 環境ど ような影響を与える かちゃん と確認しましょう。

Slide 96

Slide 96 text

Z氏 Kubernetes クラスタを、 手中に収めることができた か OTSUKA, Motohiro / Yuanying

Slide 97

Slide 97 text

Who am I ? ● OTSUKA, Motohiro / Yuanying ○ Z Lab Corporation ○ 元 OpenStack Magnum コントリビュータ ○ 言語 ■ Ruby (2007 - ) ■ Python (2014 - ) ■ Go (2017 - ) ○ 趣味 ■ ロードバイク (2009 - ) ■ トライアスロン (2010 - )

Slide 98

Slide 98 text

We are hiring

Slide 99

Slide 99 text

References: ● https://github.com/kubernetes/kubernetes/issues/71411 ● http://icooon-mono.com/ ● https://japan.zdnet.com/article/35129584/ ● https://jp.tenable.com/blog/kubernetes-privilege-escalation-vulner ability-publicly-disclosed-cve-2018-1002105 ● https://nakedsecurity.sophos.com/ja/2018/12/05/kubernetes-clou d-computing-bug-could-rain-data-for-attackers/ ● https://snyk.io/blog/critical-arbitrary-code-execution-vulnerability- found-in-kubernetes/ ● https://en.wikipedia.org/wiki/Central_dogma_of_molecular_biology ● https://en.wikipedia.org/wiki/Feline_leukemia_virus