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

내가 모르는 파일 시스템과 프로세스 기능 사이에 차이점이 있습니까? 세 번째 테스트를 올바르게 작성하는 방법은 무엇입니까?

답변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유통사이트. 이 모든 것이 여전히 혼란스럽다면 거기에 있는 예제가 도움이 될 수 있습니다.

관련 정보