system drop privilege when setuid
정말 고생했던 부분이다.
C
-rwsr-xr-x 1 root root 17320 Dec 24 2021 dreamsanta_present다음과 같은 setuid로 되어 있는 프로그램이 있다. 이때 이 dreamsanta_present 프로그램 내에서 system(”/bin/sh”) 이 실행될때 이 셸이 root로 실행될까? 정답은 아니다.
저 바이너리를 실행했을때 uid와 euid가 다르게 실행될 것이다.
/proc/self/status 파일을 보면,
C
Name: dreamsanta_pres
Umask: 0022
State: S (sleeping)
Tgid: 41
Ngid: 0
Pid: 41
PPid: 1
TracerPid: 0
Uid: 1000 0 0 0
Gid: 1000 1000 1000 1000
FDSize: 64
Groups:
NStgid: 41
NSpid: 41
NSpgid: 1
NSsid: 1다음과 같은 것을 알 수 있는데, Uid: 1000 0 0 0
다음 필드에서 각각, real / effective / saved-set / fsuid 을 의미한다.
- real UID = 1000: 이 프로세스를 시작한 실제 사용자(당신).
- effective UID = 0: 현재 권한 판단은 루트로 이루어짐(특권 있음).
- saved-set UID = 0: 한 번 루트가 된 이력을 저장. 필요 시 seteuid() 등으로 루트로 재상승 가능.
- fsuid = 0: 파일 시스템 접근 권한 판단도 루트로 동작.
당연히 알겠지만, setuid 때문에 현재 real uid랑 effective UID 다르다.
이럴때 셸을 실행했을때 , root 셸을 딸 수 있게 된다면 너무 보안적으로 위험하게 된다.
따라서 리눅스는 다음과 같은 보안을 적용시켜났다.
바로 real UID ≠ effective UID 라면 실행되는 shell 프로세스의 uid를 real UID의 권한으로 drop을 하는 것이다.
따라서 셸을 실행해도,
C
id
uid=1000(ctf) gid=1000(ctf) groups=1000(ctf)다음과 같이 되게 된다.
이때 진행할 수 있는 추가 취약점은 capability leak 등이 있다.