capsh を使用した setcap 動作の再現

capsh を使用した setcap 動作の再現

非能力認識プログラムを持つには、少なくとも1)cap_sys_adminと2)cap_dac_overrideまたはが必要ですcap_dac_read_search。これは次のように証明できます。

sudo setcap 'all=ep cap_sys_admin-ep' ./binary`                        # ./binary doesn't work
sudo setcap 'all=ep cap_dac_override-ep' ./binary`                     # ./binary works
sudo setcap 'all=ep cap_dac_read_search-ep' ./binary                   # ./binary works
sudo setcap 'all=ep cap_dac_override,cap_dac_read_search-ep' ./binary  # ./binary doesn't work

capsh代わりに同じチェックを実行したいと思いますsetcap。これらの確認を実行する前に、すべてのファイル削除機能が使用されますsudo setcap -r ./binary。最初のツリーは成功し、結果は次のように一致しますsetcap

sudo capsh --user=jdoe --keep=1 --caps="all=eip" --addamb="all" --delamb="cap_sys_admin" -- -c ./binary
sudo capsh --user=jdoe --keep=1 --caps="all=eip" --addamb="all" --delamb="cap_dac_override" -- -c ./binary
sudo capsh --user=jdoe --keep=1 --caps="all=eip" --addamb="all" --delamb="cap_dac_read_search" -- -c ./binary

最後は失敗し、プログラムは実行を続けますが、次のような動作をしてはいけません。

sudo capsh --user=jdoe --keep=1 --caps="all=eip" --addamb="all" --delamb="cap_dac_override,cap_dac_read_search" -- -c ./binary

私が知らないファイルシステムとプロセス機能の違いはありますか? 3番目のテストを正しく書くには?

ベストアンサー1

したがって、あなたの質問に対する答えは、あなたのプログラムが何をしているのかだと思います。 (通常、あなたが見ているものを再現する簡単なソースコードを質問に提供するのが最善です。)

私はいくつかのコードをすばやく書きました(GoではCよりも速くデバッグ出力を生成し、libcap、実際の例を提供します。cap袋に行きなさい)。

これはbinary.go

package main

import (
    "log"
    "os"

    "kernel.org/pub/linux/libs/security/libcap/cap"
)

func confirm(c *cap.Set, val cap.Value) int {
    on, err := c.GetFlag(cap.Effective, val)
    if err != nil {
        log.Fatalf("unable to confirm %q in effective set: %v", val, err)
    }
    log.Printf("%q in effective set of %q is: %v", val, c, on)
    if on {
        return 0
    }
    return 1
}

func fail() {
    log.Print("FAILURE")
    os.Exit(1)
}

func main() {
    c := cap.GetProc()
    if confirm(c, cap.SYS_ADMIN) != 0 {
        fail()
    }
    if confirm(c, cap.DAC_OVERRIDE)+confirm(c, cap.DAC_READ_SEARCH) > 1 {
        fail()
    }
    log.Print("SUCCESS")
}

次のようにコンパイルされました。

$ go mod init binary
$ go mod tidy
$ go build binary.go
$ ./binary 
2022/09/10 16:45:56 "cap_sys_admin" in effective set of "=" is: false
2022/09/10 16:45:56 FAILURE
$ echo $?
1

このプログラムはbinaryあなたが説明するすべての属性を持ち、あなたが期待する方法で動作します。ファイル機能バージョンと周辺継承されたバージョン(使用済みバージョンcapsh)では継承可能既存のプロセス機能:

$ sudo setcap 'all=ep cap_dac_override,cap_dac_read_search-ep' ./binary
$ ./binary 
2022/09/10 16:50:37 "cap_sys_admin" in effective set of "=ep cap_dac_override,cap_dac_read_search-ep" is: true
2022/09/10 16:50:37 "cap_dac_override" in effective set of "=ep cap_dac_override,cap_dac_read_search-ep" is: false
2022/09/10 16:50:37 "cap_dac_read_search" in effective set of "=ep cap_dac_override,cap_dac_read_search-ep" is: false
2022/09/10 16:50:37 FAILURE
$ sudo setcap -r binary
$ sudo capsh --user=$(whoami) --keep=1 --caps="all=eip" --addamb="all" --delamb="cap_dac_override,cap_dac_read_search" -- -c ./binary
2022/09/10 16:52:21 "cap_sys_admin" in effective set of "=eip cap_dac_override,cap_dac_read_search-ep" is: true
2022/09/10 16:52:21 "cap_dac_override" in effective set of "=eip cap_dac_override,cap_dac_read_search-ep" is: false
2022/09/10 16:52:21 "cap_dac_read_search" in effective set of "=eip cap_dac_override,cap_dac_read_search-ep" is: false
2022/09/10 16:52:21 FAILURE

つまり、"=ep"ファイル機能バージョンが"=eip"あり、周辺一つ。この".i."部分はプログラムに直接役立つ機能ではなく、プログラムが実行されたときにのみ機能します。

私の考えでは、コードが確認されていると思います。継承可能プロセス機能繰り返しますが、これらはいいえ自分の特権。ファイルと組み合わせた場合にのみ権限を表します。継承可能能力周辺能力。私は機能の継承がどのように機能するかについて完全に書きました。libcap流通サイト。これがまだ混乱している場合は、そこにある例が役に立ちます。

おすすめ記事