파일 · 권한 · 사용자 관리 43 / 50 · Part 5. 권한 상승과 Linux 보안
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정 analyst)
기초편 연계: 「리눅스 시스템 기초」 19. sudo와 su

1. 들어가며

42편에서 sudoers로 특정 명령만 허용할 수 있다고 했다. 그런데 "특정 명령만 허용"이 안전을 보장하지 않는다. 허용된 명령이 하위 명령이나 셸을 실행할 수 있으면, 그 하위 명령도 root 권한으로 실행되어 완전한 권한 상승이 된다.

이번 글에서는 NOPASSWD: /usr/bin/find 하나가 어떻게 root 권한으로 이어지는지 실제로 재현한다. 이것은 침투 테스트와 침해사고에서 매우 흔한 권한 상승 경로이며, GTFOBins 라는 데이터베이스로 정리되어 있다.

주의: 이 글의 목적은 방어 다. 실습은 격리된 테스트 컨테이너에서 진행하며, 이런 오설정을 탐지하고 제거 하는 것이 SOC 분석가의 역할이다. 실제 시스템 공격에 사용하지 않는다.


2. 핵심 개념

2-1. 왜 "명령 제한"이 뚫리는가

많은 표준 유닉스 도구는 하위 명령이나 셸을 실행하는 기능 을 내장한다.

도구셸 실행 기능
find-exec <명령>
vim/vi:!<명령>
less/more!<명령>
awksystem("<명령>")
tar--checkpoint-action=exec=<명령>

이 도구를 sudo로 허용하면, 도구가 실행하는 하위 명령도 root 권한 으로 동작한다. sudo는 "find를 root로 실행"을 허용했을 뿐이지만, find가 -exec로 sh를 띄우면 그 sh가 root 셸이 된다.

2-2. GTFOBins

GTFOBins는 이런 "정상 도구의 악용 기법"을 정리한 데이터베이스다. 방어자는 sudo로 허용할 명령을 여기서 미리 점검해, 셸 탈출이 가능한 도구를 배제한다.

2-3. 가능성과 실제의 구분

중요한 구분이 있다. sudo로 find를 허용한 설정 은 권한 상승 "가능성"이다. 실제 상승은 공격자가 그 기법을 실행했을 때 일어난다. SOC 관점에서는 (1) 위험한 설정을 사전에 점검(취약점 관리)하고, (2) 실제 악용을 로그로 탐지(사고 대응)한다. 둘은 다른 활동이다.


3. 동작 원리

sudo 오설정 → 권한 상승 (GTFOBins)

sudo find /etc/hostname -exec id \;의 처리 과정:

  1. sudo가 sudoers를 확인 → find가 허용되어 있음 → root 권한으로 find 실행
  2. find가 /etc/hostname을 찾고, 각 결과에 대해 -exec id 실행
  3. id는 find의 자식 프로세스로, find의 권한(root)을 상속 → euid=0
  4. id 대신 sh나 cat /etc/shadow를 넣으면 root 셸·root 파일 읽기

핵심은 3번이다. sudo는 find까지만 검사하고, find가 실행하는 하위 명령은 검사하지 않는다. find가 이미 root이므로 하위 명령도 root다. 이것이 "명령 경로 제한"이 뚫리는 원리다.


4. 명령어 실습

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

5. 실행 결과

실제 실행 결과 — Rocky Linux 9.8 · attacker@rocky9-lab — find 를 통한 권한 상승

텍스트 원본(실제 출력):

[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

6. 결과 해석

출력해석
(ALL) NOPASSWD: /usr/bin/findattacker는 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라 실제 해시는 없다). 이것이 "명령 제한이 무력화되는" 실증이다.


7. 보안 관점

방어방법
셸 탈출 도구 배제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/

8. 보안관제 관점

[취약점 관리]  위험 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 실제위험 설정(취약점 관리)과 실제 악용(사고 대응)을 구분해 보고

9. 실무에서 자주 발생하는 실수

실수결과예방
셸 탈출 도구를 sudo 허용완전한 권한 상승GTFOBins 점검 후 배제
"특정 명령만 허용"으로 안심하위 명령이 root안전한 명령만
NOPASSWD 남발무인증 권한 상승최소화
명령 인자에 와일드카드인자 주입구체적 인자 지정
위험 설정을 침해로만 다룸사전 예방 누락취약점 관리로 사전 점검

10. 실습 체크리스트

[ ] sudo 로 허용된 find 로 임의 명령을 root 실행했다
[ ] euid=0 으로 바뀌는 것을 확인했다
[ ] 셸 탈출 가능 도구 목록을 안다
[ ] GTFOBins 로 허용 명령을 점검하는 방법을 안다
[ ] 위험 sudo 설정을 grep 으로 찾을 수 있다
[ ] 설정(가능성)과 악용(실제)을 구분한다

11. 핵심 정리

  • "특정 명령만 sudo 허용"은 안전을 보장하지 않는다. 허용 명령이 셸 탈출·파일 읽기가 되면 완전한 root다.
  • find -exec, vim :!sh, less !cmd, awk system() 등 많은 표준 도구가 하위 명령을 실행한다.
  • 허용할 명령은 GTFOBins 로 사전 점검해 셸 탈출 가능 도구를 배제한다.
  • NOPASSWD를 최소화하고 명령 인자 와일드카드를 피한다.
  • 탐지는 sudo 프로세스의 자식이 셸·민감 파일 접근인지 auditd로 본다.
  • 위험 설정(취약점 관리)과 실제 악용(사고 대응)을 구분한다.

12. 다음 편 예고

다음 글 「44. ACL을 이용한 세밀한 권한 관리」 에서는 기본 권한 9비트로는 표현할 수 없는 "특정 사용자 한 명에게만 권한 부여"를 setfacl/getfacl로 구현하고, ACL의 mask와 유효 권한을 실습한다.


참고 자료


시리즈 이동

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글