exec를 통해 기능 전달

exec를 통해 기능 전달

exec()저는 Linux 기능이 다른 프로세스에 의해 전달 된 프로세스에 어떻게 전달되는지 이해하려고 노력하고 있습니다 . 내가 읽은 바에 따르면, exec 이후에 기능이 유지되려면 상속 가능한 세트에 있어야 합니다. 하지만 내가 확신할 수 없는 것은 해당 세트가 어떻게 채워지는가입니다.

내 목표는 일반적으로 루트가 필요한 일반 사용자로 프로그램을 실행할 수 있는 것입니다. 필요한 기능은 cap_dac_override개인 파일을 읽을 수 있다는 것입니다. 다른 기능을 부여하고 싶지 않습니다.

내 래퍼는 다음과 같습니다.

#include <unistd.h>

int main(int argc, char *argv[]) {
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

이는 결과 실행 파일에 대해 setuid 권한을 설정할 때 작동합니다.

~ $ sudo chown root: ./registerdns
~ $ sudo chmod u+s ./registerdns
~ $ ./registerdns 
Successfully registered hostname with DNS

하지만 setuid 대신 기능을 사용하고 싶습니다. cap_dac_override래퍼에 기능을 설정해 보았습니다 .

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

cap_dac_override또한 실행 파일 자체 의 기능 에 상속 가능 플래그를 설정해 보았습니다 net.

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ sudo setcap cap_dac_override=i /usr/bin/net
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

정확한 인수 집합을 사용할 때만 기능을 사용할 수 있도록 래퍼를 사용해야 합니다. 프로그램 net은 사용자에게 너무 광범위한 권한을 부여하는 위험할 수 있는 여러 가지 다른 작업을 수행합니다.

나는 상속이 어떻게 작동하는지 분명히 오해하고 있습니다. 래퍼를 설정하여 해당 기능을 교체 프로세스에 전달하여 사용할 수 있도록 하는 방법을 알 수 없는 것 같습니다. 나는 매뉴얼 페이지와 그 방법에 대한 수많은 다른 문서를 읽었습니다.~해야 한다나는 그것이 설명하는 일을 하고 있다고 생각했습니다.

답변1

래퍼에 +i를 설정하면~ 아니다CAP_INHERITABLE래퍼 프로세스 세트 에 기능을 추가 하면 통과되지 않습니다 exec. 따라서 호출하기 전에 수동 CAP_DAC_OVERRIDE으로 추가해야 했습니다 .CAP_INHERITABLEexecl

#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv[]) {
    cap_t caps = cap_get_proc();
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_value_t newcaps[1] = { CAP_DAC_OVERRIDE, };
    cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET);
    cap_set_proc(caps);
    printf("Capabilities: %s\n", cap_to_text(caps, NULL));
    cap_free(caps);
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

또한 cap_dac_override허용된 파일 기능 세트에 추가 /usr/bin/net하고 유효 비트를 설정해야 했습니다.

~ $ sudo setcap cap_dac_override=p ./registerdns
~ $ sudo setcap cap_dac_override=ei /usr/bin/net
~ $ ./registerdns
Capabilities = cap_dac_override+p
Capabilities = cap_dac_override+ip
Successfully registered hostname with DNS

이제 무슨 일이 일어나고 있는지 완전히 이해했다고 생각합니다.

  1. 래퍼는 CAP_DAC_OVERRIDE상속 가능한 세트에 추가할 수 있도록 허용된 세트가 필요합니다.
  2. 래퍼의 프로세스 상속 가능 집합은 파일 상속 가능 집합과 다르므로 파일에 +i를 설정하는 것은 쓸모가 없습니다. 래퍼는 / 사용 CAP_DAC_OVERRIDE에 명시적으로 추가해야 합니다 .CAP_INHERITABLEcap_set_flagcap_set_proc
  3. 파일 이 실제로 래퍼의 기능을 해당 세트로 상속할 수 있도록 상속 가능한 세트에 net있어야 합니다 . 또한 자동으로 승격되도록 유효 비트를 설정해야 합니다 .CAP_DAC_OVERRIDECAP_PERMITTEDCAP_EFFECTIVE

답변2

내 생각에는 두 가지가 모두 필요하다고 생각합니다.

setcap cap_dac_override+pe ./registerdns
setcap cap_dac_override+i /usr/bin/net

플래그 peregisterdns프로그램을 실행하면 해당 기능을 획득한다고 말합니다. 플래그 inet호출 프로그램에서 기능을 상속받을 수 있음을 나타냅니다.

관련 정보