Publicité

Contenu connexe

Présentations pour vous(20)

Similaire à FreeBSD Capsicum(20)

Publicité

Dernier(20)

Publicité

FreeBSD Capsicum

  1. FreeBSD の Capsicum について 2021 年 1 月 21 日 (株)創夢 内藤 祐一郎
  2. Capsicum とは ● FreeBSD 10.0 (2014/01/20) からサポートされている セキュリティの仕組み ● 設定不要、かつ、デフォルトで有効 ● きちんと実装されたアプリケーションならば、 使い勝手は変わらない ● 既に 7 年間使われ続けた実績がある
  3. Capsicum とは ● ユーザランドのプロセスが自発的に不要な権限を落とすこ とでセキュリティを高めようというものです ● 万が一、プロセスを乗っ取られても権限がないため情報漏 洩などを防ぐことができます ● 必要最小限の権限を capability と言ったりします ● Linux の capability とは異なりますので 本発表では Linux の capability のことは忘れてください
  4. 実装コマンド例 ● dd ● md5 / sha ● diff / diff3 ● basename ● iconv ● head / tail ● printenv ● logger ● ping / ping6 ● traceroute / 6 ● tcpdump ● rtsold ● sshd ● hastd ● iscsid ● dhclient ● bhyve ● readelf ● nm ● strings ● xz ● hexdump ● kdump ● elfdump など・・・
  5. 実装プログラム数 分類 プログラム数 bin 4 sbin 8 usr.bin 37 usr.sbin 9 contrib 12 crypto 1 合計 71 FreeBSD Current r36584 (2020/09/18) での数 ソースコード単位で集計
  6. Capsicum の設計 ● 既存の UNIX の仕組みを壊さずに拡張する ● ファイルディスクリプタなどをそのまま使う ● 新しいモードとして capability mode を追加する ● このモードは抜けることができない&子プロセスにも引き 継がれる ● capability mode ではグローバルな名前空間へのアクセス を禁止する
  7. グローバルな名前空間 名前空間 概要 Process ID プロセスに与えられる識別子 File paths ルートから始まる階層構造を持つファイルへのアクセス方法 NFS file handles NFS サーバとクライアントで使われるファイルの識別子 File system ID マウントポイント毎に割り当てられる ID Protocol addresses IPv4 / IPv6 アドレスやホスト / ドメイン名など Sysctl MIB sysctl の識別子 (kern.ostype など ) System V IPC System V の共有メモリ、メッセージなど POSIX IPC メッセージキュー、セマフォなど Jails FreeBSD のプロセスを閉じ込める仕組み CPU sets 使える CPU の一覧
  8. ローカルな名前空間 ● ファイルディスクリプタ ● 仮想メモリアドレス ● スレッド ID ● シグナルマスク ● プロセスタイマー ● プロセス優先度 ● リソース制限
  9. グローバルな名前空間へのアクセス例 ● open(2) / stat(2) / chdir(2) / unlink(2) / execve(2) – 引数にファイルパスが入るので NG ● fork(2) / wait(2) / wait4(2) – 戻り値や引数に PID が入るので NG ● connect(2) / bind(2) – 引数にネットワークアドレスが入るので NG
  10. グローバルな名前空間へのアクセス例 ● kill(2) – 自分自身へのシグナルなら OK それ以外は NG ● sysctl(3) – 自身の情報に関するものならば OK それ以外は NG ● shm_open(2) – 匿名 (ANONYMOUS) ならば OK それ以外は NG
  11. ローカルな名前空間へのアクセス例 ● openat(2) / fstat(2) / fchdir(2) / unlinkat(2) / fexecve(2) – ファイルディスクリプタを基にしたアクセスのため OK ● pdfork(2) – pid の代わりにプロセスディスクリプタを返す ● connectat(2) / bindat(2) – ファイルディスクリプタを基にしたアクセスのため OK – ただし UNIX Domain Socket しか使えない
  12. ローカルな名前空間へのアクセス例 ● read(2) / write(2) / close(2) / pipe(2) / dup(2) / select(2) – ファイルディスクリプタの操作のため OK ● getpid(2) / getuid(2) – 自身の情報を返すだけのため OK ● sigaction(2) – 自分のシグナルに関する設定のため OK
  13. Capsicum の実装 ● capability mode に入るシステムコール cap_enter(2) を 新設します ● capability mode で呼び出せないシステムコールは エラーを返します ● capability mode で呼び出せるシステムコールのうち 条件のあるものは条件を追記します ● capability mode で呼び出しても OK なものは 何も変更しません
  14. Capsicum 実装のメリット ● 全てシステムコールの入り口で判定することができます ● ファイルシステムやプロトコルスタックなどのサブシステ ムに手を入れる必要がありません ● sysctl MIB については全てに capability mode でのアクセ ス権限フラグを新設しました
  15. アプリケーションからの使い方 1.アクセスするリソースは事前に取得します – open(2) などでファイルを開いておきます 2. cap_enter(2) を呼び出します – capability mode に入ります 3.実際の処理を行います – ここで予期せぬ入力からバッファオーバーランなどを 引き起こしても、事前に取得したリソース以外へアクセ スできないため、情報流出などを防ぐことができます
  16. さらなる制限 ● 既に取得したファイルディスクリプタに更なる制限を加え ることができます ● 例えば、あるファイルディスクリプタに対して READ | FCNTL | IOCTL | SEEK | EVENT を許可することで、読み込み、 fcntl(2) 、 ioctl(2) 、シー ク、待ち合わせを許可して他を制限することができます ● 主に呼び出せるシステムコールの種類毎に権限が定義され ており、 rights(4) に 78 種類あります
  17. さらなる制限 ● また、 ioctl(2) については発行するリクエスト番号を制限 することができます ● 使用するリクエスト番号を予め 256 個まで登録することが できます ● 登録されたリクエスト番号以外をエラーとします
  18. casper ライブラリ ● capability mode の中でいくつかの制限を緩和するための ライブラリ ● casper と呼ばれる代理プロセスを経由して、制限された 機能を呼び出します。 ● 実装は libcasper.so の中にあります。 ● casper は種類毎にサービスとして分けられており、 FreeBSD Current r366713 時点で全6種類あります ( FreeBSD 12.1 Release では 7 種類)
  19. casper ライブラリの実装 メインプロセス (capability mode) casper サービス (non capability mode) cap_init() - socketpair() - fork() サービスチャンネル メインチャンネル メインチャンネル close cap_service_open() cap_enter()
  20. casper ライブラリの実装 ● casper はサービスとして存在していますが、実体は自分自 身が fork(2) した子プロセスです ● capability mode に入る前に初期化 (cap_init(3)) し、自分自 身を fork(2) して、子プロセスを立ち上げます ● 子プロセスとの間は socketpair(2) で UNIX Domain Socket のペアで繋ぎます ● cap_init(3) の戻り値としてこの通信路を含んだ構造体を返 します
  21. casper ライブラリの実装 ● 子プロセスの casper に必要なサービスを要求 (cap_service_open(3)) すると該当サービスへの通信路と して同様の UNIX Domain Socket が開かれます ● サービス毎の通信路を通してリモート関数呼び出しが行わ れます ● 各サービスの実体も同じ子プロセスです ● 従って代理実行されている処理は直列に動作します ● サービスを取得したら casper への通信路を閉じます
  22. cap_pwd ● /etc/passwd, NIS,LDAP などのユーザ情報を扱うサービスです ● getpwent(3), getpwnam(3) などの関数呼び出しを代理で実行して くれます ● 予め必要な関数名を定義しておいて、その呼び出しだけを代理実 行させることができます ● 必要なフィールドを定義しておいて、そのフィールドだけを返す ようにすることもできます ● 検索できるユーザ名または UID を制限することもできます
  23. cap_grp ● /etc/group, NIS, LDAP などグループに関する情報を扱うサービ スです ● getgwent(3), getgrnam(3) などの呼び出しを代理で実行してく れます ● 予め必要な関数名を定義しておいて、その呼び出しだけを代理 実行させることができます ● 必要なフィールドを定義しておいて、そのフィールドだけを返 すようにすることもできます ● 検索できるグループ名または GID を制限することもできます
  24. cap_sysctl ● sysctl を扱うためのサービスです ● sysctl(3), sysctlbyname(3) などの呼び出しを代理で実行し てくれます ● 予め操作する MIB を定義しておいて、その MIB だけを操 作することができます
  25. cap_syslog ● syslog を扱うためのサービスです ● syslog(3), openlog(3), closelog(3) などの呼び出しを代理 で実行してくれます ● syslog 出力のみのため、特に追加的な制限はありません
  26. cap_net ● ネットワークを扱うためのサービスです ● bind(2), connect(2), getaddrinfo(3) などの呼び出しを代理 で実行してくれます ● 予め呼び出す関数の種類を制限することができます ● 名前解決するホスト名を制限することができます ● 逆引きする IP アドレスを制限することができます ● connect(2) するアドレスを制限することができます ● bind(2) するアドレスを制限することができます
  27. cap_fileargs ● コマンドライン引数で指定されたファイル名を開くための サービスです ● 既存のコマンドを capability mode で動かすようにすると きにコードの変更を少なくするために作られました ● argv の配列を渡すとそこに書かれたファイル名であれば open(2) を代理実行してくれます ● open(2) したファイルディスクリプタに追加制限を加える ことができます
  28. 統廃合されたサービス ● cap_dns は cap_net に統合されました ● cap_random は getrandom(2) が実装されたため不要にな りました
  29. capability mode でのプログラミング ● 基本的には全てのリソースを予め取得しておきます ● そうでなければ必要なディレクトリを全て open(2) してお くと、 openat(2) で開くことができます ● ネットワークアクセスには cap_net を使用して、ホワイト リスト内の相手とだけ通信します ● 自分で casper サービスを追加するのも手です ● 逆に守りたい部分だけ fork(2) 後に子プロセスで処理し、 結果を親プロセスに返すという手もあります
  30. capability mode でのプログラミング ● 子プロセスの起動は現時点ではスタティックリンクされた バイナリのみ起動できます ● ダイナミックリンクされたバイナリは起動時にダイナミッ クリンカ (/libexec/ld-elf.so.1) が必要ですがこれにアクセス する権限がありません ● 子プロセスは起動直後から capability mode のためほとん ど何もできません ● fdfork(2), fexec(2), poll(2), close(2) を呼び出すことで子プ ロセスの実行から待ち合わせ、終了処理が行えます
  31. capability mode でのデバッグ ● システムコールが capability 違反を検出すると ECAPMODE の errno が返ります ● sysctl kern.trap_enotcap=1 に設定すると ECAPMODE が返るときにプロセスがコアダ ンプするようになります ● コアファイルからスタックトレースなどを探るとどの処理 で落ちているのかが分かりやすくなります
  32. Capsicum の限界 ● shell が書けない – shell は全ての資源にアクセスできるべきです ● スクリプト言語と相性が悪い – リソース管理がカプセル化されているため – 事前に全てのリソースを把握するのが困難 ● ライブラリが使いにくい – ファイルディスクリプタを受け渡すインタフェースに 変える必要があります
  33. 実例( rtsold ) ● 2020 年 12 月に rtsold の SA がでました – FreeBSD-SA-20:32.rtsold ● root で任意のコードが実行できる可能性があるものです ● 影響は既に bind しているネットワークインタフェースを 操作できる程度に制限されていた ➔ capsicum により情報漏洩のリスクは避けられた
  34. 実例( tcpdump ) ● 2017 年 tcpdump 4.9.0 に複数の脆弱性 CVE-2017-5486 CVE-2017-5485 CVE-2017-5484 CVE-2017-5483 CVE-2017-5482 CVE-2017-5342 CVE-2017-5341 CVE-2017-5205 CVE-2017-5204 CVE-2017-5203 CVE-2017-5202 ・・・ いずれも任意のコードが 実行されうる重大なもの
  35. 実例( tcpdump ) ● 2017 年当時既に FreeBSD の tcpdump は capability mode で動作していました ● 任意のコードが実行されたとしてもできることはほとんど ありませんでした ● FreeBSD Project から Security Advisory は出ませんした ● tcpdump は次のリリース (11.2 RELEASE 2018/6/28) で バージョンアップされました
  36. おわり ● 質問などがありましたらどうぞ
Publicité