setuid 비트가 일관되지 않게 작동하는 이유는 무엇입니까?

setuid 비트가 일관되지 않게 작동하는 이유는 무엇입니까?

나는 코드를 작성했습니다 :

// a.c
#include <stdlib.h>
int main () {
  system("/bin/sh");
  return 0;
}

다음 명령을 사용하여 컴파일합니다.

gcc a.c -o a.out

setuid 비트를 추가했습니다:

sudo chown root.root a.out
sudo chmod 4755 a.out

Ubuntu 14.04에서는 일반 사용자로 실행하면 루트 권한을 얻습니다.

하지만 Ubuntu 16.04에서는 여전히 현재 사용자의 쉘을 얻습니다.

왜 다른가요?

답변1

변경된 점은 /bin/shbe bash또는 stay bash의 동작을 모방하는 dash추가 플래그가 있다는 것입니다 .-p

-pBash에서는 다음에 설명된 대로 setuid 권한을 포기하지 않기 위해 이 플래그가 필요합니다.매뉴얼 페이지:

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

이전에는 dash이것이 무시되었고 setuid 실행이 허용되었습니다(이를 방지하기 위한 조치가 취해지지 않았습니다). 하지만우분투 16.04 dash맨페이지다음과 유사한 추가 옵션 설명이 있습니다 bash.

-p priv
유효 uid가 uid와 일치하지 않으면 재설정을 시도하지 마십시오.잘못된 사용을 방지하기 위해 기본적으로 설정되어 있지 않습니다.system(3) 또는 popen(3)을 통한 Setuid 루트 프로그램.

이 옵션은 다음에는 존재하지 않습니다.상류(제안된 패치에 반응하지 않을 수 있습니다.*)도 Debian 9는 아니지만 2018년부터 패치된 Debian Buster에 있습니다.

"/bin/sh -p"참고: Stéphane Chazelas가 설명했듯이 특정 콘텐츠가 실행되므로 system()지금 전화하기에는 너무 늦었습니다. 따라서 setuid가 이미 삭제되었습니다.system()/bin/sh드 로버트이전 코드의 대답은 이 문제를 처리하는 방법을 설명합니다 system().

* 역사에 대한 자세한 내용여기그리고거기.

답변2

아마도 어떤 이유로 쉘은 시작 중에 유효 사용자 ID를 실제 사용자 ID로 다시 변경합니다. 다음을 추가하여 이를 확인할 수 있습니다.

/* needs _GNU_SOURCE; non-Linux users see setregid/setreuid instead */
uid_t euid = geteuid(), egid = getegid();
setresgid(egid, egid, egid);
setresuid(euid, euid, euid);

(실제로 Linux 에서도 system()실제 항목을 설정해야 할 수 있습니다. 저장된 항목은 그대로 두어도 괜찮습니다. 이것은 단지 무차별 디버깅일 뿐입니다. ID를 설정한 이유에 따라 물론 필요할 수도 있습니다. 실제 ID를 어딘가에 저장하려면.)

[또한 이것이 setid 작동 방식을 배우는 연습 이상의 것이라면 특히 쉘을 호출할 때 걱정해야 할 보안 문제가 많이 있습니다. 예를 들어, 셸의 동작에 영향을 미치는 많은 환경 변수가 있습니다. sudo가능하다면 기존 방법을 선호하세요. ]

관련 정보