목적: 프로그램(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
.
( 다음에서 bash
UID를 재설정하는 프로세스 에 대해 알아볼 수 있습니다.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단계 프로세스입니다.
당신이 했던 것처럼 실행 가능한 suid 비트를 설정하십시오.
setuid(uid_t uid)
팔로우하려면 전화하세요man setuid
.
목적이 apt-get인 경우 대신 apt-get을 사용할 수 있습니다 sudo
.