Red Hat JBoss EAP RichFaces - unserialize + el = RCE - 【CVE-2018-14667】
字数 1735 2025-08-22 18:37:15

Red Hat JBoss EAP RichFaces 反序列化漏洞分析 (CVE-2018-14667)

漏洞概述

CVE-2018-14667 是 Red Hat JBoss EAP 中 RichFaces 框架的一个远程代码执行漏洞,评级为"Critical"。该漏洞允许未经身份验证的攻击者通过发送特制的对象(包含恶意表达式)来绕过白名单保护,触发反序列化操作,最终导致任意Java代码执行。

漏洞环境

  • 测试环境:
    • Tomcat 8.5.24
    • JDK 1.8.144
    • richfaces-demo-3.3.0.GA-tomcat6.war

漏洞触发流程

  1. 入口点 - BaseFilter#doFilter

    • 请求通过JBoss SeamFilter → Ajax4jsfFilter → BaseFilter
    • 关键判断逻辑决定是否进入InternetResourceService
  2. 核心处理 - InternetResourceService#serviceResource

    • 从URL获取resourceKey
    • 通过ResourceBuilderImpl获取resource和resourceDataForKey
    • 根据条件调用resource.getLastModified、resource.getExpired或resource.send
  3. 反序列化绕过 - ResourceBuilderImpl

    • 对URL中的数据进行base64解码和zip解压缩
    • 使用LookAheadObjectInputStream进行反序列化,但有白名单限制
    • 白名单检查resource-serialization.properties文件
  4. 资源生成 - ResourceBuilderImpl

    • 从URL路径生成resource
    • 使用UserResource类(在白名单中)作为反序列化载体
  5. EL表达式注入 - UserResource

    • 反序列化后的UriData对象中的表达式会被解析
    • 通过getLastModified、getExpired或send方法触发表达式执行

漏洞利用分析

关键利用点

  1. UserResource.UriData 类:

    • 包含createContent、value、modified和expires字段
    • 这些字段可以包含EL表达式
  2. 表达式执行触发点:

    • getLastModified() - 解析modified字段
    • getExpired() - 解析expires字段
    • send() - 解析createContent字段
  3. 反序列化控制:

    • 通过/DATA/路径后的base64编码数据控制反序列化内容
    • 数据经过base64解码和zip解压缩

利用条件

  1. 目标系统使用了RichFaces 3.x至3.3.4版本
  2. 系统中包含a4j:mediaOutput标签的页面
  3. 能够获取到mediaOutput生成的资源路径

漏洞复现步骤

  1. 获取资源路径:

    • 访问包含a4j:mediaOutput标签的页面
    • 从响应中提取src属性值(如:/DATA/eAHF...jsf)
  2. 构造恶意payload:

    • 使用提供的POC生成代码
    • 替换其中的EL表达式为恶意代码
    • 生成base64编码的压缩payload
  3. 发送恶意请求:

    • 使用获取的资源路径前半部分
    • 拼接生成的恶意payload
    • 发送到目标服务器

POC生成代码分析

import com.sun.facelets.el.TagMethodExpression;
import com.sun.facelets.el.TagValueExpression;
// ... 其他import省略

public class Main {
    public static void main(String[] args) throws Exception {
        // 1. 设置恶意EL表达式
        String pocEL = "#{request.getClass().getClassLoader().loadClass(\"java.lang.Runtime\").getMethod(\"getRuntime\").invoke(null).exec(\"calc\")}";
        
        // 2. 修改MethodExpression的serialVersionUID(适配Tomcat 8.5.24)
        // ... 反射修改代码省略
        
        // 3. 构造createContent MethodExpression
        MethodExpressionImpl mei = new MethodExpressionImpl(pocEL, null, null, null, null, new Class[]{OutputStream.class, Object.class});
        // ... 包装过程省略
        
        // 4. 构造modified和expires表达式
        // ... 构造过程省略
        
        // 5. 创建恶意UriData对象
        UserResource.UriData uriData = new UserResource.UriData();
        // 通过反射设置各字段
        
        // 6. 序列化并编码payload
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(uriData);
        // ... 压缩和base64编码过程省略
        
        // 7. 生成最终payload
        String poc = "/DATA/" + new String(dataArray, "ISO-8859-1") + ".jsf";
        System.out.println(poc);
    }
}

漏洞修复建议

  1. 升级到RichFaces 3.3.4以上版本
  2. 禁用不必要的RichFaces功能
  3. 加强输入验证和过滤
  4. 限制反序列化操作

技术要点总结

  1. 反序列化绕过:

    • 利用UserResource类在白名单中的特性
    • 通过合法的类载体携带恶意数据
  2. EL表达式注入:

    • 利用RichFaces对EL表达式的自动解析特性
    • 通过反序列化控制表达式内容
  3. 触发链设计:

    • 利用mediaOutput标签的自动资源生成机制
    • 通过标准接口(getLastModified等)触发表达式解析
  4. 兼容性处理:

    • 解决不同容器中MethodExpression的serialVersionUID差异
    • 确保payload在不同环境中的稳定性

参考

  • CVE-2018-14667
  • RichFaces官方公告
  • RF-13977漏洞报告
Red Hat JBoss EAP RichFaces 反序列化漏洞分析 (CVE-2018-14667) 漏洞概述 CVE-2018-14667 是 Red Hat JBoss EAP 中 RichFaces 框架的一个远程代码执行漏洞,评级为"Critical"。该漏洞允许未经身份验证的攻击者通过发送特制的对象(包含恶意表达式)来绕过白名单保护,触发反序列化操作,最终导致任意Java代码执行。 漏洞环境 测试环境 : Tomcat 8.5.24 JDK 1.8.144 richfaces-demo-3.3.0.GA-tomcat6.war 漏洞触发流程 入口点 - BaseFilter#doFilter 请求通过JBoss SeamFilter → Ajax4jsfFilter → BaseFilter 关键判断逻辑决定是否进入InternetResourceService 核心处理 - InternetResourceService#serviceResource 从URL获取resourceKey 通过ResourceBuilderImpl获取resource和resourceDataForKey 根据条件调用resource.getLastModified、resource.getExpired或resource.send 反序列化绕过 - ResourceBuilderImpl 对URL中的数据进行base64解码和zip解压缩 使用LookAheadObjectInputStream进行反序列化,但有白名单限制 白名单检查resource-serialization.properties文件 资源生成 - ResourceBuilderImpl 从URL路径生成resource 使用UserResource类(在白名单中)作为反序列化载体 EL表达式注入 - UserResource 反序列化后的UriData对象中的表达式会被解析 通过getLastModified、getExpired或send方法触发表达式执行 漏洞利用分析 关键利用点 UserResource.UriData 类: 包含createContent、value、modified和expires字段 这些字段可以包含EL表达式 表达式执行触发点 : getLastModified() - 解析modified字段 getExpired() - 解析expires字段 send() - 解析createContent字段 反序列化控制 : 通过/DATA/路径后的base64编码数据控制反序列化内容 数据经过base64解码和zip解压缩 利用条件 目标系统使用了RichFaces 3.x至3.3.4版本 系统中包含 标签的页面 能够获取到mediaOutput生成的资源路径 漏洞复现步骤 获取资源路径 : 访问包含 标签的页面 从响应中提取src属性值(如:/DATA/eAHF...jsf) 构造恶意payload : 使用提供的POC生成代码 替换其中的EL表达式为恶意代码 生成base64编码的压缩payload 发送恶意请求 : 使用获取的资源路径前半部分 拼接生成的恶意payload 发送到目标服务器 POC生成代码分析 漏洞修复建议 升级到RichFaces 3.3.4以上版本 禁用不必要的RichFaces功能 加强输入验证和过滤 限制反序列化操作 技术要点总结 反序列化绕过 : 利用UserResource类在白名单中的特性 通过合法的类载体携带恶意数据 EL表达式注入 : 利用RichFaces对EL表达式的自动解析特性 通过反序列化控制表达式内容 触发链设计 : 利用mediaOutput标签的自动资源生成机制 通过标准接口(getLastModified等)触发表达式解析 兼容性处理 : 解决不同容器中MethodExpression的serialVersionUID差异 确保payload在不同环境中的稳定性 参考 CVE-2018-14667 RichFaces官方公告 RF-13977漏洞报告