dirty cow 포스팅을 수정하려고 dirty cow가 터지는 배포판을 찾던 중에 우분투 홈페이지에서 봇이 말을걸어왔다.
대답해줬더니 진짜 사람이 나타나서 응답 해 주는것이 아닌가?!
그러면서 최근 발견된 LPE CVE를 하나 알려주고 갔다.
테스트를 안해볼수가 없지 않은가?
그래서 CVE-2025-34263 포스팅을 시작하겠다.
1. CVE-2025-32463
이 취약점은 Local Privilege Escalation(LPE) 취약점이고,
sudo 1.9.14 ~ 1.9.17 버전에서 터진다.
2. 테스트
자 다음 사진을 보자.
여러분 보기 편하라고 마지막에 whoami 도 한번 해줬다.
우선 현재 sudo 버전은 1.9.15 로 취약점이 터지는 버전이다.
그리고 hacker 계정은 sudoers에 추가가 되어있지 않기 때문에 sudo 명령을 사용할 수 없다.
실제로 sudo 명령 사용에 다음 결과를 볼 수 있다.
hacker@CT-buntuslave:~/CVE-2025-32463_chwoot$ sudo su [sudo] password for hacker: hacker is not in the sudoers file. This incident has been reported to the administrator.
그리고 PoC실행 결과 귀신같이 root 쉘이 떨어지는 것을 볼 수 있다.
3. 코드 분석
|
|
필자가 사용한 PoC 코드다. https://github.com/pr0v3rbs/CVE-2025-32463_chwoot 주소에 공개되어 있다.
천천히 한번 분석해보겠다.
1. 임시폴더 생성
먼저 /tmp 경로에 sudowoot~ 어쩌고 하는 임시 경로를 만들고 있다. 만약 실패하면 실행을 종료한다.
2. 임시 폴더에 권한상승 코드 파일 생성
누가봐도 setuid, setgid로 root 권한의 shell을 실행하는 c코드다. woot133.c 라는 파일로 생성한다.
함수 이름은 woot 다. 기억하자.
3. 권한 상승 준비 작업
임시 폴더에서 woot/etc, libnss_ 경로를 만들고
woot/etc/nsswitch.conf 파일에 “passwd: /woot1337” 이라는 구문을 입력한다.
자 이때 /etc/nsswitch.conf 파일이 중요한데, nsswitch.conf 파일은 NSS의 설정 파일로, UNIX 계열 운영체제에서 어느 파일에 사용자 인증 정보가 기록되어있는지 설정을 저장하는 파일이다.
따라서 위 설정 파일을 분석하면 “사용자 인증 정보 는 /woot1337 파일에 있어” 라는 말과 같다는 것이다.
그리고는 /etc/group 파일을 woot/etc 경로로 복사한다.
앞서 작성했던 root 권한으로 쉘을 실행하는 코드를 빌드한다.
gcc가 뭔지 모른다면.. 이글을 읽기전에 기본 부터 공부하고 오세요 :)
옵션 | 의미 |
---|---|
-shared | 공유 라이브러리(Shared Object) 생성. 즉 .so 파일 생성 |
-fPIC | Position Independent Code. 공유 라이브러리( .so )는 메모리에 어디에 로드될지 모르므로, 코드가 위치 독립적으로 컴파일 |
-Wl,-init,woot | 링커(ld )에 -init 옵션 전달:libnss_*.so.2 로드 시 woot() 함수를 자동으로 실행하라는 의미 |
-o libnss_/woot1337.so.2 | 출력 파일 이름:libnss_/woot1337.so.2 로 저장 |
4. 권한 상승
sudo -R <경로> <명령> 형태의 명령을 볼 수 있다.
sudo -R 옵션은 chroot 기능을 수행한다. 루트 디렉토리를 변경하는 기능이다.
즉 현재 임시파일 경로에 있는 woot 경로를 root 로 만든다.
sudo -R woot woot 경로는 woot 경로를 root 로 만들고, 아까 우리가 c 파일에 작성했던 woot 함수를 실행하라는 뜻과 같다.
그런데, 이 때 우리는 3단계에서 woot 경로 안에 etc/nsswitch.conf 파일을 만들었고, “passwd: /woot1337” 이라는 내용을 작성했다.
그리고 woot1337.so.2 라는 공유 라이브러리를 libnss_ 경로 아래에 생성했다.
sudo는 사용자가 루트 권한으로 어떤 명령을 실행할 수 있는지 확인하기 위해 아래 두 가지를 반드시 수행한다.
sudo 명령이 사용자 정보를 확인하는 방법
1️⃣ 현재 사용자가 누구인지 확인 • getpwuid(), getpwnam(), getgrnam() 같은 함수 호출 → 이 함수들은 내부적으로 **glibc NSS(Name Service Switch)**를 통해 /etc/passwd나 LDAP 등에서 사용자 정보를 찾는다
2️⃣ sudoers 파일(/etc/sudoers)에 규칙이 있는지 확인 • 현재 사용자가 sudo로 실행할 수 있는지 판단하려면, 사용자 이름, 그룹 정보를 가져와야 함 → 이때도 NSS를 거친다.
📌 glibc(GNU C Library) : 리눅스에서 가장 기본적인 C 라이브러리로, 시스템 호출을 wrap 해 어플리케이션이 OS와 상호작용할 수 있게 해준다.
📌 NSS(Name Service Switch) : glibc 안에 포함된 모듈화된 조회 시스템으로 /etc/nsswitch.conf 파일을 통해 호스트 이름, 사용자 계정, 그룹, 메일 별칭 같은 것을 어디서 어떻게 검색할지를 결정한다.
📌 LDAP(Lightweight Directory Access Protocol) : 트리 구조로 된 중앙 디렉토리 서버(예: OpenLDAP)에서 사용자, 그룹, 호스트 등의 정보를 저장, 조회하는 프로토콜이다.(Active Directory도 LDAP 기반이다)
따라서 NSS가 nsswitch.conf 를 무조건 참고하게 되는데,
이때 -R woot 으로 인해 으로 root directory가 변경되었다. /tmp/sudowoot~/woot 로 말이다.
따라서 NSS는 /tmp/sudowoot~/woot/etc 경로에 존재하는 woot1337.so.2 모듈을 로드하고, woot 함수가 자동 실행된다.
그런데 woot 함수는 루트 권한의 bash를 실행하는 함수다.
게임 끝.
5. 배포판 별 차이
모든 운영체제를 테스트하진 않았는데, 일단 Ubuntu에서는 발생하지만, Rocky에서는 발생하지 않았다.
그 차이가 무엇일까? 다음과 같이 한 번 생각해볼 수 있다.
Rocky Linux는 RHEL을 일반 사용자도 사용할 수 있도록(자유 소프트웨어 정신) RHEL 배포판을 이용해 만든 무료 배포판이다.
따라서, 유료 라이선스 인증과 이에 따른 유료 소프트웨어 또는 유료 지원 등을 제외하면 거의 동일한 소스코드를 사용한다.
RHEL의 가장 큰 특징이라면 서버 운용을 염두에 둔 배포판으로 보안과 안정성에 가장 큰 가치를 두고
그만큼 최신 소프트웨어를 사용하기 보다는, 안정성이 입증된 소프트웨어만 적용해서 배포한다.
그래서 아마 -R 옵션을 사용하지 못하도록 막아두지 않았을까? 실제로 rocky에서는 다음과 같은 메세지를 확인할 수 있다.
📌📎📝💡📚🔑sudo: you are not permitted to use the -R option with woot
6. Mitigation(완화책)
우선은.. 포인트가 세 개 정도 있는거 같다.
- sudo 버전을 업데이트 하는 것.
- gcc 실행 권한을 제한 하는것.
- -R 옵션을 사용할 수 없도록 sudoers 파일을 수정하는 방법
또 다른 좋은 방지법이 있을까? 흠.. 고민해봐야겠다.