Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
cve-2024-23897-jenkins-poc — Self-contained Docker reproduction and analysis of CVE-2024-23897, the Jenkins CLI arbitrary file read via the args4j @-syntax argument expansion. | Kitploit
Tools/GitHubGitHub/rivaedoardo62-boop/cve-2024-23897-jenkins-poc
Vulnerability AnalysisExploitationWeb SecurityPenetration TestingPapers & ResearchLearning & Education
GitHubrivaedoardo62-boop/cve-2024-23897-jenkins-poc

cve-2024-23897-jenkins-poc

Self-contained Docker reproduction and analysis of CVE-2024-23897, the Jenkins CLI arbitrary file read via the args4j @-syntax argument expansion.

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View Repository
2 months agoNot yet reviewed

CVE-2024-23897: Jenkins Arbitrary File Read (args4j @-Syntax)

A self-contained, fully local reproduction of CVE-2024-23897, the critical (CVSS 3.1 base score 9.8) arbitrary file read in the Jenkins CLI. The project spins up two Docker stacks that differ only by the Jenkins minor version, runs the same proof of concept against both, and shows the vulnerability firing on the unpatched controller and going silent on the patched one.

Everything is driven by a single Python program, poc.py. The harness only orchestrates the environment (Docker Compose, the official jenkins-cli.jar client, and verbatim capture of the output). The vulnerability itself lives in Jenkins' own Java code and is never reimplemented here.

A full written analysis, including the patch review and the CVSS decomposition, is in report/report.pdf.

The vulnerability in one paragraph

The Jenkins CLI builds its argument parser with the args4j library. args4j has a feature called expandAtFiles, controlled by the atSyntax flag and enabled by default, that rewrites any argument of the form @/path/to/file into the contents of that file before the command runs. The file is opened with the privileges of the Jenkins controller process. Because all three CLI transports (HTTP, WebSocket, SSH) funnel into the same parser, any client that can send any CLI command can read arbitrary files off the controller. The fix (commit 554f0378) adds a constant ALLOW_AT_SYNTAX that defaults to false, turning the expansion off.

This is not classical path traversal: there is no ../ and no base directory to escape. The path is opened directly. On the outcome axis it is an arbitrary file read; on the mechanism axis it is argument expansion.

Repository layout

root@kitploit:~
cve-2024-23897-jenkins-poc/
  README.md                      # this file
  LICENSE
  poc.py                         # Python reproduction harness (all subcommands)
  Dockerfile.vuln                # jenkins/jenkins:2.426.2-lts + matrix-auth
  Dockerfile.fix                 # jenkins/jenkins:2.426.3-lts + matrix-auth
  docker-compose.vuln.yml        # jenkins-vuln + attacker-vuln
  docker-compose.fix.yml         # jenkins-fix  + attacker-fix
  init.groovy.d/
    01-create-users.groovy       # bootstraps admin + readuser via matrix-auth
  evidence/
    docker-versions.txt          # host Docker + Compose versions
    output-vulnerable.txt        # captured during `poc.py exploit`
    output-fixed.txt             # captured during `poc.py verify-fix`
  report/
    report.pdf                   # full written analysis
    report.tex                   # LaTeX source (self-contained, no external figures)

Prerequisites

No JDK is required on the host. Java runs inside the attacker container. The compose files pin platform: linux/amd64 so the images behave identically on Apple Silicon; this is an operational choice and does not touch the vulnerability, which is platform independent.

How to run

From inside the repository:

root@kitploit:~
python3 poc.py up-vuln       # build and start the vulnerable stack, fetch the CLI jar
python3 poc.py place-proof   # write the harmless marker file inside the controller
python3 poc.py exploit       # run the PoC, writes evidence/output-vulnerable.txt
python3 poc.py up-fix        # tear down vuln, build and start the patched stack
python3 poc.py verify-fix    # run the same PoC, writes evidence/output-fixed.txt
python3 poc.py teardown      # stop and remove both stacks

First run takes a few minutes (image pulls plus the plugin install). Subsequent runs are much faster.

poc.py exploit passes when the marker string POC-PROOF-LINE appears in the captured output (the leak happened). poc.py verify-fix passes on the opposite condition: the marker must be absent. Both subcommands exit non-zero on failure, so the two evidence files plus their exit status are themselves the test result.

Architecture

Both compose files run the same two services on one Docker network: a Jenkins controller (the victim) and a small eclipse-temurin:17-jre attacker container. poc.py runs on the host and drives Docker through subprocess, but the actual java -jar jenkins-cli.jar ... invocation runs inside the attacker container. The attacker has no access to the Jenkins data volume; it reaches the controller only over the network, the way a remote attacker would.

Authorisation model

init.groovy.d/01-create-users.groovy uses the matrix-auth plugin to create two accounts with deliberately different permissions:

Account

This reproduces the exact split in the official advisory, Overall/Read versus anonymous, rather than the looser "any logged-in user versus anonymous" that the Jenkins core default would have produced. The full file leak is therefore attributable to the CVE alone, not to administrative reach.

Results

The PoC runs four contexts against each controller. The table below summarises the A/B comparison; the full captures are in evidence/.

The only variable that changes between the two columns is the Jenkins minor version, and through it the post-patch default of atSyntax. The opposite results therefore attribute the behaviour change to the parser fix in commit 554f0378.

Why Docker does not fix the bug

Running Jenkins in a container is not a mitigation. The parser reads files with the privileges of the Jenkins JVM, and those files live inside the same container filesystem that holds the credentials store. The container boundary protects the host from the Jenkins process, not the Jenkins process from itself. The Docker setup here is a demonstration sandbox, nothing more.

Mitigation

Upgrade to a patched release: 2.442 (weekly), or 2.426.3 or 2.440.1 (LTS), all published on 24 January 2024. If an immediate upgrade is not possible, leave the system property hudson.cli.CLICommand.allowAtSyntax unset (its default), which keeps ALLOW_AT_SYNTAX false and disables the expansion. Disabling individual CLI transports is only a partial measure, since all three converge on the same parser.

Safety note

All work runs in a local Docker environment against a harmless three-line marker file (/tmp/poc-proof.txt) that the harness creates itself. No public Jenkins instance is scanned or contacted, and no real secret such as secrets/master.key or credentials.xml is ever read.

References

  • Jenkins Security Advisory 2024-01-24 (SECURITY-3314, SECURITY-3315): https://www.jenkins.io/security/advisory/2024-01-24/
  • NVD entry for CVE-2024-23897: https://nvd.nist.gov/vuln/detail/CVE-2024-23897
  • Fix commit 554f0378 on jenkinsci/jenkins: https://github.com/jenkinsci/jenkins/commit/554f03782057c499c49bbb06575f0d28b5200edb
  • args4j (ParserProperties.withAtSyntax): https://github.com/kohsuke/args4j
  • Zscaler ThreatLabz write-up (file read to RCE): https://www.zscaler.com/blogs/security-research/jenkins-arbitrary-file-leak-vulnerability-cve-2024-23897-can-lead-rce
Download Tool
RequirementNotes
Docker Engine 24 or newerexact version used is recorded in evidence/docker-versions.txt
Docker Compose v2shipped as the built-in docker compose plugin
Python 3.8 or newerstandard library only, no pip install needed
Disk spaceabout 1.5 GB for two Jenkins images, the temurin image and the matrix-auth plugin
Permissions
Role in the PoC
adminJenkins.ADMINISTERexists only to satisfy "at least one admin", never used to attack
readuserJenkins.READ only (Overall/Read)the authenticated attacker
anonymousnonethe unauthenticated attacker
ObservationVulnerable 2.426.2Patched 2.426.3
@-token handlingexpanded into file contentstreated as a literal string
readuser + connect-nodefull file disclosure (3 of 3 lines)no disclosure
anonymous + who-am-i / helppartial leak (first line) via parser error before the auth gateno disclosure
marker POC-PROOF-LINE in outputpresentabsent