SK쉴더스 로고
ADT캡스캡스홈
SK쉴더스

Proxmox VE 7 로그인 API 인증 우회 취약점 (CVE-2023-54391)

EQST Now | 2026.09.02

NOW Briefing

Brief 1 2023년 코드 변경으로 8.0.4부터 사라졌지만 당시에는 취약점으로 인식되지 않았던 Proxmox VE 로그인 API 인증 우회(CVE-2023-54391)가 2026년 9월 1일 공식 공개됐습니다. 지원이 끝난 7.x 계열에서는 로그인 요청의 이중 인증용 파라미터에 임의 값을 넣으면 비밀번호 검증이 실행되지 않습니다.
Brief 2 공격자는 자격증명 없이 2FA가 설정되지 않은 활성 계정으로 로그인할 수 있으며, 기본 관리자 계정인 root@pam으로 우회하면 하이퍼바이저와 가상 머신·컨테이너 전체가 노출될 수 있습니다. 벤더는 실제 악용 보고를 받았다고 밝혔고, PoC도 공개돼 있습니다.
Brief 3 근본 대응은 지원되는 Proxmox VE 릴리스로 업그레이드하는 것입니다. 즉시 업그레이드가 어렵다면 관리 인터페이스를 인터넷에서 분리하고 벤더가 제공한 임시 패치를 적용해야 합니다.

Proxmox VE 7 로그인 API 인증 우회 취약점 (CVE-2023-54391)

■ 개요

Proxmox VE는 가상 머신과 컨테이너를 한 물리 서버에서 운영하는 오픈소스 가상화 플랫폼으로, 국내에서도 구축과 한국어 교육을 제공하는 공식 파트너가 활동하고 있습니다. 관리자는 8006 포트로 열리는 웹 관리 인터페이스나 동일한 REST API로 노드와 게스트를 제어합니다. 이번 취약점은 그 로그인 API에 있습니다. 지원이 종료(EOL)된 Proxmox VE 7.0~7.4와 설치 후 패키지를 갱신하지 않은 8.0 초기 릴리스가 영향을 받으며, 패키지 기준으로는 libpve-access-control 7.0-7 이상 8.0.4 미만입니다.

기본 root@pam 계정이 활성 상태이고 2FA가 설정되지 않은 구성에서는 관리 인터페이스에 접근할 수 있는 것만으로 공격이 성립합니다. 벤더는 8006 포트에 직접 접근하거나 리버스 프록시를 경유하는 경우를 모두 노출 조건에 포함했습니다. 미인증 공격자는 2FA를 구성하지 않은 활성 계정으로 로그인할 수 있으며, 로그인 뒤 접근 범위는 해당 계정의 권한에 따릅니다. 벤더는 두 번째 인증 요소를 구성한 사용자와 현재 지원되는 릴리스는 영향을 받지 않는다고 명시했습니다.

Proxmox는 2023년 7월 LDAP 인증 영역 동기화 이후 2FA가 무력화되는 별개 문제를 고치는 과정에서 취약한 코드 경로도 함께 수정했고, 이 변경은 2023년 7월 20일 배포된 libpve-access-control 8.0.4에 포함됐습니다. 당시에는 인증 우회 취약점으로 인식되지 않았습니다. Proxmox는 2026년 9월 1일 보안 공지(PSA-2026-00043-1)를 내고 최근 이틀 사이 여러 독립 제보와 실제 악용 보고를 받았다고 밝혔습니다. PoC도 공개된 상태입니다.

■ 요약

항목 내용
CVE ID CVE-2023-54391 (로그인 API의 tfa-challenge 파라미터 미검증 인증 우회)
CVSS 점수 • CVSS v4.0 9.3
• CVSS v3.1 9.8
취약점 유형 CWE-304, 인증 필수 단계 누락
영향/위험 • 미인증 공격자가 두 번째 인증 요소가 없는 활성 계정으로 로그인 가능
• 기본 구성에서 root@pam 로그인으로 하이퍼바이저 관리 권한 확보 가능
• 관리 권한 확보 시 해당 노드의 가상 머신·컨테이너 접근 가능
• 벤더가 실제 환경 악용 보고를 접수했다고 밝힘
취약 버전 • Proxmox VE 7.0~7.4 (2024년 7월 지원 종료)
• Proxmox VE 8.0 초기 릴리스 (패키지 미갱신 상태)
• libpve-access-control 7.0-7 이상 8.0.4 미만
패치 버전 libpve-access-control 8.0.4 (2023년 7월 20일)

■ 기술 분석

Proxmox의 인증 처리 모듈 AccessControl.pm에는 로그인 요청을 처리하는 authenticate_user()가 있습니다. 요청에 tfa-challenge 값이 있으면 이 함수는 비밀번호를 검사하는 $plugin->authenticate_user(...)를 호출하지 않고 2차 인증 처리로 넘어갑니다. 정상적인 tfa-challenge는 1차 인증 뒤 서버가 발급한 서명 티켓이므로, 다음 단계에서 값의 유효성을 반드시 확인해야 합니다. 아래 코드는 지원이 끝난 7.x 계열에서 사용한 실제 분기입니다.

    if ($tfa_challenge) {
	# This is the 2nd factor, use the password for the OTP response.
	my $tfa_challenge = authenticate_2nd_new($username, $realm, $password, $tfa_challenge);
	return wantarray ? ($username, $tfa_challenge) : $username;
    }

    $plugin->authenticate_user($cfg, $realm, $ruid, $password);

문제는 authenticate_2nd_new_do()가 challenge를 검증하기 전에 사용자의 2FA 설정부터 확인한다는 점입니다. 7.x의 user_get_tfa()는 사용자와 인증 영역에 설정된 두 번째 요소가 없으면 값을 반환하지 않습니다. 호출부는 이 빈 값을 if (!defined($tfa_cfg)) 검사로 받아 2차 인증이 필요 없는 사용자로 해석하고 즉시 undef를 반환하므로, challenge 티켓의 서명을 검증하는 verify_ticket() 호출에는 아예 도달하지 못합니다. 비밀번호 검증은 앞 단계에서 생략됐고 티켓 검증은 뒤 단계에서 실행되지 않으므로, 임의의 문자열 하나로 인증이 성립하고 서버는 정상 인증 티켓을 발급합니다.

이 조기 반환 경로를 없앤 변경이 커밋 0f3d14d6입니다. 사용자 설정의 표식 여부와 무관하게 tfa.cfg를 항상 읽도록 바꾸면서 설정 객체가 비는 경우 자체가 사라졌고, 2FA를 강제하는 영역인지 검사하는 부분은 별도 조건으로 옮겼습니다. CVE 레코드가 패치 커밋으로 지목한 032e7d6d는 이어지는 후속 커밋으로, 영역이 2FA를 요구하는데 challenge가 생성되지 않으면 인증을 실패시키도록 검사 위치를 authenticate_2nd_new_do() 안으로 다시 옮겼습니다. 두 커밋 모두 2023년 7월 20일 배포된 8.0.4에 포함됐습니다.

-    if (!$keys) {
-	return if !$realm_tfa;
-	die "missing required 2nd keys\n";
-    }
-
     my $tfa_cfg = cfs_read_file('priv/tfa.cfg');
     if (defined($keys) && $keys !~ /^x(?:!.*)$/) {
 	add_old_keys_to_realm_tfa($username, $tfa_cfg, $realm_tfa, $keys);
     }
+
+    if ($realm_tfa) {
+	my $entries = $tfa_cfg->api_list_user_tfa($username);
+	die "missing required 2nd keys\n"
+	    if scalar(@$entries) == 0;
+    }
+
     return ($tfa_cfg, $realm_tfa);
 }

■ PoC

Nebu Security가 공개한 gist에는 취약한 Proxmox 관리 페이지의 브라우저 콘솔에서 실행하는 자바스크립트 PoC가 담겨 있습니다. 이 코드는 기본 관리자 계정인 root@pam을 대상으로 로그인 API에 임의의 tfa-challenge 값을 보내고, 응답 티켓을 PVEAuthCookie에 저장해 관리 UI 세션을 만듭니다. 유효한 비밀번호나 2FA 값은 필요하지 않습니다.

PoC 코드는 본문에 싣지 않았습니다. 원문은 참고 자료의 gist에서 확인할 수 있습니다.

⚠️ WARN

인터넷에 8006 포트가 노출됐던 취약 노드는 침해 가능성을 전제로 우선 점검해야 합니다.

■ 탐지 및 점검

/var/log/pveproxy/access.log에서 POST /api2/json/access/ticket 요청 중 200 응답을 받은 항목을 뽑아, 관리자가 사용하지 않는 출발지 IP가 있는지 확인합니다. 포럼에 접수된 사례에서는 이 로그 자체가 삭제돼 최초 침입 시점을 복원하지 못했으므로, 파일이 비어 있거나 사라진 것도 점검 대상입니다.

/var/log/daemon.log*/var/log/syslog*에서 successful auth for user 항목을 추출해 선행 실패 기록 없이 성공만 남은 로그인이 있는지 대조합니다. 이 취약점은 비밀번호 검증 단계를 건너뛰므로 무차별 대입 흔적이 남지 않습니다.

• 포럼에 접수된 침해 사례 기준으로 /etc/systemd/system/PVE-1.service, /var/lib/systemd/PVE-1, /var/lib/systemd/.hide/libhide.so의 존재 여부와 /etc/environment·/etc/profile.d/sysenv.sh에 추가된 LD_PRELOAD 항목을 점검합니다. 해당 사례에서는 gulf.moneroocean.stream:20004로 향하는 암호화폐 채굴 연결이 함께 확인됐습니다.

auth.log·btmp·wtmp·lastlog/dev/null로 심볼릭 링크되어 있거나 systemd 저널이 비어 있는지 확인합니다. 같은 사례에서 로그 파괴가 함께 관측됐으므로, 기록이 사라진 것 자체를 침해 신호로 다뤄야 합니다.

pvesh get /cluster/log로 콘솔·termproxy 세션 이력을 조회해 알려지지 않은 셸 접속이 있었는지 확인합니다. 다만 보고된 사례에서는 이 이력에도 관련 기록이 남아 있지 않았습니다.

■ 대응 방안

• 지원되는 Proxmox VE 9.x로 업그레이드합니다. libpve-access-control뿐 아니라 커널·QEMU·LXC를 포함한 전체 스택을 지원 버전으로 전환해야 합니다.

• 즉시 업그레이드가 불가능하면 8006 포트를 인터넷에서 내리고 VPN이나 방화벽 뒤로 옮깁니다. /etc/default/pveproxyALLOW_FROM·DENY_FROM·POLICY로 관리 대역만 허용하는 호스트 기반 접근 제어를 함께 적용합니다.

• 벤더가 보안 공지에 첨부한 임시 패치를 적용합니다. /usr/share/perl5/PVE/AccessControl.pmtfa-challenge 값을 서명된 티켓으로 검증하는 코드를 삽입하는 방식이며, 공지에 안내된 대로 적용 결과를 확인한 뒤 서비스를 재시작해야 합니다.

• 노출 이력이 있는 노드는 root@pam 비밀번호를 변경하고 API 토큰과 SSH 키를 모두 재발급합니다. 침해 흔적이 확인되면 호스트를 재설치하고 가상 머신·컨테이너의 무결성도 확인합니다.

• 모든 로그인 계정에 두 번째 인증 요소를 구성합니다. 벤더 확인 기준으로 2FA가 설정된 사용자는 이 우회의 대상이 되지 않지만, 취약한 버전을 계속 운영해도 된다는 뜻은 아닙니다.

💡 TIP

하이퍼바이저 관리 인터페이스는 인터넷에 직접 노출할 필요가 없는 서비스입니다.
이번 사고를 계기로 8006 외에 SSH(22), 클러스터 통신 포트가 외부로 열려 있는지 함께 점검하는 것이 좋습니다.

[참고 자료]

Proxmox 보안 공지 - EOL Proxmox VE 7 인증 우회

Proxmox 포럼 - PVE 7 인증 우회 신고 및 침해 사례 스레드

pve-access-control 커밋 - tfa.cfg 조건부 읽기 제거

pve-access-control 커밋 - 영역 필수 TFA 검사 이동

취약 버전 소스 - AccessControl.pm

VulnCheck 권고 - CVE-2023-54391

CVE 레코드 - CVE-2023-54391

공개 PoC - Nebu Security gist

pveproxy 매뉴얼 - 호스트 기반 접근 제어

Proxmox 공식 한국 파트너

Proxmox VE 지원 주기

  • #EQST_NOW
  • #취약점

관련 서비스

더 많은 보안 인사이트

SK쉴더스 유튜브 채널에서 확인하세요.

SK쉴더스 유튜브 채널에서 확인하세요.
보안 트렌드와 대응방법

매월 뉴스레터로 확인하세요.

매월 뉴스레터로 확인하세요.