[2과목 1장 01절] SetUID·SetGID·스티키 비트의 동작 원리와 ls 표기(s·S·t·T), 실제 시스템 사례를 실행 결과로 확인합니다.
🎯 이 강의 학습 목표
이 강은 2과목 1장 01절 파일 소유권과 권한 설정의 마지막입니다. 이 강을 마치면 SetUID·SetGID·스티키 비트가 각각 무엇을 하는지 설명하고, ls -l에서 s·S·t·T가 왜 갈리는지 판단하며, 8진수 4000·2000·1000을 써서 설정하고 find -perm으로 점검할 수 있게 됩니다.
특수 권한은 2차 시험에서 권한 영역의 절반 가까이를 차지합니다. 그런데 rwx만 알고 있으면 -rwsr-xr-x 같은 표기를 만났을 때 손도 못 댑니다. 다행히 규칙이 세 개뿐이고, 리눅스 안에 실제 사례가 있어 눈으로 확인하며 익힐 수 있습니다.
💡 왜 특수 권한이 필요한가 — passwd의 역설
문제 하나로 시작하겠습니다. 일반 사용자가 자기 암호를 바꾸려면 passwd 명령을 씁니다. 그런데 암호는 /etc/shadow에 저장되고, 10강에서 본 것처럼 이 파일은 root만 읽고 쓸 수 있습니다.
그렇다면 일반 사용자가 어떻게 자기 암호를 바꿀 수 있을까요? 사용자에게 /etc/shadow 쓰기 권한을 주면 남의 암호까지 고칠 수 있어 말이 안 됩니다. 그렇다고 못 바꾸게 하면 쓸 수 없는 시스템입니다.
해법이 SetUID입니다. "이 프로그램이 실행되는 동안만큼은, 실행한 사람이 아니라 프로그램 소유자의 권한으로 동작하라"는 표시를 파일에 붙이는 것입니다. /usr/bin/passwd의 소유자는 root이므로, 일반 사용자가 실행해도 실행 중에는 root 권한을 갖게 되어 /etc/shadow를 고칠 수 있습니다. 물론 passwd 프로그램 자체가 "본인 암호만 바꾸도록" 제한하고 있으므로 안전합니다.
즉 특수 권한은 "권한을 잠시 빌려주는 장치"입니다. 세 가지가 있습니다.
💡 세 가지 특수 권한
| 권한 | 8진수 | 붙는 자리 | 동작 |
|---|---|---|---|
| SetUID | 4000 | 소유자의 x 자리 | 실행 중 파일 소유자의 권한으로 동작 |
| SetGID | 2000 | 그룹의 x 자리 | 실행 파일: 실행 중 파일 그룹의 권한으로 동작 디렉터리: 안에 만드는 파일이 디렉터리의 그룹을 상속 |
| 스티키 비트 | 1000 | 기타의 x 자리 | 디렉터리: 파일 소유자와 root만 삭제 가능 |
SetGID는 대상에 따라 동작이 완전히 다릅니다. 실행 파일에 붙으면 SetUID의 그룹 버전이지만, 디렉터리에 붙으면 "그 안에서 만드는 파일이 부모 디렉터리의 그룹을 물려받는다"는 뜻이 됩니다. 15강에서 새 파일의 그룹은 만든 사람의 1차 그룹이 된다고 했는데, SetGID 디렉터리 안에서는 그 규칙이 바뀝니다. 팀 공유 디렉터리를 만들 때 필수적인 기능이며, 시험에서 두 동작을 구분해 묻습니다.
스티키 비트는 14강에서 예고한 문제를 해결합니다. 파일 삭제 권한은 파일이 아니라 디렉터리의 w가 결정합니다. 그런데 /tmp는 모두가 쓸 수 있어야 하므로 w를 열어 둬야 하고, 그러면 남의 임시 파일을 지울 수 있게 됩니다. 스티키 비트는 여기에 "쓰기는 되지만 삭제는 자기 파일만"이라는 예외를 겁니다. 그래서 /tmp에는 항상 스티키 비트가 붙어 있습니다.
💡 ls 표기 — s와 S, t와 T가 갈리는 기준
특수 권한은 기존 x 자리를 덮어써서 표시됩니다. 여기서 대소문자가 갈리는데, 규칙은 단 하나입니다.
| 표기 | 의미 | 원래 x |
|---|---|---|
s (소문자) | SetUID/SetGID 있음 | 있음 — 정상 동작 |
S (대문자) | SetUID/SetGID 있음 | 없음 — 실행이 안 되므로 사실상 무의미 |
t (소문자) | 스티키 비트 있음 | 있음 — 정상 동작 |
T (대문자) | 스티키 비트 있음 | 없음 |
"실행 권한이 함께 있으면 소문자, 없으면 대문자" 이 한 문장이 전부입니다. 대문자가 보인다는 것은 특수 권한은 걸었는데 실행 권한이 없어 제대로 동작하지 않는 상태라는 뜻이므로, 설정 실수를 발견하는 단서가 됩니다.
설정은 기존 세 자리 앞에 한 자리를 더 붙이는 방식입니다.
| 명령 | 결과 표기 | 의미 |
|---|---|---|
chmod 4755 file | -rwsr-xr-x | SetUID + 755 |
chmod 2755 file | -rwxr-sr-x | SetGID + 755 |
chmod 1777 dir | drwxrwxrwt | 스티키 + 777 |
chmod 6755 file | -rwsr-sr-x | SetUID + SetGID (4+2=6) |
기호 모드로도 가능합니다. chmod u+s(SetUID), chmod g+s(SetGID), chmod +t(스티키)입니다. 제거는 u-s·g-s·-t입니다.
💻 실습으로 확인하기
먼저 실제 시스템에 존재하는 사례를 봅니다. 아래는 우분투에서 실행한 결과입니다.
$ ls -l /usr/bin/passwd /usr/bin/su /usr/bin/sudo
-rwsr-xr-x 1 root root 64152 May 30 2024 /usr/bin/passwd
-rwsr-xr-x 1 root root 55680 Aug 20 01:47 /usr/bin/su
-rwsr-xr-x 1 root root 277936 Mar 2 2026 /usr/bin/sudo
세 파일 모두 소유자 자리가 rws입니다. SetUID가 걸려 있고 소유자는 root입니다. 앞에서 설명한 passwd의 원리가 그대로 확인됩니다. su와 sudo도 마찬가지인데, 11강에서 본 "권한을 빌려 쓰는 명령"들이 바로 이 SetUID 덕분에 동작한다는 것을 알 수 있습니다.
$ ls -ld /tmp /var/tmp
drwxrwxrwt 51 root root 12288 Sep 12 21:07 /tmp
drwxrwxrwt 6 root root 4096 Sep 12 20:51 /var/tmp
두 디렉터리 모두 rwxrwxrwt로 끝납니다. 권한은 777인데 마지막 x 자리가 t입니다. 즉 1777입니다. 누구나 파일을 만들 수 있지만(w), 삭제는 자기 파일만 가능합니다. /tmp를 예로 들면 다른 사용자가 만든 임시 파일을 여러분이 지울 수 없습니다.
$ find /usr/bin -perm -2000 -type f | head -4 | xargs ls -l
-rwxr-sr-x 1 root shadow 72184 May 30 2024 /usr/bin/chage
-rwxr-sr-x 1 root crontab 39664 Mar 31 2024 /usr/bin/crontab
-rwxr-sr-x 1 root shadow 27152 May 30 2024 /usr/bin/expiry
-rwxr-sr-x 1 root _ssh 309688 Sep 1 03:38 /usr/bin/ssh-agent
SetGID 실행 파일의 실제 사례입니다. 그룹 자리가 r-s입니다. chage는 그룹이 shadow인데, 10강에서 다룬 /etc/shadow의 암호 만료 정보를 읽어야 하기 때문입니다. crontab은 그룹이 crontab으로, 28강에서 배울 사용자 crontab 디렉터리에 접근하기 위한 것입니다. SetUID로 root 전체 권한을 주는 대신, SetGID로 필요한 그룹 권한만 주는 것이 더 안전한 설계라는 점을 보여 줍니다.
find /usr/bin -perm -2000에서 -2000의 앞 하이픈은 "이 비트를 포함하는"이라는 뜻입니다. 하이픈 없이 -perm 2000이라고 쓰면 "권한이 정확히 2000인 것"을 찾아 결과가 거의 안 나옵니다. 보안 점검에서는 항상 하이픈을 붙입니다.
$ ls -ld /var/local /var/mail
drwxrwsr-x 2 root staff 4096 Apr 22 2024 /var/local
drwxrwsr-x 2 root mail 4096 Aug 6 2025 /var/mail
SetGID 디렉터리의 사례입니다. /var/mail은 그룹이 mail인데, SetGID가 걸려 있으므로 이 안에 만들어지는 메일 파일은 전부 mail 그룹을 갖게 됩니다. 메일 프로그램이 그룹 권한으로 일관되게 접근할 수 있는 이유입니다.
이제 직접 설정해 보겠습니다. 아래는 /tmp/lm16에서 실행한 결과입니다.
$ chmod 4755 t.sh && ls -l t.sh
-rwsr-xr-x 1 chung chung 0 Sep 12 21:07 t.sh
$ chmod 2755 t.sh && ls -l t.sh
-rwxr-sr-x 1 chung chung 0 Sep 12 21:07 t.sh
$ chmod 1777 sd && ls -ld sd
drwxrwxrwt 2 chung chung 4096 Sep 12 21:07 sd
4755 → 소유자 자리에 s, 2755 → 그룹 자리에 s, 1777 → 기타 자리에 t입니다. 앞자리 숫자가 어느 자리의 x를 덮어쓰는지 이 세 줄로 완전히 정리됩니다.
마지막으로 대문자가 나오는 경우를 확인합니다.
$ chmod 4644 t.sh && ls -l t.sh
-rwSr--r-- 1 chung chung 0 Sep 12 21:07 t.sh
$ chmod 1666 sd && ls -ld sd
drw-rw-rwT 2 chung chung 4096 Sep 12 21:07 sd
4644는 SetUID를 걸었지만 소유자 권한이 rw-로 x가 없습니다. 그래서 소문자 s 대신 대문자 S가 표시되었습니다. 실행 권한이 없으니 애초에 실행되지 않고, 따라서 SetUID도 의미가 없습니다. 마찬가지로 1666은 스티키 비트를 걸었지만 기타 권한에 x가 없어 대문자 T가 나왔습니다. 대문자를 보면 "설정은 됐지만 동작하지 않는 상태"라고 읽으면 됩니다.
⚠️ 보안 관점 — SetUID는 양날의 칼
SetUID는 편리한 만큼 위험합니다. 소유자가 root인 SetUID 프로그램에 취약점이 있으면, 그것을 실행할 수 있는 누구나 root 권한을 얻을 수 있습니다. 실제로 권한 상승 공격의 상당수가 이 경로를 씁니다.
그래서 시스템 점검에서 SetUID 파일 목록을 주기적으로 확인합니다. 다음 명령이 표준적인 점검 방법입니다.
# SetUID가 걸린 파일 전체 찾기
find / -perm -4000 -type f 2>/dev/null
# SetUID 또는 SetGID가 걸린 파일 찾기
find / -perm /6000 -type f 2>/dev/null
# 스티키 비트가 걸린 디렉터리 찾기
find / -perm -1000 -type d 2>/dev/null
2>/dev/null은 접근 권한이 없는 디렉터리에서 나오는 오류 메시지를 버리는 표현으로, 21강 리다이렉션에서 다룹니다. -perm -4000은 "4000 비트를 포함", -perm /6000은 "4000 또는 2000 중 하나라도 있으면"이라는 뜻입니다.
점검 원칙은 두 가지입니다. 첫째, 목록에 낯선 파일이 있으면 의심합니다. 특히 사용자 홈 디렉터리나 /tmp에 SetUID 파일이 있으면 정상이 아닙니다. 둘째, 직접 만든 스크립트에 SetUID를 걸지 않습니다. 참고로 리눅스는 셸 스크립트에 대한 SetUID를 보안상 무시하므로, 스크립트에 4755를 걸어도 기대한 대로 동작하지 않습니다.
📝 핵심 요약 — 암기표
| 항목 | 핵심 |
|---|---|
| SetUID | 4000 · 소유자 x 자리 · 실행 중 파일 소유자 권한으로 |
| SetGID | 2000 · 그룹 x 자리 · 실행 파일=그룹 권한 / 디렉터리=그룹 상속 |
| 스티키 비트 | 1000 · 기타 x 자리 · 자기 파일만 삭제 가능 |
| 대소문자 규칙 | 실행 권한 있으면 소문자(s·t), 없으면 대문자(S·T) |
| 설정 예 | chmod 4755 · chmod 2755 · chmod 1777 · 기호는 u+s·g+s·+t |
| 대표 사례 | /usr/bin/passwd·su·sudo(SetUID) · /tmp=1777(스티키) |
| SetGID 사례 | /usr/bin/chage·crontab(파일) · /var/mail(디렉터리) |
| 점검 명령 | find / -perm -4000 -type f — 하이픈은 "포함" |
| 주의 | 셸 스크립트의 SetUID는 무시됨 · 낯선 SetUID 파일은 침해 신호 |
이것으로 권한 3개 강이 끝났습니다. 다음 17강부터는 같은 1장의 02절 파일 시스템의 구성과 관리로 넘어가, inode와 하드링크·심볼릭 링크를 다룹니다.
📋 실전 문제
1. /usr/bin/passwd의 권한이 -rwsr-xr-x인 이유로 가장 적절한 것은?
① 모든 사용자가 이 파일을 수정할 수 있도록 하기 위해
② 일반 사용자가 실행할 때 root 권한으로 /etc/shadow를 수정할 수 있도록 하기 위해
③ 파일을 삭제하지 못하게 보호하기 위해
④ 실행 속도를 높이기 위해
2. 스티키 비트가 설정된 /tmp의 8진수 권한으로 알맞은 것은?
① 0777 ② 1777 ③ 2777 ④ 4777
3. ls -l 결과가 -rwSr--r--일 때 이에 대한 설명으로 옳은 것은?
① SetGID가 설정되어 있고 정상 동작한다.
② SetUID가 설정되어 있으나 소유자에게 실행 권한이 없다.
③ 스티키 비트가 설정되어 있다.
④ 권한 설정 오류로 파일을 읽을 수 없다.
4. 디렉터리에 SetGID를 설정했을 때 나타나는 효과로 옳은 것은?
① 디렉터리 안의 파일을 소유자만 삭제할 수 있다.
② 디렉터리 안에서 생성되는 파일이 디렉터리의 그룹을 상속받는다.
③ 디렉터리가 실행 파일처럼 동작한다.
④ 디렉터리의 권한이 자동으로 777이 된다.
5. chmod 2755 script를 실행한 후의 권한 표기로 알맞은 것은?
① -rwsr-xr-x ② -rwxr-sr-x
③ -rwxr-xr-t ④ -rwSr-xr-x
6. 시스템 전체에서 SetUID가 설정된 일반 파일을 찾는 명령으로 알맞은 것은?
① find / -perm 4000 -type d
② find / -perm -4000 -type f
③ find / -perm -1000 -type f
④ find / -perm -2000 -type d
7. 스티키 비트가 설정된 디렉터리에서 파일을 삭제할 수 있는 주체로 옳은 것은?
① 디렉터리에 쓰기 권한이 있는 모든 사용자
② 파일의 소유자와 root
③ 파일이 속한 그룹의 모든 구성원
④ 아무도 삭제할 수 없다
8. 특수 권한에 대한 설명으로 틀린 것은?
① SetUID는 8진수 4000, SetGID는 2000, 스티키 비트는 1000이다.
② chmod 6755는 SetUID와 SetGID를 동시에 설정한다.
③ 셸 스크립트에 SetUID를 설정하면 root 권한으로 실행된다.
④ SetUID가 걸린 프로그램에 취약점이 있으면 권한 상승 공격에 악용될 수 있다.
✅ 정답과 해설
1. 정답 ②
소유자 자리의 s가 SetUID이며, 파일 소유자가 root이므로 일반 사용자가 실행해도 실행 중에는 root 권한을 갖습니다. 그래야 root만 쓸 수 있는 /etc/shadow에 자기 암호를 기록할 수 있습니다. ①은 권한 표기가 rws이지 일반 사용자 쓰기 권한이 아니므로 틀리고, ③은 스티키 비트의 역할입니다.
2. 정답 ②
스티키 비트가 1000이고 기본 권한이 777이므로 1777입니다. 실제 ls -ld /tmp의 결과도 drwxrwxrwt로 마지막 자리가 t입니다. ③의 2000은 SetGID, ④의 4000은 SetUID입니다.
3. 정답 ②
대문자 S는 소유자 자리에 나타나므로 SetUID이고, 대문자라는 것은 실행 권한(x)이 없다는 뜻입니다. 실행이 안 되므로 SetUID도 효과가 없는 상태입니다. ①은 SetGID라면 그룹 자리에 나타나야 하므로 틀리고, ③의 스티키 비트는 기타 자리에 t/T로 표시됩니다.
4. 정답 ②
디렉터리에 붙은 SetGID는 그 안에서 만들어지는 파일이 디렉터리의 그룹을 물려받게 합니다. 원래 새 파일의 그룹은 만든 사람의 1차 그룹이 되는데, 이 규칙을 덮어쓰는 것입니다. 팀 공유 디렉터리에 필수적입니다. ①은 스티키 비트의 효과입니다.
5. 정답 ②
앞자리 2는 SetGID이므로 그룹의 x 자리가 s로 바뀌어 -rwxr-sr-x가 됩니다. ①은 4755(SetUID)의 결과, ④는 SetUID를 걸었는데 소유자에 x가 없는 경우입니다.
6. 정답 ②
SetUID는 4000이고 일반 파일이므로 -type f입니다. 숫자 앞의 하이픈은 "해당 비트를 포함"을 뜻하며, 이것이 없으면 권한이 정확히 4000인 것만 찾아 결과가 나오지 않습니다. ①은 디렉터리를 찾고 하이픈도 없으며, ③의 1000은 스티키 비트, ④의 2000은 SetGID입니다.
7. 정답 ②
스티키 비트가 걸린 디렉터리에서는 파일의 소유자와 root만 삭제할 수 있습니다. 디렉터리에 쓰기 권한이 있어도 남의 파일은 지울 수 없으며, 이것이 /tmp를 모두가 공유하면서도 안전하게 쓸 수 있는 이유입니다.
8. 정답 ③
리눅스는 셸 스크립트에 대한 SetUID를 보안상 무시합니다. 스크립트는 실행 중 내용이 바뀔 수 있어 권한 상승 공격에 취약하기 때문입니다. 따라서 스크립트에 4755를 걸어도 root 권한으로 동작하지 않습니다. ①·②·④는 모두 옳으며, ②의 6755는 4000+2000이므로 SetUID와 SetGID가 동시에 걸립니다.
📚 참고 자료
관련 주제
- SetUID
- SetGID
- 스티키 비트
- 특수 권한
- 4755
- 1777
- find -perm
- 보안
- 자격증
- 자격증 강의
- 리눅스마스터 2급 완전정복
- 무료강의
- 무료 온라인 강의
- NUGUNA
- 누구나
📚 시리즈 전체 공유
리눅스마스터 2급 완전정복
이 강의가 속한 시리즈는 총 16강, 모두 무료입니다. 처음부터 배우려는 동료에게 시리즈 전체를 알려 주세요.
댓글
불러오는 중...
