파일 기능을 사용하여 setuid-root 바이너리가 필요하지 않은 젠투 강화 상자를 관리합니다 (예 : /bin/ping
CAP_NET_RAW 등).
사실, 내가 남긴 바이너리는 이것입니다.
abraxas ~ # find / -xdev -type f -perm -u=s
/usr/lib64/misc/glibc/pt_chown
abraxas ~ #
setuid 비트를 제거하거나 루트 파일 시스템을 다시 마운트 nosuid
하면 sshd 및 GNU Screen grantpt(3)
이 마스터 psudoterminals 를 호출 하고 glibc가 분명히이 프로그램을 실행하여 슬레이브 pseudoterminal을 chown하고 chmod하기 위해이 프로그램을 실행 /dev/pts/
합니다. 실패합니다.
문제는 파일 시스템이 마운트 grantpt(3)
된 Linux에서 devpts
그러한 도우미 바이너리가 필요하지 않다는 명시 적 맨 페이지입니다 . 커널은 자동으로 슬레이브의 UID & GID를 /dev/ptmx
(호출하여 getpt(3)
) 열린 프로세스의 실제 UID & GID로 설정합니다 .
나는 이것을 보여주기 위해 작은 예제 프로그램을 작성했다.
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int master;
char slave[16];
struct stat slavestat;
if ((master = getpt()) < 0) {
fprintf(stderr, "getpt: %m\n");
return 1;
}
printf("Opened a UNIX98 master terminal, fd = %d\n", master);
/* I am not going to call grantpt() because I am trying to
* demonstrate that it is not necessary with devpts mounted,
* the owners and mode will be set automatically by the kernel.
*/
if (unlockpt(master) < 0) {
fprintf(stderr, "unlockpt: %m\n");
return 2;
}
memset(slave, 0, sizeof(slave));
if (ptsname_r(master, slave, sizeof(slave)) < 0) {
fprintf(stderr, "ptsname: %m\n");
return 2;
}
printf("Device name of slave pseudoterminal: %s\n", slave);
if (stat(slave, &slavestat) < 0) {
fprintf(stderr, "stat: %m\n");
return 3;
}
printf("Information for device %s:\n", slave);
printf(" Owner UID: %d\n", slavestat.st_uid);
printf(" Owner GID: %d\n", slavestat.st_gid);
printf(" Octal mode: %04o\n", slavestat.st_mode & 00007777);
return 0;
}
앞에서 언급 한 프로그램에서 setuid 비트가 제거 된 상태에서 작동하는지 확인하십시오.
aaron@abraxas ~ $ id
uid=1000(aaron) gid=100(users) groups=100(users)
aaron@abraxas ~ $ ./ptytest
Opened a UNIX98 master terminal, fd = 3
Device name of slave pseudoterminal: /dev/pts/17
Information for device /dev/pts/17:
Owner UID: 1000
Owner GID: 100
Octal mode: 0620
이 문제를 해결하는 방법에 대한 몇 가지 아이디어 만 있습니다.
1) 단순히 0을 반환하는 골격으로 프로그램을 교체하십시오.
2) 내 libc에서 grantpt () 패치를 수행하면 아무것도하지 않습니다.
나는이 두 가지를 자동화 할 수는 있지만, 다른 하나에 대한 권장 사항이나이를 해결하는 방법에 대한 권장 사항이 있습니까?
이것이 해결되면 마침내 할 수 있습니다 mount -o remount,nosuid /
.
pty
(필요한대로)가 아니라 프로그램을 확인합니까?