파일 · 권한 · 사용자 관리 47 / 50 · Part 5. 권한 상승과 Linux 보안
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정analyst)
기초편 연계: 「리눅스 시스템 기초」 16. chmod와 권한 관리 · 30. Linux 명령어를 활용한 보안 점검
28편에서 SUID가 권한 상승의 핵심이라고 했고, 46편에서 world-writable SUID의 위험을 봤다. 이번 글은 SUID/SGID 파일을 체계적으로 점검 하는 방법이다.
핵심 원칙은 기준값(Baseline) 비교 다. 정상 SUID 파일은 passwd, sudo, su 등 시스템당 십수 개로 고정되어 있다. 이 목록을 기준값으로 저장해 두고 현재와 비교하면, 새로 생긴 SUID를 즉시 찾을 수 있다. 이번 글에서는 /tmp에 숨겨진 SUID bash 백도어를 3단계 점검으로 찾아내고, 해시로 그 정체를 확인한다.
/usr/bin, /usr/sbin)에 있다rpm -qf/dpkg -S로 확인)passwd, sudo, su, mount, umount, chage, gpasswd, newgrp| 신호 | 의미 |
|---|---|
비표준 위치 (/tmp, /home, /dev/shm) | 거의 항상 악성 |
| 패키지 미소속 | 수동 설치 또는 백도어 |
범용 도구의 SUID (bash, cp, find) | 권한 상승 도구 |
| 기준값에 없던 신규 SUID | 조사 대상 |
find로 모든 SUID/SGID 수집diff
SUID 점검이 효과적인 이유는 정상 SUID가 거의 변하지 않기 때문이다. 패키지 업데이트로 가끔 바뀌지만, 평소에는 고정이다. 그래서 초기 설치 직후의 SUID 목록을 기준값으로 저장해 두면, 이후 추가된 SUID는 모두 조사 대상이 된다.
# 초기 기준값 저장
find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null | sort > /var/lib/baseline/suid.txt
# 이후 비교
diff <(find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null | sort) /var/lib/baseline/suid.txt
위치 검증도 강력하다. 정상 SUID는 시스템 경로에만 있다. /tmp, /home, /dev/shm처럼 사용자가 쓸 수 있는 경로에 SUID가 있다면 거의 확실히 악성이다. 마지막으로 해시로 정체를 확인한다. SUID 파일의 해시가 /bin/bash와 같다면, 그것은 root 권한으로 실행되는 bash 사본 — 전형적인 권한 상승 백도어다(09편).
root 권한 실습.
/tmp/.hidden-shell(bash 사본 SUID)과/usr/local/bin/legit-suid를 배치했다.
# 1) 전체 SUID/SGID 목록
find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null | sort | head -25
# 2) SUID 개수
find / -xdev -perm -4000 -type f 2>/dev/null | wc -l
# 3) 비표준 위치의 SUID (이상)
find /tmp /var/tmp /dev/shm /home -xdev -perm -4000 -type f 2>/dev/null
# 4) 패키지에 속하지 않는 SUID (Rocky)
for f in $(find /usr/bin /usr/sbin -perm -4000 -type f 2>/dev/null); do
rpm -qf "$f" >/dev/null 2>&1 || echo "패키지 미소속: $f"
done
# 5) 숨겨진 SUID 백도어
ls -l /tmp/.hidden-shell

텍스트 원본(실제 출력):
[root@rocky9-lab ~]# echo "=== 전체 SUID/SGID 파일 목록 ==="
=== 전체 SUID/SGID 파일 목록 ===
[root@rocky9-lab ~]# find / -xdev \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null | sort | head -25
/tmp/.hidden-shell
/usr/bin/chage
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/su
/usr/bin/sudo
/usr/bin/umount
/usr/bin/write
/usr/libexec/utempter/utempter
/usr/local/bin/legit-suid
/usr/sbin/pam_timestamp_check
/usr/sbin/unix_chkpwd
/usr/sbin/userhelper
[root@rocky9-lab ~]# echo "=== SUID 개수 ==="
=== SUID 개수 ===
[root@rocky9-lab ~]# find / -xdev -perm -4000 -type f 2>/dev/null | wc -l
13
[root@rocky9-lab ~]# echo "=== 비표준 위치의 SUID (/tmp, /home, /dev/shm 등) — 이상 ==="
=== 비표준 위치의 SUID (/tmp, /home, /dev/shm 등) — 이상 ===
[root@rocky9-lab ~]# find /tmp /var/tmp /dev/shm /home -xdev -perm -4000 -type f 2>/dev/null
/tmp/.hidden-shell
[root@rocky9-lab ~]# echo "=== 패키지에 속하지 않는 SUID (Rocky) ==="
=== 패키지에 속하지 않는 SUID (Rocky) ===
[root@rocky9-lab ~]# for f in $(find /usr/bin /usr/sbin -perm -4000 -type f 2>/dev/null); do rpm -qf "$f" >/dev/null 2>&1 || echo "패키지 미소속: $f"; done
[root@rocky9-lab ~]# echo "=== SUID bash 사본 = 권한 상승 백도어 ==="
=== SUID bash 사본 = 권한 상승 백도어 ===
[root@rocky9-lab ~]# ls -l /tmp/.hidden-shell
-rwsr-xr-x 1 root root 1389024 Sep 24 15:07 /tmp/.hidden-shell
| 출력 | 해석 |
|---|---|
/usr/bin/passwd, sudo, su, mount 등 | 정상 SUID. 표준 경로, 패키지 소속 |
/tmp/.hidden-shell | 비표준 위치의 SUID → 강한 이상 신호 |
/usr/local/bin/legit-suid | 로컬 설치 SUID (정상일 수도, 확인 필요) |
| SUID 개수 13 | 이 컨테이너 기준. 실제 서버와 다름 → 시스템별 기준값 필요 |
비표준 위치 검색 → /tmp/.hidden-shell | /tmp의 SUID를 정확히 추출 |
ls -l /tmp/.hidden-shell → -rwsr-xr-x root root 1389024 | 크기가 bash와 같음. SUID bash 사본 의심 |
/tmp/.hidden-shell이 핵심 발견이다. /tmp는 정상 SUID가 있을 수 없는 위치다. 크기(1,389,024)가 bash와 일치하는 것도 단서다. 28편에서 본 것처럼, 이런 SUID bash 사본을 실행하면 root 셸이 열린다.
정체 확인은 해시로 한다.
sha256sum /tmp/.hidden-shell /bin/bash
# 두 해시가 같으면 = bash 사본 = 권한 상승 백도어
| 점검 | 방법 |
|---|---|
| 기준값 관리 | 초기 SUID 목록 저장, 정기 diff |
| 위치 검증 | /tmp·/home·/dev/shm의 SUID는 즉시 조사 |
| 소속 검증 | 패키지 미소속 SUID 확인 |
| 정체 확인 | 해시로 bash·범용 도구 사본 판별 |
| 완화 | 사용자 파티션 nosuid 마운트(28편) |
과장 금지: SUID가 있다고 무조건 취약점이 아니다. passwd·sudo 등 정상 SUID는 시스템 동작에 필수다. 판단 기준은 기준값과의 차이, 위치, 패키지 소속 이지 "SUID의 존재" 자체가 아니다.
[Baseline] find / -xdev \( -perm -4000 -o -perm -2000 \) -type f | sort > baseline/suid.txt
↓
[정기 점검] diff (현재, baseline) → 신규 SUID 목록
find /tmp /home /dev/shm -perm -4000 # 비표준 위치
↓
[Evidence] 신규 SUID: stat(ctime·소유자), sha256sum(→ 위협 인텔), 패키지 소속
↓
[Detection] chmod u+s 실행을 auditd 로 실시간 탐지 (23·28편)
↓
[Response] 비인가 SUID 제거(chmod u-s / rm), root 획득 경로 역추적(49편)
| 관점 | 내용 |
|---|---|
| IOC | 비표준 위치 SUID, bash·범용 도구와 동일 해시, 패키지 미소속 |
| Detection | chmod u+s(SUID 설정)를 auditd로 실시간 탐지 |
| Baseline | 배포판·버전별로 정상 SUID가 다르므로 시스템별 관리 |
| 실수 | 결과 | 예방 |
|---|---|---|
| SUID 존재만으로 취약점 판단 | 오탐 | 기준값·위치·소속으로 판단 |
| 기준값 없이 점검 | 신규 SUID 놓침 | 초기 Baseline 저장 |
| 배포판 공통 기준 사용 | 오탐/누락 | 시스템별 기준값 |
| SGID 누락 | 탐지 공백 | SUID+SGID 함께 |
| 해시 확인 생략 | 정체 미확인 | sha256sum으로 판별 |
[ ] find 로 전체 SUID/SGID 목록을 수집했다
[ ] 비표준 위치(/tmp 등)의 SUID 를 탐지했다
[ ] 패키지 미소속 SUID 를 확인했다
[ ] 해시로 bash 사본 백도어를 판별하는 법을 안다
[ ] 기준값 비교(diff) 방법을 안다
[ ] SUID 존재 자체가 취약점이 아님을 이해했다
/tmp·/home), 패키지 미소속, 범용 도구 SUID./tmp의 SUID, bash와 동일 해시의 SUID는 권한 상승 백도어다.sha256sum)로 SUID 파일의 정체를 확인한다.chmod u+s를 auditd로 실시간 탐지하고 시스템별 기준값을 관리한다.다음 글 「48. Linux 계정 보안 점검」 에서는 계정 측면의 종합 점검 — UID 0 중복, 빈 비밀번호, 잠기지 않은 시스템 계정, 로그인 셸을 가진 서비스 계정, 중복 UID — 을 하나의 점검 스크립트로 묶는다.