저는 Debian Gnu/Linux의 다양한 기능을 실험하고 있습니다.
/bin/ping을 현재 작업 디렉토리에 복사했습니다. 물론, 그것은 작동하지 않았습니다. setuid 루트로 밝혀졌습니다.
그런 다음 핑을 통해 핑에 최소한의 기능(루트 아님)을 부여했고 sudo /sbin/setcap cap_net_raw=ep ./ping
핑이 예상대로 작동했습니다.
그런 다음 sudo /sbin/setcap -r ./ping
능력을 취소하십시오. 이제 예상대로 작동하지 않습니다.
이제 ping을 작동시키려고 합니다 capsh
.
capsh
권한이 없으므로 루트로 실행한 다음 루트 권한을 제거하여 다른 모든 권한을 제거해야 합니다.
secure-keep-caps
문서화되어 있지 않지만 capsh
기능 매뉴얼에 있는 이 기능 도 필요하다고 생각합니다 . 에서 비트 수를 얻었습니다 /usr/include/linux/securebits.h
. 출력에 --print
비트가 올바른 것으로 표시되므로 올바른 것처럼 보입니다 .
나는 몇 시간 동안 그것과 내가 지금까지 가지고 있는 것을 만지작거려 왔습니다.
sudo /sbin/capsh --keep=1 --secbits=0x10 --caps="cap_net_raw+epi" == --secbits=0x10 --user=${USER} --print -- -c "./ping localhost"
그러나 해당 기능이 없을 때 이런 일이 발생합니다 ping
. ping: icmp open socket: Operation not permitted
이는 또한 이것이 우리가 필요로 하는 것에 충분하지 않다는 것을 --print
보여줍니다 .Current: =p cap_net_raw+i
e
sudo /sbin/capsh --caps="cap_net_raw+epi" --print -- -c "./ping localhost"
기능을 이것으로 설정하는 Current: = cap_net_raw+eip
것은 맞지만 root
.
편집-1
나는 지금 시도했다sudo /sbin/capsh --keep=1 --secbits=0x11 --caps=cap_net_raw+epi --print -- -c "touch zz; ./ping -c1 localhost;"
그러면 다음이 생성됩니다.
touch: cannot touch `zz': Permission denied
ping: icmp open socket: Operation not permitted
첫 번째 오류는 예상되었지만 secure-noroot: yes
두 번째 오류는 예상되지 않았습니다.Current: = cap_net_raw+eip
편집 2
==
앞에 넣으면 --print
지금 표시되므로 Current: = cap_net_raw+i
이전 오류는 설명되지만 루트에서 전환할 때 전원이 꺼지는 이유는 설명되지 않으므로 이 secure-keep-caps
문제를 해결해야 한다고 생각합니다.
편집 3
내가 볼 수 있는 한, exec를 호출하면 valid(e)와 allowed(p)가 손실됩니다. 이는 당연한 일이지만, 안전캡을 씌워 분실을 방지해야 한다고 생각합니다. 내가 뭐 놓친 거 없니?
편집 4
더 많은 조사를 하고 설명서를 다시 읽었습니다. 일반적으로 사용자에서 전환할 때(또는 적용하여 루트를 일반 사용자로 만들 때) 기능이 손실되는 것처럼 보입니다. e
이는 호출할 때 재정의될 수 있으며, 이는 제가 아는 한 불변입니다.p
root
secure-noroot
secure-keep-caps
exec
제가 아는 한, 매뉴얼대로 작동하고 있습니다. 내가 아는 한, 유용한 일을 할 수 있는 방법은 없습니다 capsh
. 내가 아는 한, 함수를 사용하려면 다음이 필요합니다. 파일 함수를 사용하거나 을 사용하지 않는 함수 인식 프로그램이 있어야 합니다 exec
. 따라서 권한 있는 래퍼가 없습니다.
이제 내 질문은 내가 무엇을 놓치고 있고 capsh
내 목적이 무엇인지입니다.
편집 5
환경 기능에 대한 답변을 추가했습니다. 상속된 함수에서도 작동 할 수 있지만 capsh
유용하게 사용하려면 실행 파일에 설정해야 합니다. 나는 주변 기능이나 상속된 기능을 허용하지 않고 어떻게 capsh가 유용한 작업을 수행할 수 있는지 이해하지 못합니다.
버전:
capsh
패키지libcap2-bin
버전 부터1:2.22-1.2
- edit-3 이전에는 최신 버전을 받아서
capsh
사용git://git.debian.org/collab-maint/libcap2.git
하기 시작했습니다. uname -a
Linux richard-laptop 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1+deb7u2 x86_64 GNU/Linux
사용자 공간은 32비트입니다.
답변1
능력은 프로세스의 속성입니다. 전통적으로 세 가지 그룹이 있습니다.
- 허용된 기능(피): 현재 프로세스에서 "활성화"될 수 있는 기능입니다.
- 유효능력(이자형): 현재 프로세스에서 현재 사용할 수 있는 기능입니다.
- 유전능력(나): 상속될 수 있는 파일 기능입니다.
루트로 실행되는 프로그램은 항상 완전히 허용되고 유효한 기능을 가지므로 더 많은 기능을 "추가"해도 눈에 띄는 효과는 없습니다. (상속 가능한 기능 세트는 일반적으로 비어 있습니다.) setcap cap_net_raw+ep ping
기본적으로 이 프로그램을 실행하는 모든 사용자에 대해 이러한 기능을 활성화합니다.
불행하게도 이러한 함수는 실행된 파일에 바인딩되어 있으며 새 하위 프로세스를 실행한 후에는 유지되지 않습니다. 리눅스 4.3 출시환경 역량이를 통해 하위 프로세스가 기능을 상속받을 수 있습니다. (당신은 또한 볼 수 있습니다execve() 중 함수 변환존재하다능력(7).)
기능을 사용할 때 다음과 같은 함정에 유의하세요.
- 사용자를 루트에서 루트가 아닌 사용자로 변경하면 유효 및 허용된 권한이 지워집니다(참조:사용자 ID 변경이 기능에 미치는 영향존재하다능력(7)).
--keep=1
옵션을 사용하면capsh
컬렉션이 지워지는 것을 방지할 수 있습니다. - 사용자 또는 그룹 ID를 변경하면 환경 기능 세트가 지워집니다. 해결 방법: 환경 기능 추가뒤쪽에사용자 ID를 변경했지만앞으로자식 프로세스를 실행합니다.
- 허용된 기능 세트와 상속 가능한 기능 세트 모두에 이미 있는 경우에만 기능을 환경 기능 세트에 추가할 수 있습니다.
libcap 2.26부터 capsh
프로그램은 다음 옵션을 통해 환경 기능을 수정하는 기능을 얻었습니다 --addamb
.범죄). 옵션의 순서가 중요합니다. 사용 예:
sudo capsh --caps="cap_net_raw+eip cap_setpcap,cap_setuid,cap_setgid+ep" \
--keep=1 --user=nobody --addamb=cap_net_raw -- \
-c "./ping -c1 127.0.0.1"
팁: --print
명령줄의 어느 위치에나 이 옵션을 추가 capsh
하고 현재 기능을 확인할 수 있습니다.
참고: cap_setpcap
은 필수 --addamb
이고 옵션은 cap_setuid,cap_setgid
필수입니다 --user
.
답변2
Lekenstein의 답변은 정확하고 완전해 보이지만 환경 기능 세트가 해결하는 문제를 강조하기 위해 다른 관점에서 또 다른 설명을 제공하려고 노력할 것입니다.
다음을 실행할 때 sudo capsh --user=<some_user> --
함수를 다시 계산(및 제거할 수도 있음)하게 하는 두 가지 시스템 호출이 있습니다 .
setuid
: 에 따르면man capabilities
:
SECBIT_KEEP_CAPS 이 플래그를 설정하면 하나 이상의 0 UID를 가진 스레드가 모든 UID가 0이 아닌 값으로 전환될 때 기능을 유지할 수 있습니다. 이 플래그가 설정되지 않으면 이러한 UIDswitch로 인해 스레드가 모든 기능을 잃게 됩니다.
즉, 위 명령에서는 시스템 호출 시 SECBIT_KEEP_CAPS가 설정되어 있는지 capsh
확인해야 합니다 . setuid
그렇지 않으면 모든 능력이 상실됩니다. 그것이 바로 그 일 --keep=1
입니다. 이제 명령은 다음과 같습니다.sudo capsh --user=<some_user> --keep=1 --
execve
: 이 옵션을 사용하면--keep=1
모든 기능 세트(유효, 허용, 상속 가능)가 유지됩니다.까지...그러나 이execve
시스템 호출을 사용하면execve
덜 명확한 방식으로 권한이 다시 계산됩니다(루트가 아닌 사용자의 경우). 요컨대,환경 기능 세트를 추가하기 전에, 스레드가 호출된 후 집중되도록 "허용된" 함수의 경우 다음을execve
수행할 수 있습니다.- 파일에는 "허용" 세트의 기능이 있어야 합니다.. 이는 으로 수행할 수 있습니다
setcap cap_net_raw+p /bin/bash
. 그렇게 하면 스레드의 기능 세트(경계 세트 제외)가 더 이상 효과가 없기 때문에 전체 연습이 쓸모없게 됩니다. - 파일과 스레드 모두 "상속 가능" 세트에 기능이 있어야 합니다.. 이것이 문제를 해결할 것이라고 생각할 수도 있지만 , 이로 인해 권한이 없는 사용자가 호출할 때 스레드의 고유 권한이 제거되는 것으로
setcap cap_net_raw+i
나타났습니다 (현재 이에 대해 감사해야 합니다 ). 따라서 권한이 없는 사용자로서 이 조건을 충족할 수 있는 방법은 없습니다.execve
setuid
- 파일에는 "허용" 세트의 기능이 있어야 합니다.. 이는 으로 수행할 수 있습니다
Linux 4.3에 도입된 환경 기능을 사용하면 setuid
권한이 없는 사용자에게 스레드가 제공되고 이어서 스레드가 제공되더라도 스레드의 기능을 유지할 수 있습니다 execve
.파일 기능에 의존할 필요가 없습니다.
답변3
최근 커널의 호출 시간을 향상시키는 Lekenstein의 답변을 약간 조정했습니다.
sudo /usr/sbin/capsh --keep=1 --user=$USER \
--inh=cap_net_raw --addamb=cap_net_raw -- \
-c './ping -c1 localhost'
참고: sudoers 파일에 따라 이로 인해 환경이 엉망이 될 수 있습니다(예: HOME 변경). capsh는 uid를 변경하지만 sudo의 환경 변경 사항을 되돌리기 위해 아무 작업도 수행하지 않습니다.
그래서 무슨 일이야? 한 번 보자:
sudo /usr/sbin/capsh
: 유효한(이 작업을 수행할 수 있음) 집합과 허용된(유효한 집합에 추가할 수 있음) 집합의 모든 기능을 갖고 있지만 다른 집합에는 아무것도 없는 루트부터 시작합니다. 다른 컬렉션에 대해서는 나중에 논의하겠습니다.--keep=1
: 보안(읽기: 레거시) 이유로 인해 기능은 일반적으로 루트 -> 루트가 아닌 ID 스위치에서 상속되지 않습니다. 이 플래그는SECBIT_KEEP_CAPS
이를 수행하는 기능을 활성화합니다 . exec 시 자동으로 지워진다는 점은 주목할 가치가 있는데, 이는 좋은 생각입니다.--user=$USER
: UID 변경으로 모든 기능이 손실되는 것은 아니므로 루트 상태를 종료하겠습니다. 고맙게도SECBIT_KEEP_CAPS
우리는 루트와 같은 권한을 유지하고 있어 우리의 기능을 더욱 혼란스럽게 합니다.--inh=cap_net_raw
: 함수가 상속 가능하지 않으면 환경 함수로 설정할 수 없기 때문에 대상 함수를 상속 가능한 집합에 추가합니다(다음 항목 참조).--addamb=cap_net_raw
SECBIT_KEEP_CAPS
: 권한이 없는execve
(setuid/setgid/setcap 없음) 바이너리는아직우리의 능력에 대한 명확성은 특권으로 이어지지 않습니다. Linux 4.3에는 권한이 없는 바이너리를 실행할 때 유효하고 허용된 세트를 다시 추가하는 환경 세트가 추가되었습니다. 완벽한!-- -c ...
: 모든 설정이 완료되면 다음 매개변수를 사용하여 bash를 실행합니다. 기능 세트가 지워지고(bash에는 권한이 없으므로) 환경 세트가 다시 추가됩니다. 짜잔! 원시 소켓을 여는 데 필요한 권한이 있습니다.
capsh 에 대한 특수 인수를 사용하여 ==
이를 확인할 수 있으며, 이는 명령줄의 나머지 부분을 사용하여 자체적으로 실행되도록 합니다.
sudo /usr/sbin/capsh --keep=1 --user=$USER \
--inh=cap_net_raw --addamb=cap_net_raw == --print
Current: = cap_net_raw+eip
이는 cap_net_raw를 유효(실행 가능), 상속 가능(자식 프로세스에 전달 가능), 허용(가져오기 허용)으로 처리한다는 의미입니다. 그 안에 다른 기능은 없습니다.
기능 및 작동 방식에 대한 자세한 내용을 보려면 가장 좋은 방법은 다음과 같습니다.Function(7) 매뉴얼 페이지. 구체적으로 제목 Transformation of capabilities during execve()
.
답변4
이 setpriv
명령은 .com보다 처리하기가 더 쉽습니다 capsh
. 질문의 런타임 기능 부분 대신 이것을 사용하는 것을 고려하십시오. 부품에는 큰 영향을 미치지 않습니다 setcap
.
$ setpriv --help
Usage:
setpriv [options] <program> [<argument>...]
Run a program with different privilege settings.
이제 ping
Fedora 32의 권한이 없는 사용자로서 다음 작업을 수행합니다.
$ cp /usr/bin/ping .
$ ./ping -c 1 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.030 ms
그래서 나는 다음을 선택했습니다 tcptraceroute
.
$ tcptraceroute ::1
Running:
traceroute -T -O info ::1
You do not have enough privileges to use this traceroute method.
socket: Operation not permitted
그리고
$ sudo setpriv --no-new-privs --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' tcptraceroute ::1
Running:
traceroute -T -O info ::1
traceroute to ::1 (::1), 30 hops max, 80 byte packets
1 localhost (::1) <rst,ack> 0.041 ms 0.010 ms 0.007 ms
이 명령에는 광범위하게 상승된 권한이 없습니다.
$ sudo setpriv --no-new-privs --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' touch /root/secret
touch: cannot touch '/root/secret': Permission denied
$ sudo setpriv --no-new-privs --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' sudo touch /root/secret
sudo: PERM_SUDOERS: setresuid(-1, 1, -1): Operation not permitted
sudo: no valid sudoers sources found, quitting
sudo: error initializing audit plugin sudoers_audit
$ sudo setpriv --no-new-privs --inh-caps '-all,+net_raw' --bounding-set '-all,+net_raw' id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023