mrtc0.log

tail -f mrtc0.log

ケイパビリティ

ケイパビリティとは

スーパーユーザー権限の細かい制御を提供することで, root ユーザーの使用を減らすことができる.
つまりrootか非rootかではなく, もっと細かい単位で権限を与えることが可能.
そのため, setuid属性を付与しなくてもケイパビリティで置き換えることが可能であり, 推奨されている.
実際にpingではCAP_NET_RAWが利用されており, 一般ユーザーでもpingを使うことができるようになっている.

$ getcap /bin/ping
/bin/ping = cap_net_raw+ep

ケイパビリティの定義は/usr/include/linux/capability.h内でCAP_から始まるもので定義されている. いくつか抜粋すると以下のようなケイパビリティがある.

  • CAP_CHOWN - ファイルのUIDとGIDを変更可能
  • CAP_DAC_OVERRIDE - ファイルにアクセス(読み書き実行)可能
  • CAP_DAC_READ_SEARCH - ファイルの読み出しと実行可能
  • CAP_NET_BIND_SERVICE - 1024番未満のポートを使用可能
  • CAP_NET_RAW - RAWソケットおよびPACKETソケットを使用可能
  • CAP_SYS_CHROOT - chrootが可能

プロセスの持つケイパビリティを確認する

getpcapsコマンドの引数にプロセスIDを渡して実行する.
以下はhttpd(apache)のプロセスIDを引数として渡した例.

$ getpcaps 27252
Capabilities for `27252': = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+ep

最後の+epはケイパビリティセットを表している.
プロセスはケイパビリティセットを持ち, 以下の3種類がある.

  • effective - カーネルがスレッドの権限 (permission) をチェックするときに 使用するケーパビリティセット
  • permitted - そのプロセスが持つことを許されているケイパビリティ
  • inheritable - 実行時に継承されるケーパビリティセット

fork(2)で作成される子プロセスは, 親のケーパビリティセットのコピーを継承する.
また, capsetコマンドでプロセスは自分自身のケーパビリティセット を操作することができる.
例の場合, +epとあるのでeffectiveとpermittedがセットされている.


実行ファイルの持つケイパビリティを確認する

実行ファイルにケーパビリティセットを対応付けることができる.

  • effective - これが設定されていなければ実行したときにプロセスのpermittedが設定されない
  • permitted - 実行したときに許可されるケイパビリティセット
  • inheritable - 実行時に継承されるケイパビリティセット

実行ファイルのケイパビリティセットを確認するにはgetcapコマンドを使用する.

$ getcap /bin/ping
/bin/ping = cap_net_raw+ep

ケイパビリティをセットする

ここではpingコマンドにケイパビリティの付与, 削除を行ってみる.

$ cp /bin/ping /tmp/ping
$ cd /tmp
$ getcap ./ping

コピーしたpingにはケイパビリティは付与されていない. そのため, 一般ユーザーでは実行してもネットワークソケットを使えずにOperation not permittedと表示される.

$ ./ping 8.8.8.8
ping: icmp open socket: Operation not permitted

setcapコマンドを使って, ケイパビリティをセットする. ソケットを使用するため, CAP_NET_RAWにeffectiveとpermittedを設定する.

$ sudo setcap cap_net_raw=ep ./ping
$ getcap ./ping                    
./ping = cap_net_raw+ep
$ ./ping 8.8.8.8 -c 1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=48 time=54.9 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms

ケイパビリティの削除にはsetcapコマンドに-rオプションを渡す.

$ sudo setcap -r ./ping
$ ./ping 8.8.8.8
ping: icmp open socket: Operation not permitted

これを使えば一般ユーザーでは参照できないディレクトリをlsコマンドで参照できるようになる.
man capabilities で調べるとCAP_DAC_READ_SEARCHの項目に

Bypass file read permission checks and directory read and execute permission checks;

とあるのでCAP_DAC_READ_SEARCHを付与すれば, ファイルの読み出し権限のチェックをバイパスできる.
実際にlsコマンドとcatコマンドに付与し, /root/hidden.txtを読み取ってみる.

$ cp /usr/bin/ls /tmp/
$ cp /usr/bin/cat /tmp/
$ cd /tmp

$ ./ls /root
./ls: ディレクトリ /root を開くことが出来ません: 許可がありません
$ sudo setcap cap_dac_read_search=ep ./ls
$ ./ls /root                             
hidden.txt

$ ./cat /root/hidden.txt
./cat: /root/hidden.txt: 許可がありません
$ sudo setcap cap_dac_read_search=ep ./cat
$ ./cat /root/hidden.txt                  
This file is root's file

参考