Apache Commons Text RCE Vulnerability Analysis - CVE-2022-42889
Tags: cybersecurity, vulnerability, apache, security
Published: 2022-12-02 04:00:41



## Introduction

Apache Commons Text is a low-level library for performing various text operations such as escaping, computing string differences, and replacing placeholders in text with values ​​looked up by interpolators.

## Vulnerability Description

On October 13, 2022, the official release of the Apache Commons Text vulnerability notice, vulnerability number: CVE-2022-42889. Apache Commons Text performs variable interpolation, allowing dynamic evaluation and expansion of attributes. The standard format for interpolation is "${prefix: name}", where "prefix" is used to locate the interpolation. An instance of org.apache.commons.text.lookup.StringLookup. From version 1.5 to 1.9, an attacker can construct a malicious text that causes Apache Commons Text to execute arbitrary malicious code when it is parsed.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxbso55s2d99urescwy3.png)


### Scope
1.5 <= Apache Commons Text <= 1.9

## Vulnerability Analysis

### Environment Build

IDEA imports dependencies through Maven

pom.xml is as follows:

```
<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-configuration2</artifactId>
        <version>2.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.9</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>
```

Test code:

```
package org.text;

import org.apache.commons.text.StringSubstitutor;

public class Main {
    public static void main(String[] args) {

        StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
//        String payload = interpolator.replace("${script:js:new java.lang.ProcessBuilder(\"calc\").start()}");
        String payload = "${script:js:new java.lang.ProcessBuilder(\"calc\").start()}";
        interpolator.replace(payload);
    }
}
```

JDK version 1.8

### Dynamic Analysis

Before code analysis, let's take a look at the content in the official user manual ( https://commons.apache.org/proper/commons-text/userguide.html ).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gz4amb6akacemwsn15ud.png)

This demonstrates the usage of using the default lookup StringSubstitutor to construct a complex string, and the key point in the vulnerability description is to perform variable interpolation, and its standard format is ${prefix:name}.

Refer to the documentation of StringLookupFactory ( http://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html )

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ii4ciij76tjoyc0o1jdq.png)

Since version 1.5, string search of script type can be satisfied, but it is not included by default.

Target the code to

org.apache.commons.text.lookup.InterpolatorStringLookup#lookup

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l786s4k7pvbqy2jykvz.png)

Here the lookup method will extract the part after ":" as the prefix value, and then extract its corresponding lookup instantiation object according to stringLookupMap.

into org.apache.commons.text.lookup.ScriptStringLookup#lookup.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9hp0pnpao2s1b3240oa.png)

Call ScriptEngineManager to execute code.

Understand the second half of the vulnerability, set a breakpoint, and dynamically debug it to see how to call the lookup method.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4y82q0isbc9xwvl4xmr5.png)

org.apache.commons.text.StringSubstitutor#createInterpolator

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dffsyxkriax3x7tfvmvm.png)


Here is to instantiate StringSubstitutor and pass

StringLookupFactory.INSTANCE.interpolatorStringLookup() into it

org.apache.commons.text.StringSubstitutor#replace

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pzy90ndsqnx7bfmk9es.png)

Convert the type of the parameter, and then pass it to the substitute for processing, and then it will go through a series of judgment checks.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gmeyj0x6dzd7vmvfqa0.png)

Finally, pass in resolveVariable

org.apache.commons.text.StringSubstitutor#resolveVariable

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/whcwjluia7gf8rqjxv5c.png)


After the value of getStringLookup, it will directly call the lookup method in org.apache.commons.text.lookup.InterpolatorStringLookup.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttskdzlvtinuc6ijn9qh.png)


At this point, as analyzed at the beginning, the lookup method will extract the part after ":" as the prefix value, then extract its corresponding lookup instantiation object according to the stringLookupMap, and finally execute the code by calling ScriptEngineManager.

## Vulnerability

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wurf3hd634bl3wpqmkxx.png)

Of course, many bigwigs on the Internet have analyzed this vulnerability. This vulnerability is actually different from Log4Shell (CVE-2021-44228) because, in Log4Shell, string interpolation can be performed from the log message body, which usually contains Untrusted input. In the Apache Common Text issue, the relevant methods are explicitly used to perform string interpolation and are clearly documented, so it is less likely that an application will inadvertently pass untrusted input without proper validation.