スマートフォン解析 top

TOP > タイガーチームセキュリティレポート > Sandboxについて - Part 3

タイガーチームセキュリティレポート

Sandboxについて - Part 3

sandboxに関するコラムの第3回です。今回はLXCのセキュリティがテーマです。


-プロセスの権限を見てみる-

まずContainer内で起動しているプロセスの権限をチェックしましょう。mylxc内でbashを起動した状態で、Host環境からpsを実行します。


mylxc内のbashはHost環境から見てroot権限で起動していることがわかります。さらに、同じbashのstatus情報をチェックします。


CapPrm, CapEff, CapBndがすべてffffffffffbfffffなので、22番めのcapabilityがdropされていることがわかります。

capabilityとはrootユーザだけが持つような特権を細かく分けたものです。root権限のプロセスから一部のcapabilityを落すことでプロセスに弱いroot権限を持たせたり、一般ユーザ権限のプロセスにcapabilityを足すことで一部の特権をそのプロセスに委譲することができます。

例えばUnix系のシステムでは伝統的にプロセスがwell knownポートにbindするためにroot権限が必要でしたが、これは最小権限の原則から見て好ましくない状態でした。CAP_NET_BIND_SERVICEを与えることでroot権限がなくともwell knownポートにbindできるようになります。

お使いのLinuxでのcapabilityの番号は/usr/include/linux/capability.hに定義されています。個々のcapabilityの役割はman 7 capabilitiesに説明されています。


CAP_SYS_BOOTがdropされているのでこのbashはreboot()とkexec_load()をコールできませんがそれ以外のシステムコールはコールできます。


-Container外へのアクセス-

Container内から外にアクセスできないか試して見ましょう。

mylxcではHost環境のディレクトリをroでbind mountしていますがContainer内からそれらをrwでremontすることが可能です。


これでHost環境の/mylxc/rootfs以外のディレクトリにも書き込み可能になりました。mylxcとHost環境はPIDとmountに関してNamespaceが分離されていますが、deviceに関しては同じものが見えます。Linux KernelはdeviceのNamespaceを実装していません。Container内で/dev以下にmknodすればHost環境と同じdeviceにアクセスすることができます。


ここでmknodした/dev/sda1をmountすればContainer内からHost環境のfile system全域にrwアクセスできるようになります。


mount()をコールするために必要なcapabilityはCAP_SYS_ADMINです。CAP_SYS_ADMINが与えられたContainer内のプロセスはContainer外のfile systemにrwアクセスできることがわかりました。これはセキュリティ上問題があります。mylxcを終了(exitで終了できます)しプロセスからCAP_SYS_ADMINをdropする設定をmylxcの設定に追加します。


ここで行ったdevice fileをmknodしmountする方法は前々回のコラムで紹介したchroot jailから脱出するための方法の別解でもあります。

以下はchroot jailから脱出するためのもう一つの quick & dirty なプログラム(jailbreak2.c)です。


これをコンパイルして前々回と同じchroot jail用のディレクトリコピーし、chroot()してjail内のbashから実行してみましょう。


脱出成功です。やはりchroot jailは弱いです。


-デバイスへのアクセス制御-

Container内からdevice fileへの自由なアクセスを許すのは危険なので、Cgroupの機能でアクセス制御してみましょう。

Container内でdevice fileが必要な場合にはContainer起動前にdevice fileをmknodしておくことができますが、そうでない場合もあります。例えばContainer内でsshdを起動する場合、sshdはログインのたびに疑似端末masterとなる/dev/ptmxと/dev/pts以下の新しい疑似端末slaveを必要とします。

以下はmylxcを起動する前に/mylxc/rootfs/dev以下に作成したdevice fileのリストの例です。


CgroupのDevice Whitelist Controllerを利用するとContainer内からdevice fileへのアクセスに関してrwm(read, write, mknod)の可否をmajor, minor番号の組ごとに設定することができます。

以下のmylxcの設定により、mylxc内で/dev/console等の一部のcharacter deviceを除くすべてのdevice fileに対するrwはすべて拒否されます。mknodに関してはすべて許可する設定です。


以上です。今回はdeviceまわりのLXCのセキュリティを検証し、mylxcのセキュリティを強化するための設定を追加しました。

Linux kernel 3.8でUser Namespaceの実装が完了しました。これは親子のNamespace間で同じプロセスのUID/GIDをマッピングする機能です。User Namespaceを分離すればContainer内のroot権限のプロセスに対しHost環境でのroot権限を与えないといったことが可能です。今回はLinux kernel 3.2で検証したので、この機能は利用できませんでした。


参考情報:
[1] lxc.conf
http://manpages.debian.net/cgi-bin/man.cgi?query=lxc.conf
[2] capabilities
http://manpages.debian.net/cgi-bin/man.cgi?query=capabilities
[3] 最小権限の原則 - Wikipedia
http://ja.wikipedia.org/wiki/...
[4] Linux 3.8 - Linux Kernel Newbies
http://kernelnewbies.org/Linux_3.8


次回も、別の角度からLXCのセキュリティについて見ていくことにします。


タイガーチームメンバー 塚本 泰三