| 항목 | 내용 |
|---|---|
| CVE ID | CVE-2025-32463 |
| 영향 버전 | sudo 1.9.14 ~ 1.9.17 (모든 p 리비전) |
| CVSS v3.1 | 9.3 (Critical) — 배포판에 따라 7.8(High)로 재평가되기도 함 |
| 공개일 | 2025-06-30 |
| 발견자 | Rich Mirch (Stratascale Cyber Research Unit) |
| 별칭 | "chwoot" |
sudo 는 --chroot(-R) 옵션으로, 명령을 실행하기 전에 프로세스의 루트 디렉터리를 사용자가
지정한 디렉터리로 바꿔주는 기능을 제공했다. CVE-2025-32463은 이 옵션을 처리하는 과정에서
아직 sudoers 정책 검사(이 사용자가 애초에 sudo를 쓸 자격이 있는지)를 마치기도 전에
루트 디렉터리 전환이 먼저 일어나 버려서, 그 직후 이어지는 사용자 정보 조회 과정이 공격자가
완전히 통제하는 디렉터리 안의 설정 파일을 읽고, 그 설정이 가리키는 임의의 공유 라이브러리를
root 권한으로 로드해버리는 취약점이다. 로그인만 되어 있으면(sudoers에 아무 권한이
없어도) 로컬 사용자가 즉시 root shell을 얻을 수 있어 CVSS 9.3으로 평가됐다.
sudo -R <디렉터리> <명령> 은 지정한 명령을 실행하기 전에, 그 프로세스가 보는 파일시스템의
"루트(/)"를 사용자가 지정한 디렉터리로 바꿔버린다. 예를 들어 sudo -R /home/user/fakeroot id 를 실행하면, 그 안에서 실행되는 id 명령 입장에서는 /home/user/fakeroot 가 곧
/ 처럼 보인다. 이 기능은 원래 "격리된 환경에서 특정 도구를 실행하고 싶을 때"를 위한
편의 기능이었다.
리눅스에서 "이 사용자 이름(uid)이 실제로 누구인가"(passwd 조회), "이 그룹은 어떤
사용자들로 구성되는가"(group 조회) 같은 질문에 답하는 방식은 하나로 고정되어 있지 않다.
/etc/nsswitch.conf 파일이 "이런 종류의 조회를 할 때 어떤 방법(백엔드)을 쓸지" 를
정의한다. 일반적인 리눅스 시스템은 아래처럼 되어 있다.
passwd: files systemd
group: files systemd
여기서 files 는 "/etc/passwd 파일을 그대로 읽어라" 라는 뜻의 백엔드 이름이다.
glibc 는 이 백엔드 이름을 받아서, libnss_<백엔드 이름>.so.2 라는 이름의 공유
라이브러리를 동적으로 로드해서 실제 조회를 위임한다. 즉 nsswitch.conf 에 어떤 이름을
적느냐가, glibc 가 어떤 .so 파일을 찾아서 로드할지를 결정한다.
ELF 공유 라이브러리(.so)는 __attribute__((constructor)) 로 표시된 함수를 가질 수
있다. 이런 함수는 라이브러리가 로드되는 순간, 그 라이브러리를 로드한 프로세스와 같은
권한으로 자동 실행된다 — 그 라이브러리의 원래 목적(NSS 조회 등)과 상관없이, "로드되기만
하면" 실행된다는 것이 핵심이다.
전통적인 chroot() 시스템 콜은 프로세스가 보는 루트 디렉터리만 바꾼다. sudo는 버전
1.9.14부터 --chroot 처리 방식을 pivot_root() 기반으로 바꿨는데(더 견고한 격리를
의도한 것으로 보인다), 그 결과 실제로 프로세스의 루트를 사용자 지정 디렉터리로 전환하는
시점이, sudo가 sudoers 정책을 검사하기 위해 필요한 사용자/그룹 정보 조회보다 앞당겨졌다.
sudo가 sudoers 정책을 평가하려면 "이 uid가 어떤 사용자인지", "어떤 그룹에 속하는지" 같은
정보가 필요하고, 이는 내부적으로 NSS(passwd/group 조회)를 거친다. 문제는 1.9.14의
pivot_root 방식에서는 이 조회가 일어나는 시점에 프로세스가 이미 사용자 지정
디렉터리로 chroot된 상태였다는 것이다. 즉 NSS가 참고하는 /etc/nsswitch.conf 가
sudo 실행자 자신이 완전히 통제하는 파일이 되어버린다.
정상적으로 기대되는 순서
sudo 시작 (아직 root 디렉터리는 실제 /)
│
▼
sudoers 정책 검사
├─ 이 사용자가 sudo 를 쓸 자격이 있는가? (passwd/group 조회)
│ └─ /etc/nsswitch.conf 는 실제 시스템 파일 (신뢰 가능)
│
▼
자격이 확인되면 그제서야 --chroot 적용, 명령 실행
취약한 순서 (sudo 1.9.14 ~ 1.9.17, pivot_root 방식)
sudo 시작
│
▼
--chroot 대상 디렉터리로 pivot_root() 먼저 수행 ← 여기가 너무 이르다
│
▼
sudoers 정책 검사
├─ passwd/group 조회
│ └─ /etc/nsswitch.conf 가 공격자 디렉터리의 파일로 뒤바뀜 ← 오염
│
▼
NSS 가 공격자 지정 백엔드 이름으로 libnss_<이름>.so.2 로드 시도
│
▼
공격자가 그 이름의 라이브러리를 미리 그 디렉터리 안에 심어둠
│
▼
라이브러리 로드 → constructor 함수가 root 권한으로 실행됨
공개된 PoC(sudo-chwoot.sh, 발견자 Rich Mirch 작성) 는 다음과 같이 동작한다.
- 임시 작업 디렉터리 안에
woot/etc/nsswitch.conf를 만들고 그 내용을passwd: /woot1337로 채운다. 백엔드 이름에 슬래시(/)를 넣은 것이 핵심이다 — glibc 가 이 이름으로 라이브러리를 찾을 때libnss_/woot1337.so.2라는, 디렉터리 구성요소를 포함한 경로를 만들어내게 된다. woot/libnss_/woot1337.so.2위치에,constructor함수를 가진 공유 라이브러리를 미리 컴파일해 둔다. 이 함수는setreuid(0,0)/setregid(0,0)로 실제 uid/gid를 0(root)으로 바꾸고 셸을 실행한다.sudo -R woot woot를 실행한다 — 두 번째woot는 존재하지 않는 명령이라 최종 실행 자체는 실패하지만, 그 전에 이미 정책 검사 단계에서 NSS 조회가 일어나고, 그 시점에 위 라이브러리가 로드되어 constructor 가 실행되므로 공격은 이미 성공한 뒤다.- 결과적으로 sudoers 파일에 어떤 권한도 부여받지 않은 일반 사용자가 root 셸을 얻는다.
이 PoC가 인상적인 부분은, 최종적으로 실행하려던 명령(woot)이 사실 존재하지도 않는다는
점이다 — 공격은 "명령 실행" 단계가 아니라 그 이전의 "정책 검사를 위한 조회" 단계에서 이미
완료된다.
실제 수정 커밋(fffcc07c53, "Revert pivot_root and go back to prepending the new root
directory")은 커밋 메시지에서 문제를 정확히 짚는다: "우리는 루트 디렉터리를 바꾼
이후에 passwd/group 조회를 할 수 없다." 수정은 pivot_root() 로 실제 프로세스의
루트를 통째로 바꿔버리는 방식을 버리고, 예전 방식인 경로 앞에 새 루트 경로를
붙이는(prepend) 방식으로 되돌렸다 — 즉 chroot 대상 안에서 명령을 실행할 파일 경로만
조정할 뿐, sudo 프로세스 자체가 정책 검사를 마치기 전에 실제로 chroot되는 일은 없다.
패치 후 순서
sudo 시작 (root 디렉터리는 계속 실제 /)
│
▼
sudoers 정책 검사
├─ passwd/group 조회
│ └─ /etc/nsswitch.conf 는 여전히 실제 시스템 파일 ← 오염 안 됨
│
▼
자격 확인 후, 명령을 실행할 때만 경로에 chroot 대상을 prepend
(프로세스 자체의 루트를 바꾸는 실제 chroot/pivot_root는 이 시점 이후, 필요한 경우에만)
이와 함께 sudo 프로젝트는 --chroot 기능 자체를 deprecated(향후 완전히 제거 예정)
로 표시했다 — "심볼릭 링크가 있는 경로를 chroot 대상과 매칭할 때 완벽하게 처리되지 않는다"
는 한계를 커밋 메시지에서 스스로 인정하면서, 이 기능 자체의 위험성을 낮추는 방향(제거)을
택한 것이다. 이는 CVE-2025-32463과 함께 공개된 CVE-2025-32462(-h/--host 옵션 관련
별도 취약점)와 함께 sudo 1.9.17p1에서 수정됐다.
sudo-chwoot.shPoC 원문 — pr0v3rbs/CVE-2025-32463_chwoot (사용자 제공 참고 저장소)- 보완 PoC — zinzloun/CVE-2025-32463 (사용자 제공 참고 저장소)
- Local Privilege Escalation via chroot option — sudo.ws 공식 어드바이저리
- 수정 커밋 fffcc07c53 — sudo-project/sudo
- sudo 1.9.17p1 릴리스 노트 — sudo-project/sudo
- CVE-2025-32463 — NVD
- CVE-2025-32463 — Ubuntu Security
sudo.ws공식 어드바이저리 페이지는 이번 접근에서 403으로 막혀 원문을 직접 열람하지 못했다. 대신 공식 GitHub 릴리스 노트와 실제 fix 커밋 메시지(1차 자료)로 대체해 재구성했으므로 근거 자체는 확보됐지만, 발견자 본인의 서술 톤/추가 세부사항은 대조하지 못했다.- 1.9.14에서 왜
pivot_root방식으로 바꿨는지(원래 의도했던 격리 개선의 구체적 내용)는 이번에는 다루지 않았다.