Rapid7's latest Metasploit wrap-up landed with sixteen new modules — and for defenders, the headline isn't the count. It's the composition. Five of the new modules target vulnerabilities on CISA's Known Exploited Vulnerabilities (KEV) catalog, spanning Cisco, PaperCut, SonicWall, JetBrains, and Langflow. That means reliable, weaponized exploitation capability for confirmed in-the-wild bugs is now one msfconsole command away for every low-skill actor on the planet.
The module I want to focus on in depth is the new auxiliary scanner scanner/http/elasticsearch_tika_xfa_xxe, covering CVE-2025-66516 (and its sibling CVE-2025-54988) — an XML External Entity (XXE) vulnerability in Apache Tika's XFA parser, reachable through the Elasticsearch ingest-attachment plugin. This is a local file read primitive against one of the most widely deployed data platforms in enterprise environments. If your cluster indexes PDFs — and nearly every one does — you need to validate your exposure this week, not this quarter.
The broader lesson stands too: when Metasploit ships a module, your detection engineering backlog just got a deadline. Below is the technical breakdown, detection content, and remediation path.
Technical Analysis
The Vulnerability: XXE in Apache Tika's XFA Parser
Apache Tika is the content-analysis toolkit embedded in an enormous number of Java applications — Elasticsearch's ingest-attachment processor being one of the highest-value targets. Tika parses documents (PDF, Office, images) to extract text for indexing.
The flaw lives in how Tika handles XFA (XML Forms Architecture) content embedded in PDF files. XFA is an XML-based form specification, and Tika's parser was processing attacker-supplied XML with external entity resolution enabled. A crafted PDF containing malicious XFA XML can declare an external entity pointing at a local file or internal network resource:
- CVE-2025-54988 — the initial disclosure: XXE in the PDF parser module (
tika-parser-pdf-module) via crafted XFA content, enabling local file read. - CVE-2025-66516 — the follow-up that broadened the scope: the vulnerable code path was actually in Tika's core XML handling, meaning the initial fix didn't fully close the exposure across affected Tika versions (spanning the 1.x through 3.x lines). This is the variant the Metasploit scanner validates.
The fix landed in Apache Tika 3.2.2. Anything below that on the 3.x line — and effectively the entire legacy 1.x/2.x branches that many Elasticsearch deployments still transitively pull in — should be treated as vulnerable until verified otherwise.
Attack Chain from a Defender's Perspective
- Delivery: Attacker submits a weaponized PDF to any workflow that feeds documents into Elasticsearch's ingest-attachment processor — resume upload portals, document management systems, email-to-index pipelines, legal discovery ingestion, threat intel feeds.
- Parse: The ingest node hands the PDF to Tika. Tika encounters the XFA XML block and resolves the attacker-defined external entity (e.g.,
file:///etc/passwd,file:///proc/self/environ, cloud metadata endpoints likehttp://169.254.169.254/). - Exfiltration: The resolved content is embedded into the parsed output — meaning stolen file contents land in the indexed document itself or in error messages. The attacker retrieves them by simply searching the index. No shell, no callback, no C2. The exfil channel is the application.
Why This Is Dangerous
- No authentication required in most ingestion workflows — document upload is an unauthenticated attack surface by design.
- The Elasticsearch service account context determines what's readable: config files, keystores, environment variables with cloud credentials,
/proc/self/environ. - SSRF capability: external entities can point at internal HTTP endpoints, turning this into an internal reconnaissance and cloud-metadata-theft primitive.
- Low noise: exploitation looks like ordinary document indexing. Nothing crashes. Nothing alerts by default.
Exploitation Status
A working Metasploit auxiliary scanner now exists in the public framework (PR #21739). While the KEV-listed modules in this release cover the other named vendors, the availability of a validated scanner for CVE-2025-66516 means mass scanning of internet-exposed Elasticsearch clusters and document-ingestion endpoints is imminent if not already underway. Treat this as actively weaponized for prioritization purposes.
Detection & Response
The challenge with XXE-through-ingestion is that the malicious payload arrives inside a legitimate document over a legitimate channel. Network-layer detections should focus on the ingest API surface; host-layer detections on the Java process's file access behavior.
Sigma Rules
---
title: Elasticsearch Ingest Attachment API Invocation with Suspicious Payload
type: web
description: Detects HTTP requests to Elasticsearch ingest pipeline simulation or document indexing endpoints carrying XML external entity declarations, indicative of CVE-2025-66516 XXE exploitation attempts via Apache Tika XFA parsing.
references:
- https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-goes-to-sixteen
- https://nvd.nist.gov/vuln/detail/CVE-2025-66516
author: Security Arsenal
date: 2026/01/10
status: experimental
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection_ingest:
cs-uri|contains:
- '/_ingest/pipeline/'
- '/_simulate'
- 'pipeline=attachment'
- '?pipeline='
selection_xxe:
cs-body|contains:
- '<!ENTITY'
- '<!DOCTYPE'
- 'SYSTEM "file:///'
- 'SYSTEM \'file:///'
- 'xfa:data'
condition: selection_ingest and selection_xxe
falsepositives:
- Internal QA testing of ingest pipelines with synthetic XFA documents
level: high
---
title: Java Process Reading Sensitive Files Outside Expected Paths
description: Detects the Elasticsearch or Tika JVM process accessing sensitive operating system files that are inconsistent with normal indexing behavior, a post-exploitation indicator of XXE local file read via CVE-2025-66516.
references:
- https://www.rapid7.com/blog/post/pt-metasploit-wrap-up-goes-to-sixteen
- https://nvd.nist.gov/vuln/detail/CVE-2025-66516
author: Security Arsenal
date: 2026/01/10
status: experimental
tags:
- attack.collection
- attack.t1005
logsource:
category: file_event
product: linux
detection:
selection_process:
Image|contains:
- 'java'
selection_target:
TargetFilename|contains:
- '/etc/shadow'
- '/etc/passwd'
- '/proc/self/environ'
- '/proc/1/environ'
- '.aws/credentials'
- '.ssh/'
- 'elasticsearch.keystore'
condition: selection_process and selection_target
falsepositives:
- Elasticsearch service startup reading its own keystore (restrict monitoring windows or baseline startup I/O)
- Legitimate JDK diagnostic tooling run by administrators
level: high
The first rule assumes your WAF, reverse proxy, or load balancer logs request bodies for ingest endpoints — if it doesn't, enable body capture on / _ingest/* paths at minimum. The second rule requires Sysmon-for-Linux, auditd file watch rules, or an EDR with file-access telemetry mapped to the file_event category.
KQL — Microsoft Sentinel
Elasticsearch typically ships logs into Sentinel via Syslog/CEF forwarders. This query hunts for the scanner's signature pattern and for XXE payload strings appearing in application or ingest logs. Run it against whatever table carries your Elasticsearch application logs.
// Hunt for XXE exploitation attempts against Elasticsearch ingest-attachment (CVE-2025-66516)
let xxe_patterns = dynamic(["<!ENTITY", "SYSTEM \"file:///", "SYSTEM 'file:///", "xfa:data", "169.254.169.254"]);
union isfuzzy=true
(Syslog
| where TimeGenerated > ago(7d)
| where SyslogMessage has_any (xxe_patterns)
| where SyslogMessage has_any ("_ingest", "attachment", "tika", "pipeline")
| project TimeGenerated, Computer, Facility, SyslogMessage
),
(CommonSecurityLog
| where TimeGenerated > ago(7d)
| where RequestURL has_any ("_ingest", "_simulate", "pipeline=")
| where AdditionalExtensions has_any (xxe_patterns) or RequestContext has_any (xxe_patterns)
| project TimeGenerated, SourceIP, DestinationHostName, RequestURL, RequestMethod
)
| order by TimeGenerated desc
If you run Defender for Endpoint on your Elasticsearch Linux hosts, also hunt the JVM's child process behavior — XXE exploitation itself won't spawn processes, but post-exploitation reconnaissance often does:
// Elasticsearch JVM spawning unexpected child processes (post-exploitation recon)
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName has "java"
| where InitiatingProcessCommandLine has_any ("elasticsearch", "tika")
| where FileName in~ ("sh", "bash", "curl", "wget", "id", "whoami", "env", "cat")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessCommandLine, AccountName
| order by TimeGenerated desc
Velociraptor VQL
For live-response on an Elasticsearch ingest node, enumerate what the JVM has open and check for reads outside expected index/plugin paths. This artifact is tuned to catch a JVM with handles on sensitive credential or system files during or after suspected exploitation.
-- Hunt for Elasticsearch/Tika JVM processes holding open handles to sensitive files
-- Target: ingest nodes suspected of CVE-2025-66516 XXE exploitation
SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)java'
AND CommandLine =~ '(?i)elasticsearch|tika'
Pair it with a glob sweep for forensic evidence — Tika extraction temp files and recently modified PDFs dropped into ingestion staging directories:
-- Locate recently staged PDF files in ingestion/upload directories for triage
SELECT FullPath, Size, Mtime, Ctime
FROM glob(globs=[
'/tmp/**/*.pdf',
'/var/tmp/**/*.pdf',
'/opt/**/uploads/**/*.pdf',
'/srv/**/ingest*/**/*.pdf'
])
WHERE Mtime > now() - 604800
ORDER BY Mtime DESC
Any PDF returned by that hunt that contains an <xfa: element with an <!ENTITY declaration is your smoking gun. Carve it, hash it, and search your index for the resolved content — that's how you confirm whether file data was actually exfiltrated into searchable documents.
Remediation and Verification Script
This Bash script inventories your Elasticsearch nodes for the vulnerable Tika dependency, checks the installed Tika version against the fixed release, and verifies whether the ingest-attachment plugin is present on clusters where it isn't needed.
#!/bin/bash
# CVE-2025-66516 / CVE-2025-54988 - Tika XXE exposure check for Elasticsearch nodes
# Run on each ingest-capable node. Requires read access to the ES installation.
ES_HOME="${ES_HOME:-/usr/share/elasticsearch}"
echo "=== Tika XXE Exposure Check (CVE-2025-66516) ==="
echo "Scanning: ${ES_HOME}"
# 1. Locate Tika jars and extract versions
TIKA_JARS=$(find "${ES_HOME}" -name 'tika-*.jar' 2>/dev/null)
if [ -z "${TIKA_JARS}" ]; then
echo "[OK] No Tika jars found - ingest-attachment likely not installed on this node."
else
echo "[INFO] Tika artifacts detected:"
VULN=0
for jar in ${TIKA_JARS}; do
VER=$(basename "${jar}" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
MAJOR=$(echo "${VER}" | cut -d. -f1)
MINOR=$(echo "${VER}" | cut -d. -f2)
PATCH=$(echo "${VER}" | cut -d. -f3)
echo " - ${jar} (version ${VER})"
# Fixed in 3.2.2; all 1.x/2.x branches and 3.x < 3.2.2 treated as vulnerable
if [ "${MAJOR}" -lt 3 ] || { [ "${MAJOR}" -eq 3 ] && { [ "${MINOR}" -lt 2 ] || { [ "${MINOR}" -eq 2 ] && [ "${PATCH}" -lt 2 ]; }; }; then
echo " [VULNERABLE] ${VER} is below the fixed version 3.2.2"
VULN=1
else
echo " [OK] ${VER} meets the fixed baseline (3.2.2+)"
fi
done
fi
# 2. Confirm ingest-attachment plugin presence
if [ -d "${ES_HOME}/plugins/ingest-attachment" ]; then
echo "[INFO] ingest-attachment plugin IS installed."
echo " -> If attachment indexing is not a business requirement, remove it:"
echo " sudo ${ES_HOME}/bin/elasticsearch-plugin remove ingest-attachment"
else
echo "[OK] ingest-attachment plugin not present."
fi
# 3. Check whether any node is assigned the ingest role unnecessarily
if [ -f "${ES_HOME}/config/elasticsearch.yml" ]; then
echo "[INFO] Ingest role configuration:"
grep -E '^\s*(node\.roles|node\.ingest)' "${ES_HOME}/config/elasticsearch.yml" || echo " (defaults apply - node likely holds the ingest role)"
fi
# 4. Quick index sweep hint for exfiltration review
echo ""
echo "[NEXT STEPS]"
echo " 1. Upgrade Tika to 3.2.2+ (via Elasticsearch version that bundles it, or dependency override)."
echo " 2. Search indices for leaked file content, e.g.:"
echo " GET /*/_search?q=\"root:x:0:0\" OR q=\"AWS_SECRET_ACCESS_KEY\""
echo " 3. Block XXE-suspect uploads at the WAF: reject bodies containing <!ENTITY or DOCTYPE on ingest paths."
[ "${VULN:-0}" -eq 1 ] && exit 1 || exit 0
Remediation
-
Upgrade Apache Tika to 3.2.2 or later. This is the version that remediates both CVE-2025-54988 and the broader-scoped CVE-2025-66516. For Elasticsearch deployments, the Tika version is bundled with the ingest-attachment plugin — track Elastic's advisory feed for the Elasticsearch release that ships the fixed Tika, and upgrade clusters on an accelerated cadence rather than your normal maintenance window. Do not attempt to hot-swap Tika jars inside the plugin directory on production nodes without vendor guidance; use the supported upgrade path.
-
Remove ingest-attachment where it isn't required. The single most effective compensating control:
bin/elasticsearch-plugin remove ingest-attachmenton every node that doesn't have a documented business need for attachment parsing. Every plugin you don't run is attack surface you don't patch. -
Strip the ingest role from nodes that don't need it. Set explicit
node.rolesso that only designated ingest nodes can execute pipelines. This shrinks the blast radius — exploitation then requires reaching a smaller, more closely monitored set of hosts. -
Enforce network egress controls on Elasticsearch nodes. The JVM should have no route to the internet or to cloud metadata endpoints. Block 169.254.169.254 at the host firewall (
iptables -A OUTPUT -d 169.254.169.254 -j DROP) and require IMDSv2 where metadata access is legitimately needed. This neuters the SSRF side of the XXE even if parsing remains vulnerable. -
Filter at the edge. WAF/reverse-proxy rules that reject request bodies containing
<!ENTITYor<!DOCTYPEdirected at_ingest,_simulate, or pipeline-parameterized indexing endpoints will break both the Metasploit scanner and most manual exploitation, at the cost of a small false-positive risk from legitimately XML-heavy document uploads. -
Hunt for exfiltration in the index itself. Because resolved entity content is indexed, search your clusters for markers of successful reads:
/etc/passwdcontents (root:x:0:0), environment variable names, private key headers (BEGIN RSA PRIVATE KEY), and cloud credential patterns. If you find them, you're in incident response — rotate every secret readable by the Elasticsearch service account. -
Work the rest of the wrap-up. Five KEV-listed modules in one release means your Cisco, PaperCut, SonicWall, JetBrains, and Langflow assets need their KEV due-dates re-verified against your asset inventory. CISA's remediation deadlines apply to federal agencies; for everyone else, KEV membership alone is the prioritization signal. Pull the current catalog at cisa.gov/known-exploited-vulnerabilities-catalog and reconcile it against your vulnerability scan data this week.
The Metasploit release cadence is, functionally, a free threat-intel feed. When a module ships, the exploitation barrier drops to zero — your detection coverage needs to be in place before the wrap-up blog post, not after.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.