설명할 수 없는 다음과 같은 현상을 관찰했습니다. CAP_SYS_ADMIN
기능 을 추가한 후에는 unshare
더 이상 글쓰기가 불가능합니다 /proc/self/setgroups
.
실제로 이 파일에 쓰기필요기능이 있지만 이는 사용자 네임스페이스를 변경하여 달성됩니다. 왜다음에 추가상위 프로세스의 기능으로 인해 파일 쓰기가 차단됩니까?
me@myhost:~$ unshare -r
root@myhost:~# exit
logout
me@myhost:~$ sudo setcap cap_sys_admin=ep /usr/bin/unshare
me@myhost:~$ unshare -r
unshare: cannot open /proc/self/setgroups: Permission denied
me@myhost:~$ sudo setcap cap_sys_admin= /usr/bin/unshare
me@myhost:~$ unshare -r
root@myhost:~#
덧붙여서:저는 커널 버전 4.4 및 util-linux(포함) 버전 unshare
2.27.1과 함께 Ubuntu 16.04.4 LTS를 실행하고 있습니다.
답변1
여기서 일어나는 일은 "공유 해제" 프로세스에 파일 쓰기 setgroups
(및 uid_maps
, ) 권한이 없다는 것입니다.gid_maps
외부사용자 네임스페이스.
해당 네임스페이스의 의사 파일은 /proc/<PID>
루트가 소유하며, 유효한 uid가 여전히 자신의 사용자인 것처럼 해당 파일에 쓸 수 있는 권한이 없습니다.
예를 들어 백그라운드에서 프로세스를 실행하고 실행 중에 파일의 권한을 확인하면 sleep
이를 쉽게 시각화할 수 있습니다 (그리고 정확히 동일하게 작동합니다).setgroups
uid_maps
gid_maps
먼저 추가 기능 없이 바이너리를 사용합니다.
$ cp /usr/bin/sleep .
$ ./sleep 10 &
[1] 11209
$ ls -l /proc/11209/setgroups
-rw-r--r--. 1 myuser myuser 0 Jul 31 12:33 /proc/11209/setgroups
[1]+ Done ./sleep 10
$
그런 다음 여기에 몇 가지 파일 기능을 추가하고 소유권 변경을 살펴보겠습니다.
$ sudo setcap cap_net_bind_service=ep sleep
$ ./sleep 10 &
[1] 11220
$ ls -l /proc/11220/setgroups
-rw-r--r--. 1 root root 0 Jul 31 12:34 /proc/11220/setgroups
[1]+ Done ./sleep 10
$
파일의 소유권은 /proc/<PID>
Linux 커널의 "dumpable" 플래그에 의해 제어됩니다. 이 플래그는 권한이 있는 프로세스에서 권한이 없는 사용자에게 정보가 유출되는 것을 방지하는 데 사용됩니다.
unshare
추가 기능을 실행하고 있지만 여전히 루트가 아닌 사용자를 사용하고 있다고 생각하면효과적인uid, 루트가 소유한 이러한 의사 파일에 대한 쓰기 액세스는 운영 체제의 일반적인 액세스 제어를 통해 차단됩니다.
PR_GET_DUMPABLE
다음을 사용하여 "dumpable" 플래그의 값을 확인할 수 있습니다.prctl(2)시스템 호출.
설명에서 PR_SET_DUMPABLE
다음 사항도 확인할 수 있습니다.
일반적으로 이 플래그는 1로 설정됩니다. 그러나
/proc/sys/fs/suid_dumpable
다음 조건에서는 파일에 포함된 현재 값(기본값은 0)으로 재설정됩니다.[...]
- 프로세스는
execve(2)
파일 기능을 가진 프로그램을 실행( )합니다.capabilities(7)
), 그러나 획득한 허용 용량이 프로세스에서 이미 허용한 용량을 초과하는 경우에만 해당됩니다.
이것이 바로 unshare
파일 기능을 갖춘 바이너리인 귀하의 경우입니다.
흥미롭게도 루트가 소유한 setuid 바이너리를 사용하면 unshare
이 문제가 발생하지 않습니다. 예, "dumpable" 플래그가 지워지고 그 안의 파일은 /proc/<PID>
루트가 소유하게 됩니다. 그러나 효과적인 uid를 고려하면반품setuid 바이너리를 실행할 때 루트 액세스가 허용됩니다.
unshare
이 경우 특정 설정을 처리할 수 없는 논리와 관련된 다른 문제가 발생합니다 (아마도 유효 uid와 실제 uid 간의 불일치와 관련됨).
$ cp /usr/bin/unshare .
$ sudo setcap -r unshare
$ sudo chown root:root unshare
$ sudo chmod 4711 unshare
$ ./unshare -r
-bash: cannot set uid to 65534: effective uid 0: Invalid argument
-bash-4.4$
또한 "덤프 가능" 플래그 지우기는 파일 기능이 설정된 바이너리를 실행하면 트리거됩니다. 다른 방식으로 추가 기능을 얻으면 이 문제가 발생하지 않을 수도 있습니다. 예를 들어, "환경" 기능을 사용하는 것은 새로운 사용자 네임스페이스에 대한 공유를 취소할 때 여전히 문제가 발생하지 않으면서 네임스페이스 외부에서 추가 기능을 얻을 수 있는 좋은 방법입니다.
(안타깝게도 아직 환경 기능에 대한 도구가 많지 않습니다. libcap
지원은 현재 대부분의 배포판에서 사용할 수 있는 최신 git 버전 2.25에서만 사용할 수 있습니다. capsh
꽤 낮은 수준이므로 얻기가 쉽지 않습니다. 좋아요.여기최신 환경 기능 사용에 대한 capsh
세부정보가 추가되었습니다. 나는 또한 그것을 시도했지만 systemd-run
거기에서도 환경 기능을 실제로 설정할 수 없었습니다. 그럼에도 불구하고 기능, 루트가 아닌 사용자 및 사용자 네임스페이스가 필요한 경우 이를 조사해야 합니다! )