POSIX 기능 확산 방지

POSIX 기능 확산 방지

일반적으로 유닉스(또는 특히 Linux) 프로그램은 ICMP_ECHO("ping")를 사용하여 라우터의 접근성을 확인하는 것과 같은 작업을 수행할 수 없습니다.누구나슈퍼유저로 실행또는setuid 루트또는적절한 POSIX 기능을 갖추고 있어야 합니다. 분명히 setuid 또는 POSIX 기능을 바이너리에 적용하려면 모든 작동 시스템에 대한 수퍼유저 개입이 필요합니다.

개발 환경에 CAP_SETFCAP 기능이 있는 경우 적어도 로컬 작업에 관한 한 빌드하는 프로그램에 적절한 POSIX 기능을 설정할 수 있어야 합니다.

켄 톰슨에게 경의를 표합니다신뢰에 대한 생각논문에 따르면 모든 라이브러리의 정적 링크를 가정하면 원칙적으로 각 프로그램 소스 모듈에 지문을 작성하고 이를 객체와 바이너리에 전파하여 특정 바이너리가 특정 세트에서 빌드되었음을 증명하는 감사 추적을 제공할 수 있어야 합니다. 자원이 된다. 따라서 새로 생성된 IDE 복사본을 승인해 달라고 요청하는 관리자는 IDE가 자체적으로 생성하는 프로그램에서만 기능을 설정할 수 있고 문서화되지 않은 코드를 통과할 수 있도록 악의적인 사용자가 수정할 수 없다는 점을 스스로 만족시킬 수 있어야 합니다. 예를 들어 시작 옵션을 setcap의 개인 복사본으로 사용하십시오.

여기서 문제는 가장 성숙한 개발 환경(예:라자루스 통합 개발 환경)은 자체적으로 빌드될 수 있으므로 로컬 관리자가 CAP_SETFCAP로 입증 가능한 깨끗한 복사본을 축복하면 악의적인 사용자가 이를 다시 빌드하여 악성 코드를 포함하고 CAP_SETFCAP를 직접 적용하여 로컬 시스템 보안을 손상시킬 수 있습니다.

다른 CAP_SETFCAP 또는 상위 집합 기능 중 하나에 의해 새로 생성된 프로그램에 전파될 수 없도록 POSIX CAP_SETFCAP 기능을 바이너리 파일에 적용할 수 있습니까?

답변1

setcap방금 활성화한 사용자 에게 사용을 예약하려면 sudo여기에 기능을 추가할 필요가 없습니다. 그냥 해.

신뢰할 수 있는 사용자에 대해 알고 있는 경우 이 기능을 사용하는 데는 두 가지 옵션이 있습니다. 또한 자신이 능력 있는 것처럼 보이고 싶은 경우 패키지 파일 등을 포함하여 세 번째 옵션도 포함했습니다.

  1. 로컬 복사본을 만들고 setcap공개 그룹(건축업자) 사용자에게 허용된 기능을 제공합니다. 이는 이 그룹의 사용자 구성원이 올바르게 행동할 것을 신뢰합니다.
$ cp $(which setcap) ./builder-setcap
$ sudo chgrp builders ./builder-setcap
$ chmod 0750 ./builder-setcap
$ sudo ./builder-setcap cap_setfcap=p ./builder-setcap
  1. 사용상속 가능한builder-setcap권한을 가지고 실행될 수 있는 사람을 제한하는 파일 기능입니다 . 실제로 런타임에 해당 권한을 얻으려면 또 다른 단계가 필요합니다(어떤 방식으로든 실행 중인 사용자가 프로세스를 사전 획득함).상속 가능한capsh또는 같은 능력pam_cap.so). 이 메커니즘은 빌드 시스템 주변의 래퍼일 수 있습니다. 다음과 같이 진행 됩니다 capsh.
$ cp $(which setcap) ./builder-setcap
$ sudo chgrp builders ./builder-setcap
$ chmod 0750 ./builder-setcap
$ sudo ./builder-setcap cap_setfcap=i ./builder-setcap
$ sudo capsh --user=$(whoami) --inh=cap_setfcap --
... $ # in this shell cap_setfcap is available to ./builder-setcap
  1. 세 번째 메커니즘은 사용자 네임스페이스 컨테이너를 사용하는 것입니다. 그러한 컨테이너 안에는 잘못된 특권 개념과 잘못된 개념이 있습니다.뿌리사용자. 이 환경에서는 권한이 없는 사용자가뿌리이 컨테이너에 대해 간단히 다음을 호출하여 setcap잘못된 기능을 제공할 수 있습니다 .
$ unshare -Ur
... $ id
uid=0(root) gid=0(root) groups=0(root),65534(nobody)
... $ cp $(which setcap) builder-setcap
... $ ./builder-setcap cap_setfcap=p ./builder-setcap

마지막 경우 파일 기능은 컨테이너 내부에서 작동하지만 컨테이너를 종료한 후에는 작동합니다. 기능이 활성화된 파일에는 실제로 기능이 없습니다.

... $ exit
$ getcap -n ./builder-setcap 
./builder-setcap cap_setfcap=p [rootid=1000]

여기의 매개변수는 -n사용자 네임스페이스 루트 ID를 나타냅니다. 네임스페이스 외부에는 다음과 같이 파일에 실제로 파일 기능이 없다는 것을 알 수 있습니다.

$ ./builder-setcap -r builder-setcap 
unable to set CAP_SETFCAP effective capability: Operation not permitted

당신이 원하는 것에 대한 가장 실현 가능한 접근 방식은 기능적으로 접근 방식 2와 동일한 빌드 호출 래퍼를 직접 작성하고 sudo capsh --user=$(whoami) --inh=cap_setfcap -- -c 'exec builder'접근 방식 2에 따라 바이너리를 준비하는 것입니다.builder-setcap

물론, builder-setcap특정 기능은 부여하고 다른 기능은 부여하지 않으려면 자신만의 버전을 작성하여 부여하려는 파일 기능을 필터링할 수도 있습니다. 전체 코드 복잡성 setcap은 다음과 같습니다.꽤 작은.

답변2

몇 년 전에도 비슷한 문제가 있었습니다.
직원은 로컬 네트워크 프로토콜 사용에 대한 통계를 생성하는 임무를 맡고 있습니다. 그는 Python을 사용하여 PACKET_RAW를 사용하여 패킷을 읽을 것입니다.
그러나 PACKET을 사용하려면 CAP_NET_RAW가 필요합니다.
CAP_NET_RAW를 Python에 제공하는 것은 다른 사람들이 그 특권으로부터 이익을 얻을 것이기 때문에 절대 금물입니다. 직원에게 sudo를 제공하는 것도 후배 직원이기 때문에 금기시됩니다.

내 해결책은 이를 위해 특별히 런처를 작성하는 것이었습니다. 런처에는 CAP_NET_RAW 권한이 있으며 Ambient 세트에서 CAP_NET_RAW를 사용하여 Python을 시작합니다. 런처 소유자는 루트이며 특정 사용자만 실행할 수 있고 다른 사람은 읽을 수 없습니다.
런처는 잘 작동하지만 안전성에 대한 디자인을 검토한 적이 없습니다.

관련 정보