setuid 루트가 작동하지 않습니다

setuid 루트가 작동하지 않습니다

목적: 프로그램(C++ 바이너리)을 루트로 실행합니다. 동일:우분투에서 SetUID 비트가 작동하지 않습니까?

그리고:실행 파일에 대해 setuid가 작동하지 않는 이유는 무엇입니까?

./a.out 출력:

E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied) E: Unable to lock the administration directory (/var/lib/dpkg/), are you root? psurana //output for "whoami" Look below for the code.

ls -l 출력:

-rwsrwxr-x 1 root root 46136 Jun 7 20:13 a.out

암호:

#include <string>
#include <stdlib.h>
int main(int argc, char *argv[]){
        std::string input = "apt-get install " + std::string(argv[1]);
        system(input.c_str());
        system("whoami");
        return 0;
}

세부 사항:: 프로그램을 컴파일하고 실행합니다 chown root:root a.out && chmod u+s a.out. 위의 ls -l 출력을 참조하세요.

아직 루트 권한이 없으며 코드의 system("whoami") 출력은 컴퓨터의 내 사용자 이름입니다.

이 두 가지 관련 질문을 읽어도 아무 것도 얻지 못했습니다. :(. 파일의 작성자와 소유자는 모두 루트입니다. setuid 비트가 설정되었으므로 작동해야 합니다. 파일 시스템도 외부가 아니며 내 컴퓨터입니다. 어떻게 작동하게 할 수 있나요?

답변1

다음과 같이 코드를 변경하면 유효한 실제 UID를 볼 수 있습니다.

#include <string>
#include <stdlib.h>
int main(int argc, char *argv[]){
        system("id");
        system("bash -c id");
        return 0;
}

내 시스템에서는 다음 두 줄이 반환됩니다(관련 없는 그룹을 건너뛰려면 ...를 사용합니다).

uid=1001(roaima) gid=1001(roaima) euid=0(root) groups=1001(roaima),24(cdrom),...,103(vboxsf)
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima),24(cdrom),...,103(vboxsf)

보시다시피 원래 호출은 id유효 UID 0(루트)을 반환하지만 실제 UID는 여전히 내 것입니다. 이것이 당신이 기대하는 것입니다.

bash -c id그러나 호출에 유효 UID가 제거되어 더 이상 루트로 실행되지 않는 것을 볼 수 있습니다 . 이는 man bash다음과 같이 기록됩니다.

쉘 시작 시 유효 사용자(그룹) ID가 실제 사용자(그룹) ID와 동일하지 않은 경우, -p이 옵션을 제공하지 않으면 시작 파일을 읽지 않으며 해당 환경에서 쉘 기능을 상속받지 않습니다. , SHELLOPTS, BASHOPTS, 환경에 CDPATH변수가 GLOBIGNORE나타나면 무시되고 유효 사용자 ID는 실제 사용자 ID로 설정됩니다. 호출 시 이 옵션을 제공 하면 -p시작 동작은 동일하지만 유효 사용자 ID가 재설정되지 않습니다.

따라서 여기서 해결 방법은 해당 플래그를 포함하는 것입니다 -p.

( 다음에서 bashUID를 재설정하는 프로세스 에 대해 알아볼 수 있습니다.setuid 비트는 bash에 영향을 미치지 않는 것 같습니다..)

그러나 이야기는 여기서 끝나지 않습니다. 왜냐하면 당신이 전화하지 않았다고 말할 것이라는 것을 알고 있기 때문입니다 bash. 불행하게도 그것은 system()당신을 대신하여 수행되는 일이며 당신이 지정하는 것을 허용하지 않습니다 -p.

strace루트 권한을 포기하지만 strace -f ./a.out무슨 일이 일어나고 있는지 알 수 있는 충분한 출력은 다음과 같습니다.

execve("./a.out", ["./a.out"], [/* 44 vars */]) = 0
brk(0)                                  = 0x24f1000
...
clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x7ffee0d42a1c) = 4619
wait4(4619, Process 4619 attached
 <unfinished ...>

이 시점에서 하위 프로세스가 시작되고 실행 준비가 완료됩니다.id

[pid  4619] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f100eb270e0}, NULL, 8) = 0
[pid  4619] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x7f100eb270e0}, NULL, 8) = 0
[pid  4619] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid  4619] execve("/bin/sh", ["sh", "-c", "id"], [/* 44 vars */]) = 0
[pid  4619] brk(0)                      = 0x7f849dd71000
[pid  4619] brk(0)                      = 0x7f849dd71000
...
[pid  4619] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f849d1d89d0) = 4620

이제 유효 UID를 삭제하는 쉘이 실행 중입니다. 다음으로 id명령을 실행하고 출력을 다음에 기록하는 것을 볼 수 있습니다 .표준 출력당신을 위한:

Process 4620 attached
[pid  4619] wait4(-1,  <unfinished ...>
[pid  4620] execve("/usr/bin/id", ["id"], [/* 44 vars */]) = 0
[pid  4620] brk(0)                      = 0x1785000
...
[pid  4620] write(1, "uid=1001(roaima) gid=1001(roaim"..., 149) = 149
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima),24(cdrom),...,103(vboxsf)
...

여기서 해결 방법은 exec*()시리즈 중 하나를 직접 사용하거나 해당 시리즈에 대한 호출을 포함하거나 , 예를 들어 암호 없이 대상 프로그램을 직접 호출할 수 있는 setuid(0)도구를 구성하는 것입니다 .sudo

이러한 옵션 중에서 저는 개인적으로 sudo솔루션을 선택하겠습니다. 이 문서의 작성자는 (의도하지 않은) 권한 상승 공격으로부터 코드가 안전한지 확인하는 데 오랜 시간을 보냈습니다.

답변2

이는 2단계 프로세스입니다.

  1. 당신이 했던 것처럼 실행 가능한 suid 비트를 설정하십시오.

  2. setuid(uid_t uid)팔로우하려면 전화하세요 man setuid.

목적이 apt-get인 경우 대신 apt-get을 사용할 수 있습니다 sudo.

관련 정보