본문 바로가기
Security/OverTheWire

Bandit Level 19 → Level 20 (setuid)

by curious week 2025. 12. 1.

문제

To gain access to the next level, you should use the setuid binary in the homedirectory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used the setuid binary.

## 문제 요구사항
다음 레벨에 액세스하려면 홈 디렉토리에서 setuid 바이너리를 사용해야 합니다. 
사용 방법을 알아보려면 인수 없이 실행하세요. 
이 레벨의 비밀번호는 setuid 바이너리를 사용한 후 일반적인 장소(/etc/bandit_pass)에서 찾을 수 있습니다.

## 내가 사용한 명령어
ssh bandit19@bandit.labs.overthewire.org -p 2220
./bandit20-do cat /etc/bandit_pass/bandit20

## 왜 이 명령어를 골랐는가
ls -l을 입력하면
파일타입 + 권한
-rwsr-x---   1 bandit20 bandit19 14884 Oct 14 09:26 bandit20-do
가 출력된다.
bandit20 사용자 권한으로 명령을 실행 해당 바이너리로 cat 명령을 실행하면 bandit20 패스워드 파일을 읽기 가능.
- : 일반 파일 (d면 디렉토리)
rws : x자리에 s가 있다면 setuid + 실행 가능이라는 뜻. 
같은 그룹 19가 r-x 실행 권한을 가지고 있다.
1 : 링크 수
bandit20 : 소유자
bandit19 : 그룹
14884 : 파일 크기
날짜/시간 + bandit20-do : 파일 이름


1. setuid란 무엇인가

setuid(set user ID)는 실행 파일에 특별한 비트를 설정하여, 그 프로그램을 ‘파일 소유자의 권한’으로 실행시키는 장치다.

즉:

사용자는 실행 권한만 있으면,
파일의 owner 권한으로 프로그램을 실행할 수 있다.

예)

-rwsr-xr-x root root /usr/bin/passwd

여기서 s가 setuid.
사용자는 root가 아니어도 /usr/bin/passwd 실행 시 root 권한으로 동작한다.


2. setuid가 왜 필요할까?

대부분의 setuid 프로그램은 일반 사용자가 접근할 수 없는 시스템 자원을 변경해야 하는 경우에 필요하다.

대표적인 예:

(1) 비밀번호 변경 프로그램 "passwd"

일반 사용자도 자신의 비밀번호를 바꿀 수 있어야 한다.
하지만 실제 비밀번호는 /etc/shadow 같은 root-only 파일에 저장돼 있다.

따라서:

  • 유저가 passwd 실행
  • passwd는 setuid root → root 권한으로 shadow 파일 수정
  • 유저는 root 권한이 없어도 비밀번호 변경 가능

필수적인 시스템 관리 기능을 안전하게 일반 사용자에게 제공하기 위한 기법

(2) mail, ping, sudo 등

  • ping은 raw socket을 열어야 하는데, 일반 유저는 raw socket 사용 불가 → setuid 필요
  • sudo는 root 권한을 상승시키는 역할 → setuid root
  • chsh, crontab 등도 setuid 프로그램

즉, setuid는 “권한을 빌려주는 장치”다.


3. setuid는 어떻게 들어가는가? (적용 방식)

파일에 setuid 비트를 올려놓는 방식은 아주 단순하다:

chmod u+s 파일명

또는 숫자 방식으로:

chmod 4755 파일명

여기서 4가 setuid.

권한 표시는 이렇게 나타난다:

  • 원래: -rwxr-xr-x
  • setuid 적용 후: -rwsr-xr-x

x 대신 s가 보이면 setuid 활성화.


4. setuid의 동작 원리 (OS 내부 관점)

리눅스에서 실행 파일을 실행하면:

  1. 프로세스의 실제 사용자 ID(real UID)는 실행한 사용자 ID
  2. setuid 비트가 켜져 있으면, 프로세스의 effective UID가 파일 owner의 UID로 변경됨
  3. 따라서 프로세스의 모든 파일 접근/권한 판단은 effective UID 기준으로 이루어진다

즉:

내가 bandit19로 실행했는데,
프로그램은 bandit20 권한으로 파일을 읽고 쓸 수 있게 된다.

5. setuid의 위험성

setuid는 강력하기 때문에 항상 위험을 동반한다.

(1) 작은 버그도 바로 “권한 상승 취약점”이 된다

setuid 프로그램이 root 권한일 때:

  • 버퍼 오버플로우
  • 입력값 미검증
  • 명령어 인젝션
  • 환경 변수 조작

이런 취약점이 있으면
일반 사용자가 root 권한을 뺏을 수 있다.

예시:

setuid root 프로그램이 system("ls") 같은 코드 사용
→ PATH 조작 → 악성 ls 실행 → root 탈취

(2) 환경 변수 오염 공격

setuid 프로그램은 안전하지 않은 환경 변수(PATH, LD_PRELOAD, LD_LIBRARY_PATH 등)를 무시해야 한다.

하지만 구현이 허술하면:

LD_PRELOAD=/malicious.so ./vulnerable-setuid

→ root 권한으로 악성 라이브러리 로드 → root 탈취

(3) 파일 오픈 순서 취약점 (TOCTOU)

  • 파일이 존재하는지 체크
  • 그 뒤에 열기
    이 사이에 심볼릭 링크를 바꿔치기하면 root 권한으로 임의 파일 덮어쓰기 가능.

(4) 디버깅/trace 공격

setuid는 디버그를 허용하면 안 된다.
그러므로 setuid 프로그램은 자식 프로세스 보호가 핵심.


6. setuid의 유사한 개념들

(1) setgid

group 권한 상승.
s가 그룹 영역에 나타남:

-rwxr-sr-x

예시:
mail 시스템, games 디렉토리 등이 setgid를 많이 사용.

(2) sticky bit (+t)

디렉토리에서 많이 쓰이는 개념.

대표적으로 /tmp:

drwxrwxrwt
  • 모든 사용자가 쓰기 가능
  • 하지만 삭제는 자신이 만든 파일만 삭제 가능
    → multi-user 시스템에서 안전하게 공용 디렉토리 제공하기 위한 것

(3) sudo / doas

setuid root 프로그램에
정교한 ACL(권한 규칙)을 붙인 진화된 형태.

즉:

  • setuid가 원시적인 권한 상승이라면
  • sudo/doas는 정책 기반 고급 권한 상승