리눅스 시스템 기초 · 입문편 — 본문의 "N편"은 입문 과정 번호다. 번호별 글과 전체 250편 구성은 통합 로드맵에서 확인할 수 있다.
리눅스 시스템 기초 16 / 50 · Part 2. 파일·명령어·권한
실습 환경: Rocky Linux 9 (10.0.0.200)
이전 글: 15. Linux 파일 권한 이해
🔗 심화 시리즈 — 「파일 · 권한 · 사용자 관리」
이 주제를 더 깊게 다룬 실무형 보안 시리즈: 23. chmod 기호 방식 · 24. chmod 숫자 방식 (755·644·600) · 28. SUID 권한 · 29. SGID 권한 · 30. Sticky Bit
15편에서 권한 9비트(rwxrwxrwx)의 의미와 검사 순서를 정리했다. 이번 글은 이 권한을 바꾸는 chmod와, 9비트 앞에 붙는 특수 권한 3비트(SUID, SGID, Sticky Bit), 그리고 소유자·그룹·기타만으로 표현하기 어려운 권한을 위한 ACL 을 다룬다.
특수 권한 중 SUID 는 보안관제와 모의해킹 양쪽에서 가장 먼저 보는 항목이다. "일반 사용자가 실행해도 root 권한으로 동작하는 프로그램"이기 때문에, 설정이 잘못되면 그대로 권한 상승 경로가 된다.
| 방식 | 문법 | 예 | 결과 |
|---|---|---|---|
| 숫자 (절대) | 3~4자리 8진수 | chmod 640 app.conf | rw-r----- |
| 기호 (상대) | [ugoa][+-=][rwxst] | chmod g+w,o-rwx dir | 그룹 쓰기 추가, 기타 전부 제거 |
| 기호 | 의미 |
|---|---|
u / g / o / a | 소유자 / 그룹 / 기타 / 전체 |
+ / - / = | 추가 / 제거 / 정확히 지정 |
X (대문자) | 디렉터리이거나 이미 실행 권한이 있는 파일에만 x 부여 |
chmod -R로 하위 전체를 바꿀 때 chmod -R 755처럼 숫자를 쓰면 일반 파일까지 모두 실행 가능 해진다. 디렉터리와 파일을 구분하려면 chmod -R u=rwX,go=rX처럼 대문자 X를 쓴다.
| 비트 | 숫자 | 파일에 설정 시 | 디렉터리에 설정 시 | 대표 예 |
|---|---|---|---|---|
| SUID | 4000 | 파일 소유자 권한으로 실행 | (Linux에서는 무시) | /usr/bin/passwd, /usr/bin/sudo |
| SGID | 2000 | 파일 그룹 권한으로 실행 | 새 파일이 디렉터리의 그룹을 상속 | 공유 폴더 |
| Sticky | 1000 | (현재는 의미 없음) | 자기 소유 파일만 삭제·이름 변경 | /tmp |
표시 위치:
| 설정 | ls -l 표시 |
|---|---|
| SUID + 소유자 x | rws |
| SUID, 소유자 x 없음 | rwS (대문자 — 대개 설정 실수) |
| SGID + 그룹 x | r-s (그룹 칸) |
| Sticky + 기타 x | rwt (기타 칸) |
Linux 커널은
#!로 시작하는 스크립트의 SUID는 무시 한다. SUID가 의미 있는 것은 ELF 실행 파일이다.
기본 권한은 "소유자 1명, 그룹 1개, 나머지"만 표현할 수 있다. "감사 담당자 한 명에게만 로그 읽기 권한을 추가"처럼 세밀한 규칙은 ACL로 설정한다.
| 명령 | 용도 |
|---|---|
getfacl <파일> | ACL 조회 |
setfacl -m u:<사용자>:<권한> <파일> | 사용자 규칙 추가 |
setfacl -m g:<그룹>:<권한> <파일> | 그룹 규칙 추가 |
setfacl -x u:<사용자> <파일> | 규칙 제거 |
setfacl -b <파일> | ACL 전체 제거 |
ACL이 설정된 파일은 ls -l 권한 끝에 + 가 붙는다.

프로세스에는 두 종류의 사용자 ID가 있다.
| ID | 의미 |
|---|---|
| RUID (Real UID) | 실제로 실행한 사용자 |
| EUID (Effective UID) | 권한 검사에 쓰이는 사용자 |
보통은 둘이 같다. 하지만 SUID가 설정된 파일을 실행하면 커널이 EUID를 파일 소유자로 바꾼다. /usr/bin/passwd는 root 소유 SUID 파일이라, 일반 사용자 roror가 실행해도 EUID=0(root)이 되어 /etc/shadow를 수정할 수 있다. 대신 passwd 프로그램이 "자기 비밀번호만 바꾸도록" 내부에서 제한한다.
문제는 내부 제한이 없는 프로그램에 SUID가 붙었을 때 다. 예를 들어 파일을 열람하거나 외부 명령을 실행할 수 있는 프로그램(편집기, 페이저, 인터프리터, find 등)에 root SUID가 있으면, 그 기능을 통해 root 권한으로 임의 작업을 할 수 있다. 이런 프로그램 목록은 GTFOBins 같은 공개 자료에 정리되어 있어, 공격자와 방어자 모두 참고한다.
15편에서 "파일 삭제 권한은 디렉터리의 w"라고 했다. /tmp는 모두에게 w가 있으므로, Sticky Bit가 없으면 누구나 다른 사람의 파일을 지우거나 바꿔치기 할 수 있다. Sticky Bit는 삭제·이름 변경을 파일 소유자, 디렉터리 소유자, root 로 제한한다.
mkdir -p ~/lab16 && cd ~/lab16
# 1) 기호/숫자 표기
touch app.conf; chmod 640 app.conf; ls -l app.conf
chmod g+w,o-rwx app.conf; ls -l app.conf
mkdir -p tree/sub && touch tree/a.txt tree/sub/b.txt
chmod -R u=rwX,go=rX tree && ls -lR tree
# 2) 시스템의 대표 특수 권한 확인
ls -l /usr/bin/passwd /usr/bin/sudo
ls -ld /tmp /var/tmp
stat -c '%a %A %n' /usr/bin/passwd /tmp
# 3) SUID 동작 관찰 — RUID/EUID
passwd & # 입력 대기 상태로 두고
ps -o pid,ruser,euser,cmd -C passwd
kill %1
# 4) SGID 공유 디렉터리
sudo groupadd -f dev
sudo mkdir -p /srv/share && sudo chgrp dev /srv/share && sudo chmod 2775 /srv/share
ls -ld /srv/share # drwxrwsr-x
# 5) ACL — 특정 사용자에게만 로그 읽기 권한
sudo useradd -M -s /sbin/nologin auditor 2>/dev/null
sudo cp /var/log/messages /tmp/lab16_messages && sudo chmod 600 /tmp/lab16_messages
sudo setfacl -m u:auditor:r /tmp/lab16_messages
ls -l /tmp/lab16_messages # 권한 끝에 +
getfacl /tmp/lab16_messages
sudo rm -f /tmp/lab16_messages
# 6) SUID/SGID 전체 목록
sudo find / -xdev -type f \( -perm -4000 -o -perm -2000 \) -exec ls -l {} + 2>/dev/null
아래 출력은 형식 설명용 예시다.
① RUID/EUID
PID RUSER EUSER CMD
9021 roror root passwd
실행한 사람은 roror인데 권한 검사는 root로 이루어진다. SUID의 효과를 직접 확인할 수 있다.
② getfacl
# file: tmp/lab16_messages
# owner: root
# group: root
user::rw-
user:auditor:r--
group::---
mask::r--
other::---
mask는 ACL로 부여한 사용자·그룹 권한의 상한 이다. mask::r--면 ACL로 rw를 줘도 실제로는 r만 적용된다.
③ SUID 목록 판단
| 파일 | 판단 |
|---|---|
/usr/bin/passwd, /usr/bin/sudo, /usr/bin/su, /usr/bin/mount | 배포판 기본 — 패키지 소속 확인(rpm -qf) |
/tmp, /home, /var/www 아래의 SUID 파일 | 즉시 조사 — 정상적으로 존재할 이유가 거의 없음 |
| 편집기·인터프리터·파일 도구에 SUID | 권한 상승 경로 — 제거 대상 |
패키지 소속 없음 (rpm -qf → not owned) | 직접 설치했거나 악성 — 해시·출처 확인 |
| 위협 | 설명 | 대응 |
|---|---|---|
| SUID 권한 상승 | 쉘 실행·파일 조작 기능이 있는 프로그램에 root SUID | 불필요한 SUID 제거, 기준값 관리 |
| SUID 백도어 | 공격자가 root 획득 후 쉘 사본에 SUID를 붙여 재진입 경로 확보 | 새 SUID 파일 탐지 |
/tmp 파일 바꿔치기 | Sticky Bit 누락 시 다른 사용자 파일 삭제·교체 | find -perm -0002 ! -perm -1000 |
chmod -R 777 | 문제 해결용으로 전체 권한 개방 | 변경 감사(auditd perm_mod) |
| 과도한 ACL | 기본 권한만 보고 안전하다고 판단 | + 표시 확인, getfacl -R |
| 파티션 차원 방어 | 사용자 쓰기 가능 파티션의 SUID | nosuid 마운트 옵션 (6편) |
# 기준값 저장 (정상 상태에서 1회)
sudo find / -xdev -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null | sort \
| sudo tee /root/baseline_suid.txt > /dev/null
# 정기 점검 — 새로 생긴 SUID/SGID
sudo find / -xdev -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null | sort \
| comm -13 /root/baseline_suid.txt -
# 패키지 소속 확인
for f in $(sudo find / -xdev -type f -perm -4000 2>/dev/null); do
printf '%-40s %s\n' "$f" "$(rpm -qf "$f" 2>/dev/null || echo 'NOT OWNED')"
done
comm -13 A B는 B에만 있는 줄, 즉 새로 생긴 항목 을 출력한다.
# chmod 계열 System Call 중 SUID/SGID 비트를 설정하는 경우는 perm_mod 규칙(15편)으로 기록되고,
# 이후 ausearch 로 조회한다.
sudo ausearch -k perm_mod -i | grep -E 'chmod|a1=' | tail
[Event] 정기 점검: 새 SUID 파일 /var/tmp/.cache/bash (소유자 root)
↓
[확인] file → ELF, sha256sum 이 /usr/bin/bash 와 동일 → 쉘 사본
rpm -qf → NOT OWNED
↓
[타임라인] ctime/btime → 03:21 생성 / ausearch perm_mod → 같은 시각 chmod 4755
↓
[Root Cause] 03:10 SSH 로그인한 계정이 sudo 로 root 획득 후 SUID 쉘 생성 (지속성)
↓
[Response] 파일 증적 보존 후 제거, 해당 계정·sudo 권한 조치, 전체 SUID 기준값 재검증
chmod는 숫자(절대)와 기호(상대) 표기를 쓴다. 재귀 변경 시 대문자 X로 파일과 디렉터리를 구분한다.S/T는 실행 권한 없이 특수 비트만 있는 상태로, 대개 설정 실수다.+ 표시로 드러나며 getfacl로 확인한다. mask가 상한이다.다음 글 「17. chown과 파일 소유권」 에서는 파일의 소유자와 그룹을 바꾸는 chown, chgrp를 다룬다. 소유권이 잘못된 웹 루트가 웹셸로 이어지는 구조, 계정 삭제 후 남는 소유자 없는 파일(orphan file) 점검까지 정리한다.