Weitere ähnliche Inhalte
Ähnlich wie Programming under capability mode (20)
Mehr von Yuichiro Naito (20)
Programming under capability mode
- 2. ケーパビリティモード
● FreeBSD 9.0-R から された しいモード。搭載 新
● cap_enter(2) を び した の された 。呼 出 後 制限 環境
●
たなファイルディスクリプタを できなくなる。新 取得
● shmget(2) などのリソース ができなくなる。取得
●
ケーパビィティモードは プロセスにも される。子 継承
● cap_rights_limit(2) により かく細 (read, write, ...) できる制御
。
- 3. メリット
● selinux と なりユーザの が 。異 設定 不要
● root に setuid されたプログラムなど、
きすぎる を つプロセスが に を とせる。大 権限 持 自発的 権限 落
● えば例 ping, traceroute はパケット のために取得 root を権限
つため、 が が つかった に したパケットを持 万 一脆弱性 見 場合 細工
させるなどして の になりやすい。受信 攻撃 標的
●
ケーパビリティモードで していれば、 が されてもア動作 万 一攻撃
クセスできるリソースがないため を められる。安全性 高
● FreeBSD-11 から ping, traceroute はケーパビリティモードで
する。動作
- 4. なプログラムの れ基本的 流
1. 必要なファイルディスクリプタを取得する。
2. cap_enter(2) を実行する。
3. 必要があればさらに cap_rights_limit(2) で制限を加える。
4. アプリケーションとしての処理を実行する。
5. プロセス終了。
- 5. されるシステムコール制限
● chdir, stat, open, rename, mkdir, unlink など
にパス を るものは えない。引数 名 取 使
● connect, bind, sendto
に引数 struct sockaddr * をとり 、 を するも送信先 受信元 指定
の
● execve, wait, waitpid, wait3/4/6
● shm_open, shmget, msgget
● すると使用 ECAPMODE の errno が る。返
- 6. を けないシステムコール影響 受
● read, write, close, sendfile, select, poll, mmap など
のファイルディスクリプタを するもの既存 使用
● pipe, socket, accept, listen, kqueue など
のプロセスに するだけもの自分 影響
● getpid, getuid, time, gettimeofday など
なる のもの単 情報取得
● fork
- 7. より かい を える細 制限 加
● cap_rights_limit(2) によりファイルディスクリプタごとに細か
く制限することが可能。
➔ READ
➔ WRITE
➔ IOCTL
➔ FSTAT
➔ FUNLINK
➔ MMAP, MMAP_R, MMAP_W, MMAP_RW など
● 概ねファイルディスクリプタを操作するシステムコール毎に権限
を設定できる。
- 9. となるシステムコール代替
● cap_enter(2) にディレクトリのファイルディスクリプタを前
open(" ディレクトリ名 ", O_RDONLY|O_DIRECTORY) で取得
しておく。
● openat, renameat, mkdirat など ~ at を する。系 使用
~ at は となるディレクトリのファイルディスクリプタ系 基準
から パスで する。相対 指定
● パスに相対 “ ..” を れて ディレクトリに がる はカーネル入 親 上 操作
に される。拒否
● fchdir, fstat などファイルディスクリプタを にとるものを引数
する。使用
- 10. プログラムの れ ファイルアクセス流 ( )
1. base=open(“/var/data”,O_RDONLY|O_DIRECTORY);
2. cap_enter();
3. fd=openat(base, “sample.txt”, O_RDWR);
4. read(fd, buf, size);
...
5. close(fd);
- 11. ネットワークの利用( UDP )
● cap_enter() の前にソケットを作成し、予め送信先や受信元を設
定しておく。
➔ sendto(2), bind(2) は えなくなる。使
● 送信先は connect(2) で指定する。
● 受信元は bind(2) で指定する。
- 12. プログラムの れ流 ( UDP 送信)
1. sock=socket(PF_UNSPEC, SOCK_DGRAM, 0);
2. < sockaddr に接続先を入れる >
3. connect(sock, &sockaddr, size);
4. cap_enter();
5. send(sock ,data, len);
6. recv(sock, buf, buf_len);
7. …
8. close(sock);
- 13. プログラムの れ流 ( UDP 受信)
1. sock=socket(PF_UNSPEC, SOCK_DGRAM, 0);
2. < sockaddr に受信元を入れる >
3. bind(sock, &sockaddr, size);
4. cap_enter();
5. recv(sock ,buf, buf_len);
6. send(sock, data, size);
7. …
8. close(sock);
- 14. ネットワークの利用( TCP )
● cap_enter() の にソケットを し前 作成 bind(2) または
connect(2) しておく。
● bind(2) のソケットに済 accept はできるため は 。受信 可能
● connect(2) はたとえ じ であっても できないため、同 接続先 使用
タイムアウトなどで することができない。再接続
●
クライアントプログラムならば、プロセスを する。再起動
● さもなければ unix domain socket を して、経由
プロセスが したソケットを け してもらう。別 接続 受 渡
- 15. ソケット け しの受 渡 例
親プロセス 子プロセス
socketpair(PF_UNIX)
fork()
send(“ ”ホスト名:ポート番号 )
connect()
sendmsg(ソケット)
recv()
recvmsg()
cap_enter()
- 16. プロセス生成
● fork, fexecve が えるため、使
ファイルディスクリプタさえあれば イメージを 。実行 起動可能
しかし、ケーパビリティモードは プロセスにも子
されるため、継承 /libexec/ld-elf.so.1 の み みに読 込
してしまう。失敗
スタティックリンクされたプログラムなら できる。起動
● wait ができないため、 ち わせる がない。待 合 手段
● 11-R では pdfork(2), pdwait(2) が される だったは実装 予定
ず。。。
- 17. その他
● libc を めたライブラリについては が い。含 制限 多
● fopen() ではなく fdopen() を うなど、プログラム での使 側 対処
が 。必要
● getpwent() など で にファイル内部 暗黙 (/etc/passwd など ) を
するものは えない。参照 使
● casperd を して なリソースにアクセスするようになる経由 必要
み。見込