내가 아는 한, 다양한 사용자 ID는 다음과 같습니다(프로세스 관점에서).
- 실제 사용자 ID: 프로세스를 소유한 사용자 ID
- 유효 사용자 ID: 현재 허용되는 것과 허용되지 않는 것을 결정하는 사용자 ID입니다.
- 저장된 사용자 ID: 기본적으로 원래의 유효 사용자 ID이며, 필요한 경우 원래의 유효 사용자 ID로 돌아갈 수 있습니다.
이제 두 가지 질문이 있습니다.
프로그램 시작 시 유효한 사용자 ID를 변수에 저장하면 저장할 필요가 없는 사용자 ID가 됩니까?
C 프로그램에서 저장된 사용자 ID를 검색하는 방법은 무엇입니까? 이 작업을 수행하는 기능을 찾을 수 없습니다.
답변1
프로그램 시작 시 유효한 사용자 ID를 변수에 저장하면 저장된 사용자 ID가 필요 없게 됩니까?
사용자 공간 프로그램이 무엇을 기억하는지가 아니라 커널이 어떤 권한을 사용하도록 허용하는지가 문제입니다. 사용자를 분리하려면 시스템이 프로세스에서 사용할 수 있는 사용자 ID를 제어해야 합니다. 그렇지 않으면 모든 프로세스에서 루트 권한을 요청할 수 있습니다.
C 프로그램에서 저장된 사용자 ID를 검색하는 방법은 무엇입니까? 이 작업을 수행하는 기능을 찾을 수 없습니다.
getuid()
이는 표준 함수(sum 만 해당 ) 를 사용하면 불가능합니다 geteuid()
. 적어도리눅스는getresuid()
그러나 세 개의 사용자 ID가 모두 반환됩니다.
어쨌든 일반적으로 읽을 필요는 없습니다. setuid 프로그램의 경우 실제 사용자 ID와 유효 사용자 ID 간 전환을 허용하므로 유효 사용자 ID의 복사본으로 시작됩니다.
setuid 프로그램에서 실제 사용자 ID는 프로그램을 실행하는 사용자의 ID이고, 유효하고 저장된 사용자 ID는 해당 프로그램을 소유한 사용자의 ID입니다. 유효 사용자 ID는 권한 확인에 매우 중요하므로 프로세스에서 일시적으로 권한을 포기하려는 경우 실제 사용자 ID와 저장된 사용자 ID 사이에서 유효 사용자 ID를 변경합니다.
프로세스가 사용자 ID를 변경할 수 있는지 확인하기 위해 커널은 저장된 사용자 ID를 어떤 방식으로 사용합니까? 이는 프로세스가 유효 사용자 ID를 변경하려고 시도할 때 커널이 저장된 사용자 ID를 확인하여 프로세스가 그렇게 할 수 있는지 확인한다는 의미입니까?
예. Linux 매뉴얼 페이지에 setuid()
이에 대한 언급이 있지만 다소 숨겨져 있습니다.
ERRORS
EPERM The user is not privileged and uid does not match the real
UID or saved set-user-ID of the calling process.
즉, (유효) 사용자 ID는 실제 ID 또는 저장된 ID 중 하나만 설정할 수 있습니다.
setreuid()
이에 대한 매뉴얼 페이지가 더 명확합니다.
Unprivileged processes may only set the effective user ID to the real
user ID, the effective user ID, or the saved set-user-ID.
답변2
저장된 uid가 변수인 경우.
유효한 또는 실제 uid에 복사할 수 있는 권한이 없기 때문에 일반 변수를 사용할 수 없습니다. 핵심할 수 없다일반 변수에서 복사할 수 있습니다. 이렇게 하면 원하는 대로 될 수 있습니다(괜찮습니다. 하지만 값이 이미 s 중 하나에 있는 경우에만 해당 uid
).
맞습니다. 유효 uid는 시스템 호출의 권한을 확인하는 데 사용됩니다. 예외는 setuid
/ 입니다 setgid
(함수 참조).
권한은 setuid
다음과 같습니다. ID를 이동할 수 있지만(한 uid에서 다른 uid로) 새 ID를 도입할 수는 없습니다( CAP_SETUID
이를 포함하는 :root가 없는 한).
그래서 일반 사용자로서. 하나 또는 두 개의 uid(실제 및 유효하지만 둘 다 동일할 수 있음)로 시작합니다. 서로 다른 경우 실제 항목을 유효한 항목으로 복사할 수 있습니다. 그렇게 하면 돌이킬 수 없이 하나만 남게 됩니다. 커널은 일반 변수에서 로드하는 것을 허용하지 않습니다. 따라서 유효한 콘텐츠를 저장 파일에 복사합니다. 나머지 실행에서는 원래의 유효한 콘텐츠를 저장하는데 이는 사실입니다. 이제 Effective-uid에 복사하여 유효하게 만들 수 있습니다. 얼마 후에는 하나를 버릴 수도 있습니다. 예를 들어 real을 다른 두 개에 복사합니다. 이제 되돌릴 수 없습니다. 이제 권한을 얻는 유일한 방법은 exec
setuid 바이너리를 사용하는 것입니다. (또는 새로운 기능을 갖춘 바이너리이지만 지금은 걱정하지 마세요).
suid를 얻으려면 다음을 사용할 수 있습니다 getresuid
.http://man7.org/linux/man-pages/man2/getresuid.2.html
실제로 일반 C 변수를 사용하면 됩니다. 그러나 uid 값이 uid 중 하나에 이미 포함되어 있지 않으면 해당 값을 추가할 수 없습니다.
/*setup UIDs*/
uid_t real_uid = getuid(void);
uid_t original_effective_uid = geteuid(void);
int err = setresuid(real_uid, original_effective_uid, original_effective_uid); /*this line not needed as done by kernel for setuid binary*/
#ifdef see_effect_of_no_suid
int err = setresuid(real_uid, original_effective_uid, real_uid);
#endif
while (true) {
err=seteuid(original_effective_uid);
/*do stuff as original_effective uid*/
err=seteuid(real_uid);
/*do stuff as real uid*/
}