파일 · 권한 · 사용자 관리 43 / 50 · Part 5. 권한 상승과 Linux 보안
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정analyst)
기초편 연계: 「리눅스 시스템 기초」 19. sudo와 su
42편에서 sudoers로 특정 명령만 허용할 수 있다고 했다. 그런데 "특정 명령만 허용"이 안전을 보장하지 않는다. 허용된 명령이 하위 명령이나 셸을 실행할 수 있으면, 그 하위 명령도 root 권한으로 실행되어 완전한 권한 상승이 된다.
이번 글에서는 NOPASSWD: /usr/bin/find 하나가 어떻게 root 권한으로 이어지는지 실제로 재현한다. 이것은 침투 테스트와 침해사고에서 매우 흔한 권한 상승 경로이며, GTFOBins 라는 데이터베이스로 정리되어 있다.
주의: 이 글의 목적은 방어 다. 실습은 격리된 테스트 컨테이너에서 진행하며, 이런 오설정을 탐지하고 제거 하는 것이 SOC 분석가의 역할이다. 실제 시스템 공격에 사용하지 않는다.
많은 표준 유닉스 도구는 하위 명령이나 셸을 실행하는 기능 을 내장한다.
| 도구 | 셸 실행 기능 |
|---|---|
find | -exec <명령> |
vim/vi | :!<명령> |
less/more | !<명령> |
awk | system("<명령>") |
tar | --checkpoint-action=exec=<명령> |
이 도구를 sudo로 허용하면, 도구가 실행하는 하위 명령도 root 권한 으로 동작한다. sudo는 "find를 root로 실행"을 허용했을 뿐이지만, find가 -exec로 sh를 띄우면 그 sh가 root 셸이 된다.
GTFOBins는 이런 "정상 도구의 악용 기법"을 정리한 데이터베이스다. 방어자는 sudo로 허용할 명령을 여기서 미리 점검해, 셸 탈출이 가능한 도구를 배제한다.
중요한 구분이 있다. sudo로 find를 허용한 설정 은 권한 상승 "가능성"이다. 실제 상승은 공격자가 그 기법을 실행했을 때 일어난다. SOC 관점에서는 (1) 위험한 설정을 사전에 점검(취약점 관리)하고, (2) 실제 악용을 로그로 탐지(사고 대응)한다. 둘은 다른 활동이다.

sudo find /etc/hostname -exec id \;의 처리 과정:
find가 허용되어 있음 → root 권한으로 find 실행/etc/hostname을 찾고, 각 결과에 대해 -exec id 실행id는 find의 자식 프로세스로, find의 권한(root)을 상속 → euid=0id 대신 sh나 cat /etc/shadow를 넣으면 root 셸·root 파일 읽기핵심은 3번이다. sudo는 find까지만 검사하고, find가 실행하는 하위 명령은 검사하지 않는다. find가 이미 root이므로 하위 명령도 root다. 이것이 "명령 경로 제한"이 뚫리는 원리다.
attacker계정에NOPASSWD: /usr/bin/find만 부여한 취약 설정 을 만들어, 그 결과를 확인한다. 격리된 테스트 컨테이너 전용이다.
# 1) 허용된 sudo 권한 확인
sudo -l
# 2) find 의 -exec 로 명령을 root 로 실행
sudo find /etc/hostname -exec id \;
# → euid=0(root): find 를 통해 root 명령 실행
# 3) 특정 명령 허용이 전체 권한으로 — shadow 읽기
sudo find /etc/hostname -exec cat /etc/shadow \; | head -1
# → root 전용 파일 읽기 성공 = 사실상 root

텍스트 원본(실제 출력):
[attacker@rocky9-lab ~]$ echo "=== 위험한 sudo 설정: NOPASSWD + find ==="
=== 위험한 sudo 설정: NOPASSWD + find ===
[attacker@rocky9-lab ~]$ sudo -l 2>/dev/null | tail -2
User attacker may run the following commands on rocky9-lab:
(ALL) NOPASSWD: /usr/bin/find
[attacker@rocky9-lab ~]$ echo "=== find 는 -exec 로 명령 실행 가능 → 권한 상승 ==="
=== find 는 -exec 로 명령 실행 가능 → 권한 상승 ===
[attacker@rocky9-lab ~]$ sudo find /etc/hostname -exec id \; 2>/dev/null
uid=0(root) gid=0(root) groups=0(root)
[attacker@rocky9-lab ~]$ echo " ↑ euid=0(root) — find 를 통해 root 명령 실행됨 (GTFOBins)"
↑ euid=0(root) — find 를 통해 root 명령 실행됨 (GTFOBins)
[attacker@rocky9-lab ~]$ echo "=== 왜 위험한가: 특정 명령 허용이 전체 권한으로 ==="
=== 왜 위험한가: 특정 명령 허용이 전체 권한으로 ===
[attacker@rocky9-lab ~]$ sudo find /etc/hostname -exec cat /etc/shadow \; 2>/dev/null | head -1
root:!locked::0:99999:7:::
[attacker@rocky9-lab ~]$ echo " ↑ shadow 읽기 성공 = 사실상 root"
↑ shadow 읽기 성공 = 사실상 root
| 출력 | 해석 |
|---|---|
(ALL) NOPASSWD: /usr/bin/find | attacker는 find만 sudo 허용 |
sudo find ... -exec id \; → uid=0(root) | find의 하위 명령 id가 root로 실행 |
sudo find ... -exec cat /etc/shadow \; → root:!locked... | root 전용 파일 읽기 성공 |
id가 uid=0(root)를 보여 준 것이 핵심이다. attacker는 find 하나만 허용받았지만, find의 -exec를 통해 임의 명령을 root로 실행했다. cat /etc/shadow로 해시 파일까지 읽었다(이 컨테이너의 root는 !locked라 실제 해시는 없다). 이것이 "명령 제한이 무력화되는" 실증이다.
| 방어 | 방법 |
|---|---|
| 셸 탈출 도구 배제 | find·vim·less·awk·tar·인터프리터를 sudo 허용 금지 |
| GTFOBins 사전 점검 | 허용할 명령을 GTFOBins에서 확인 |
| NOPASSWD 최소화 | 자동화에 꼭 필요한, 안전한 명령만 |
| 와일드카드 주의 | 명령 인자에 *는 인자 주입 위험 |
| I/O 로깅 | sudo의 세션 로깅(log_output)으로 실행 내용 기록 |
위험 sudo 설정 점검:
# NOPASSWD 규칙과 셸 탈출 가능 명령 점검
grep -rE 'NOPASSWD' /etc/sudoers /etc/sudoers.d/
grep -rE '(find|vim|vi|less|more|awk|tar|nmap|env|python|perl|ruby)' /etc/sudoers /etc/sudoers.d/
[취약점 관리] 위험 sudo 설정 사전 점검 (셸 탈출 가능 명령 허용 여부)
↓
[Detection] sudo 로그에서 셸 탈출 정황
- COMMAND 가 find ... -exec / vim / less 인데 이후 root 활동
- auditd execve: sudo 의 자식으로 sh·bash·cat /etc/shadow
↓
[Evidence] sudo 로그(user·COMMAND·시각), auditd 프로세스 트리(부모=find, 자식=sh)
↓
[판단] 허용 명령을 통한 셸 탈출 = 권한 상승 (ATT&CK T1548.003)
↓
[Response] sudoers 규칙 즉시 축소, 계정 조사, 침입 경로 역추적
| 관점 | 내용 |
|---|---|
| 탐지 포인트 | sudo 프로세스의 자식이 셸(sh/bash)이거나 민감 파일 접근 |
| auditd | 프로세스 트리로 "find → sh" 같은 탈출 체인 확인 |
| 가능성 vs 실제 | 위험 설정(취약점 관리)과 실제 악용(사고 대응)을 구분해 보고 |
| 실수 | 결과 | 예방 |
|---|---|---|
| 셸 탈출 도구를 sudo 허용 | 완전한 권한 상승 | GTFOBins 점검 후 배제 |
| "특정 명령만 허용"으로 안심 | 하위 명령이 root | 안전한 명령만 |
| NOPASSWD 남발 | 무인증 권한 상승 | 최소화 |
| 명령 인자에 와일드카드 | 인자 주입 | 구체적 인자 지정 |
| 위험 설정을 침해로만 다룸 | 사전 예방 누락 | 취약점 관리로 사전 점검 |
[ ] sudo 로 허용된 find 로 임의 명령을 root 실행했다
[ ] euid=0 으로 바뀌는 것을 확인했다
[ ] 셸 탈출 가능 도구 목록을 안다
[ ] GTFOBins 로 허용 명령을 점검하는 방법을 안다
[ ] 위험 sudo 설정을 grep 으로 찾을 수 있다
[ ] 설정(가능성)과 악용(실제)을 구분한다
find -exec, vim :!sh, less !cmd, awk system() 등 많은 표준 도구가 하위 명령을 실행한다.다음 글 「44. ACL을 이용한 세밀한 권한 관리」 에서는 기본 권한 9비트로는 표현할 수 없는 "특정 사용자 한 명에게만 권한 부여"를 setfacl/getfacl로 구현하고, ACL의 mask와 유효 권한을 실습한다.